我正在Prolog中建立一个考试时间表。 调度程序基于以下示例: https://metacpan.org/source/DOUGW/AI-Prolog-0.741/examples/schedule.pl
如何确保我的解决方案中没有排列?
例如解决方案
- > ((考试1,老师1,时间1,房间1),(考试2,老师2,时间2,房间2))
后来的解决方案:
- > ((考试2,老师2,时间2,房间2),(考试1,老师1,时间1,房间1))
我该如何避免这种情况? 谢谢!
答案 0 :(得分:0)
1)与您所接受的最接近/最简单的方法是检查您所选择的课程是否比前一课程严格更大。
例如,通过添加一个额外的谓词,其中还包括组合中的前一个课程。
%%makeListPrev(PreviousTakenCourse, ResultCombinationOfCourses, NrOfCoursesToAdd)
makeListPrev(_,[], 0).
makeListPrev(course(Tprev,Ttime,Troom),[course(Teacher,Time,Room)|Rest], N) :-
N > 0,
teacher(Teacher),
classtime(Time),
classroom(Room),
course(Tprev,Ttime,Troom) @< course(Teacher,Time,Room), %% enforce unique combinations
is(M,minus(N,1)),
makeListPrev(course(Teacher,Time,Room),Rest,M).
通过这种方式,您可以通过始终将词典最小化来消除相同组合的所有重复排列。
例如,如果你有4门课程:
(a,b,c,d)
(a,b,d,c) % d can't be before c
(a,c,b,d) % c can't be before b
...
2)另一种轻松解决此问题的方法是首先创建所有可能课程的列表。然后顺序取出所有可能的N组合。
scheduler(L) :-
%% Find all possible courses
findall(course(Teacher,Time,Room),(teacher(Teacher),classtime(Time),classroom(Room)),Courses),
makeList(Courses,4,L),
different(L).
makeList([],0,[]) :- !. %% list completed
makeList([H|T],N,[H|Res]) :- %% list including H
M is N-1,
makeList(T,M,Res).
makeList([_|T], N, Res) :- makeList(T, N, Res). %% list without H