Prolog:考试时间表生成器 - 如何避免解决方案中的排列

时间:2015-12-23 20:05:30

标签: prolog permutation schedule

我正在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))

我该如何避免这种情况? 谢谢!

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