【问题标题】:Rule for amount of facts事实数量规则
【发布时间】:2019-03-03 07:41:28
【问题描述】:

对于一个学校项目,我想在 Prolog 中制作一个规划师。我希望 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.

但是,我无法让 Prolog 给我正确的结果,因为我查询以下 Prolog 给了我所有选项,而不是关于所需的员工数量。

?- planning(X, Y).

X = tom,
Y = monday ;
X = thomas,
Y = monday ;
X = timme,
Y = monday ;
X = timo,
Y = monday ;
X = tom,
Y = tuesday ;
false.

你们能看出我做错了什么吗?提前致谢!

编辑: 我认为在计划中列出每天的员工名单可能会很方便。所以我将代码编辑为以下(还修复了 cmets 中指出的一些语法错误);

planning_on_day(Day, Employees) :-
    workingday_employeesneeded(Day, Amount),
    findall(E, employee_availability(E, Day), Employees),
    length(Employees, Amount).

以下问题依然存在;如果可用的员工比需要的多,则程序不会打印当天的计划,而只会选择前 N 名员工。

你们有解决这个问题的建议吗?

【问题讨论】:

  • planing/2的两条独立规则?
  • 另外,&lt;= 必须写成=&lt;
  • 你对?- planning_on_day(monday, Xs). 有什么期望?
  • @repeat 我期待Xs = [tom, thomas];
  • 还有更多答案吗?排列呢?

标签: prolog


【解决方案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]]

【讨论】:

    猜你喜欢
    • 2019-05-10
    • 1970-01-01
    • 2011-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多