假设我们要在 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来执行此操作? (对于大问题,这将很麻烦)。