对于一个学校项目,我想在Prolog中创建计划制定者。我希望Prolog每天都做一个计划。每天需要一定数量的员工,而员工只能在某些日子工作。我希望Prolog制定一项计划,以计划每天合适的人数。为此,我编写了以下代码:
c.Spawner.cmd
但是,我无法让Prolog给出正确的结果,因为我查询以下Prolog可以为我提供所有选择,而与所需员工数量无关。
workingday_employeesneeded(monday, 2).
workingday_employeesneeded(tuesday, 1).
workingday_employeesneeded(wednesday, 2).
employee_availability(tom, monday).
employee_availability(thomas, monday).
employee_availability(timme, monday).
employee_availability(timo, monday).
employee_availability(tom, tuesday).
planning(Employee, Day) :-
workingday_employeesneeded(Day, Amount),
employee_availability(Employee, Day).
planning(Employee, Day) :-
aggregate_all(count, planning(Employee, Day), Count),
workingday_employeesneeded(Day, Amount),
Count <= Amount.
你们能看到我在做什么吗?预先感谢!
编辑: 我认为在计划中每天列出员工列表可能会很方便。因此,我将代码编辑为以下内容(还修复了注释中指出的一些语法错误);
?- planning(X, Y).
X = tom,
Y = monday ;
X = thomas,
Y = monday ;
X = timme,
Y = monday ;
X = timo,
Y = monday ;
X = tom,
Y = tuesday ;
false.
以下问题仍然存在;如果可用的员工人数超过所需的人数,则该程序不会打印当天的计划,而只会选择前N名员工。
你们有解决这个问题的建议吗?
答案 0 :(得分:1)
您的谓词失败了,因为首先使用findall/3
,然后限制列表的长度。例如,对于monday
,有4名员工可用,您找到的所有员工都与findall/3
并存储到Employees
中。然后,您检查列表的长度,列表将失败。要解决此问题,您需要找到所有可用的员工,然后找到所需长度的列表子集。因此您的代码将是:
subset([], []).
subset([E|Tail], [E|NTail]):-
subset(Tail, NTail).
subset([_|Tail], NTail):-
subset(Tail, NTail).
planning_on_day(Day, Employees) :-
workingday_employeesneeded(Day, Amount),
findall(E, employee_availability(E, Day), E),
length(Employees,Amount),
subset(E,Employees).
?- planning_on_day(monday,P).
P = [tom, thomas]
P = [tom, timme]
P = [tom, timo]
P = [thomas, timme]
P = [thomas, timo]
P = [timme, timo]
false
?- planning_on_day(tuesday,P).
P = [tom]
false
?- planning_on_day(wednesday,P).
false
然后,如果要查找本周的计划,则可以添加:
isDifferent(_, []).
isDifferent(X, [H | T]) :-
X \= H,
isDifferent(X, T).
allDifferent([]).
allDifferent([H | T]) :-
isDifferent(H, T),
allDifferent(T).
solve([],Plan,Plan):-
flatten(Plan,P),
allDifferent(P).
solve([Day|T],LT,Plan):-
workingday_employeesneeded(Day, Amount),
planning_on_day(Day,PlanD),
length(A,Amount),
subset(PlanD,A),
append(LT,[PlanD],LT1),
solve(T,LT1,Plan).
?- solve([monday,tuesday],[],L).
L = [[thomas, timme], [tom]]
L = [[thomas, timo], [tom]]
L = [[timme, timo], [tom]]