在Prolog中修剪对称解决方案

时间:2019-03-16 15:15:26

标签: prolog

假设我们要在 native 序言中写谓词 schedule / 6 ,该谓词给出了一份工作列表,为N个工人创建了一个时间表,每个工人可以在其中工作最多H小时

作业表示为:

job(Name, time(StartTime, EndTime))

序言源可能看起来像这样:(假设 overlapping / 3 检查某项工作是否与某人当前分配的工作重叠)

schedule(_, _, _, [], Schedule, Schedule).
schedule(N, CurrentPerson, H, Jobs,  CurrentSchedule, Schedule):-
    CurrentPerson =< N,
    scheduleP(CurrentPerson, H, Jobs, RemainingJobs, 0, CurrentSchedule, UpdatedSchedule),
    NewPerson is CurrentPerson + 1,
    schedule(N, NewPerson, H, RemainingJobs, UpdatedSchedule, Schedule).    


scheduleP(CurrentPerson, H, [job(A, time(Y,Z)) | T1], RemainingJobs, Time, CurrentSchedule, Schedule):-
    NewTime is Time + (Z - Y),
    NewTime =< H,
    \+ overlapping(CurrentPerson, time(Y,Z), CurrentSchedule),
    scheduleP(CurrentPerson, H, T1, RemainingJobs, NewTime, [CurrentPerson - A | CurrentSchedule], Schedule).

scheduleP(CurrentPerson, H, [job(A, time(Y,Z)) | T1], [job(A, time(Y,Z)) | T2], Time, CurrentSchedule, Schedule):-
    NewTime is Time + (Z - Y),
    NewTime =< H,
    overlapping(CurP, act(Y,Z), CurASA),
    scheduleP(CurrentPerson, H, T1, T2, Time, CurrentSchedule, Schedule).

scheduleP(_, _, RemainingJobs, RemainingJobs, _, Schedule, Schedule).

基本上,上面的代码应该以

的格式返回元素列表。
Person - JobName

指示哪个人从事了哪个工作。 通过请求更多解决方案,谓词将生成下一个可能的排列。

问题是,如何防止其显示对称解? 例如,如果输入作业列表是

[ job(a1, time(0,3)), job(a2, time(4,6)), job(a3, time(1,2)) ]

那么以下调用的一些输出将是:

schedule(2,1, 10, [ job(a1, time(0,3)), job(a2, time(4,6)), job(a3, time(1,2)) ], Schedule).

Schedule = [1 - a1, 1 - a2, 2 - a3]

;

Schedule = [2 - a1, 2 - a2, 1 - a3]

但是这两个解决方案被认为是对称的。 是否可以在本机序幕中不使用setof / 3来执行此操作? (对于大问题,这将很麻烦)。

0 个答案:

没有答案