Prolog 事实数量规则
对于一个学校项目,我想用Prolog做一个计划制定者。我想让Prolog为每天做一个计划。每天都需要一定数量的员工,员工只能在特定的日期工作。我想让Prolog制定一个计划,每天安排适当数量的人。为此,我编写了以下代码:Prolog 事实数量规则,prolog,Prolog,对于一个学校项目,我想用Prolog做一个计划制定者。我想让Prolog为每天做一个计划。每天都需要一定数量的员工,员工只能在特定的日期工作。我想让Prolog制定一个计划,每天安排适当数量的人。为此,我编写了以下代码: workingday_employeesneeded(monday, 2). workingday_employeesneeded(tuesday, 1). workingday_employeesneeded(wednesday, 2). employee_availabi
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.
你们能看出我做错了什么吗?提前谢谢
编辑:
我想在计划中列出每天的员工名单可能很方便。因此,我将代码编辑为以下内容(还修复了注释中指出的一些语法错误)
以下问题仍然存在;如果有超过需要的员工,该计划不会打印当天的计划,而只挑选前N名员工
你们有解决这个问题的建议吗?简单地说,谓词失败是因为首先使用
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]]
两条独立的规划规则?另外,
你希望有哪些答案?-在计划日(星期一,Xs)进行规划。
?@重复Xs=[tom,thomas]代码>还有其他答案吗?排列呢?
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]]