我决定学习prolog只是为了好玩,我找到了解决这个问题的方法 .
我能够在纸上解决这个难题,但我无法将其传递给代码 .
问题:
我有8名候选人(Lia,Mel,Nanda,Olga,Rute,Sara,Tina,Pilar) . 他们将在周一至周五的8:00和9:00进行测试 .
我有一些规则,如:
Sara将于周三9点接受测试 . 周三,8岁的女孩将不会接受测试.Pilar必须在Nanda之前进行测试 . Olga将在Mel的同一天进行测试 . 如果Lia在任何一天的8天进行测试,那么Rute必须在不同的日子进行8次测试 .
我 don't want 完整的解决方案,我只是想从一开始就有所帮助 .
我试图写一些东西,但没有成功 .
% Facts %
candidate(lia).
candidate(mel).
candidate(nanda).
candidate(olga).
candidate(pilar).
candidate(rute).
candidate(sara).
candidate(tina).
day(monday).
day(tuesday).
day(wednesday).
day(thursday).
day(friday).
time(8).
time(9).
/*Sara HAS TO be tested on Wednesday at 9*/
tested_on(sara, wednesday, 9).
/*No test will happen on Wednesday at 8*/
no_test(X, wednesday, 8) :- X == none.
我甚至试图 Build 一个 struct
cand(
sara,
date(wednesday, 9)
).
之后,我的程序将不得不回答一些问题,如:
从星期一到星期五,哪个候选人将在8:00进行测试?
我的主要想法是开始编写规则和事实然后我'd go through all the rules testing each one. But I can'甚至写 facts
和 rules
对......
2 回答
Prolog是一种声明性语言 . 专注于清楚地描述每个解决方案的内容 . Prolog系统将为您完成剩下的工作 . 不要说:"I'd go through all the rules testing each one" . 更好的说法:“我说明了解决每个解决方案的属性 . ”这是因为,当您完成后,您的谓词可用于多个方向:是的,您可以使用它来测试给定的解决方案 . 但是,如果可能,您还可以使用它来生成解决方案,并完成部分填充的计划 .
首先:
schedule(S) :- ...
这被理解为:
S
是一个时间表 if ....现在,填写点:在任何有效的时间表中有哪些属性?这些是您的任务中给出的约束,在Prolog中表示为目标 .如您所愿,我不会给您一个完整的解决方案,但有一些提示可以帮助您入门 . 我正在使用CLP(FD)约束来声明性地陈述所有要求 . 该代码在SICStus,SWI,YAP,GNU Prolog和其他几个系统中运行,最多只需稍作修改 .
首先,为了表示可用的时隙,我使用整数0..9 . 具体来说,我使用:
例如,星期四9:00由整数
7
表示 .每个候选者是有限域变量,表示候选者被分配的时隙 .
我将时间表表示为时间列表,每个候选者一个,按任务描述中的顺序列出 .
仅使用CLP(FD)谓词来编码指定的约束 . 查看Prolog系统的文档,了解这些谓词的含义 . 例如,对于SICStus Prolog,请查看membership constraints和arithmetic constraints . 同样适用于其他系统 .
这是一个开始:
如您所见,这与任务描述中出现的约束密切对应 . 例如,Sara只能在星期三9:00安排,并且根据上表,该特定时隙对应于整数
5
,变量Sara
表示Sara被调度的时隙 . 因此,我们陈述约束Sara #= 5
. 同样,周三8:00也无法安排任何人 . 此时隙对应于整数4
,因此我们声明约束maplist(#\=(4), Vars)
,当且仅当Vars
中的每个变量不等于((#\=)/2
)到4
时才为真 .我将编码最后两个约束作为练习留给你 . 尝试很好地和紧凑地编码它们 .
具有编码约束的示例解决方案:
请注意,巧合的是,这甚至满足了我们尚未明确编码的最后一个约束 .
为了简化日期比较,一个小的表示更改很方便:
然后我们可以将解决方案表示为对的列表
(Date,Time)
,其中列表中的位置代表女孩:域生成有点棘手:我们必须得到所有不同的Day,Time对 . 第一种低效的方法
而这种替代方案更快
(dom / 1适用于任何长度,我选择6来举例说明......)
例如,现在可以表达约束
约束
可能很棘手:这意味着该对
(3,8)
不能出现在Dom中 . 但是使用if / then / else构造变得容易 .如果您需要更多线索,请告诉我 .