1

我正在尝试做一个在 Prolog 中有限制的时间表。调度将基于两个约束。同一学期的课程和同一名教师教授的课程不能安排在同一时间段。

course(ceng123,1). 课程代码和学期课程。

slot(monday,1). 一天一小时。

teaches(jack,ceng123). 教师和课程代码。

 course(cse111,1).
 course(cse112,1).
 course(cse113,1).
 course(cse114,1).
 course(cse115,2).
 course(cse116,2).
 course(cse117,2).
 course(cse118,2).
 slot(monday,1).
 slot(monday,2).
 slot(tuesday,1).
 slot(tuesday,2).
 teaches(erkan,cse111).
 teaches(erkan,cse112).
 teaches(erkan,cse113).
 teaches(erkan,cse114).
 teaches(merkan,cse115).
 teaches(merkan,cse116).
 teaches(kan,cse117).
 teaches(kan,cse118).

我期望的答案是:

 ?- schedule([cse111,cse112,cse113,cse114,cse115,cse116,cse117,cse118],X).
 X = [cse111, monday, 1, cse112, monday, 2, cse113, tuesday, 1, cse114, tuesday, 2, cse115, monday, 1, cse116, monday, 2, cse117, tuesday, 1, cse118, tuesday, 2]

我写了一个没有约束的代码:

 course(cse111,1).
 course(cse112,1).
 course(cse113,1).
 course(cse114,1).
 course(cse115,2).
 course(cse116,2).
 course(cse117,2).
 course(cse118,2).
 slot(monday,1).
 slot(monday,2).
 slot(tuesday,1).
 slot(tuesday,2).
 teaches(erkan,cse111).
 teaches(erkan,cse112).
 teaches(erkan,cse113).
 teaches(erkan,cse114).
 teaches(merkan,cse115).
 teaches(merkan,cse116).
 teaches(kan,cse117).
 teaches(kan,cse118).


 schedule([],[]).
 schedule([Course|CourseTail],[Course,Day,Slot|ScheduleTail]):-
     slot(Day,Slot),schedule(CourseTail,ScheduleTail).

没有问题,但是当我尝试这个时;

 course(cse111,1).
 course(cse112,1).
 course(cse113,1).
 course(cse114,1).
 course(cse115,2).
 course(cse116,2).
 course(cse117,2).
 course(cse118,2).
 slot(monday,1).
 slot(monday,2).
 slot(tuesday,1).
 slot(tuesday,2).
 teaches(erkan,cse111).
 teaches(erkan,cse112).
 teaches(erkan,cse113).
 teaches(erkan,cse114).
 teaches(merkan,cse115).
 teaches(merkan,cse116).
 teaches(kan,cse117).
 teaches(kan,cse118).     

 schedule([],[]).
 schedule([Course|CourseTail],[Course,Day,Slot|ScheduleTail]):-
     schedule(CourseTail,ScheduleTail), check(Course,Day,Slot,ScheduleTail).

 check(_, _, _,[]).
 check(Course,Day,Slot,[Course2,Day2,Slot2|Tail]):- check(Course,Day,Slot,Tail),
     course(Course,Semester1),course(Course2,Semester2),Semester1=\=Semester2, 
     slot(Day,Slot),slot(Day2,Slot2).

我试图写约束,但我出错了。

 uncaught exception: error(syntax_error('user_input:1 (char:4) . or operator expected           after expression'),read_term/3) 

你能看出错误吗?

4

2 回答 2

3

单例变量是在程序中只提到一次的变量:参见 wiki。你得到了第 27 行的内容,我认为是这个: check(Course,Day,Slot,[]). 您可以将其替换为 check(_, _, _,[]). ('_' 表示任何变量。这意味着您可以普遍量化变量。)

您不会收到错误消息。Prolog 说不只是意味着无法满足您的约束。

于 2012-12-26T18:10:37.203 回答
0

您应该首先明确定义您的约束。从您的评论中,我读到: 一个小时内的两门课程不能有相同的学期编号,同一位老师的课程不会在同一小时内。

因此,您可以在课程满足这些要求时为其分配时间表,暗示您必须知道哪些作业已经发布。因此,您可以创建一个保留当前计划的程序,并且仅在满足您的要求时添加新分配。

因此,首先定义您的schedule/2过程,该过程调用一个schedule/3带有空列表的新过程:

schedule(Courses,Schedule):-
   schedule(Courses, [], Schedule).

现在,此过程在第一个参数上具有要分配时间表的课程列表,将当前作业与第二个参数保持一致,并将第三个参数与最终时间表(使用您需要的数据,即课程、日期和时段)统一起来. 我将使用一个结构来表示每个分配schedule(Course, Day, Slot),因为将这些数据混合在一个列表中并不是一个好主意。

schedule([], _, []).
schedule([Course|CourseTail], Courses, [schedule(Course,Day,Slot)|ScheduleTail]):-
% Two courses in an hour cannot have same semester number and same teacher's courses will not be in same hour.
     course(Course, Semester),
     teaches(Teacher, Course),
     slot(Day, Slot),
     \+ member(s(Day, Slot, Semester, _), Courses),
     \+ member(s(Day, Slot, _, Teacher), Courses),
     schedule(CourseTail, [s(Day, Slot, Semester, Teacher)|Courses], ScheduleTail).

第一个子句是基本情况。它指出,当输入列表中没有更多课程时,时间表将为空。

第二个子句从输入列表中获取第一门课程,并为该课程计算可能的学期、教师和日/时段,然后检查是否满足约束条件。它测试是否已经有该日/时段/学期的时间表,以及在该日/时段是否已经有教师的作业。如果满足要求,则我们将此分配添加到当前分配列表中并继续递归。

返回后,我们将课程/天/时段添加到最终时间表的列表中。

于 2012-12-27T14:19:17.320 回答