大家好,我还是新手,我仍然不知道如何用Prolog来解决这个难题,我做了一些尝试,看起来是错误的和不完整的,这就是问题:
在一次音乐会上,五个学生(约翰、凯特、拉里、玛丽和尼克)演奏了五首乐曲。两个是巴赫,两个是莫扎特,一个是维瓦尔第。有三位小提琴手和两位钢琴家。每个学生只演奏一首曲子,只演奏一支乐器。找出学生的顺序,他们各自的乐器和作曲家,有以下条件:
在这里,我的half-code:
List=[
musicians(_,_,_,_),
musicians(_,_,_,_),
musicians(_,_,_,_),
musicians(_,_,_,_),
musicians(_,_,_,_)],
member(musicians(1,_,_,mozart),List) ,
member(musicians(5,_,_,vivaldi),List) ,
member(musicians(_,_,P1,mozart),List) ,P1\==piano,
member(musicians(3,kate,_,_),List) ,
member(musicians(_,john,_,mozart),List) ,
member(musicians(N1,nick,piano,_),List) ,N1==john_num+1,
member(musicians(_,mary,_,C1),List) ,C1\==vivaldi,N1==john_num+1,之后写尼克声明发布于 2017-04-12 19:30:22
我做过这种事很多次了。首先,您需要一个函数来解决这个问题:
solve(List) :- % and now you can go on to define List, etc.下面是我的方法:生成和测试方法。
solve(List) :-
generate(List),
verify(List).generate(List)将生成所有可能的解决方案,而verify只允许与约束匹配的解决方案。这是最基本的方法。我通常会在生成部件的过程中进行交叉验证,以便尽快抛出糟糕的解决方案。
使用member的解决方案很有趣,而且可能会工作,但在测试它之前,您仍然需要生成一个东西。例如,这是行不通的:
member(musicians(_,mary,_,C1),List) ,C1\==vivaldi因为在member的末尾,C1是不绑定的,所以C1\=vivaldi必然会失败。但这样做是可行的:
member(C1,[bach, mozart]), member(musicians(_,mary,_,C1),List)#2a问题也由此而来:
member(ViolinNumber1,[1,2,3,4,5]), member(ViolinNumber2,[1,2,3,4,5]),
member(PianoNumber,[1,2,3,4,5]),
ViolinNumber1 < PianoNumber, PianoNumber < ViolinNumber2,
member(musicians(ViolinNumber1,_,violin,_),List),
member(musicians(ViolinNumber2,_,violin,_),List),
member(musicians(PianoNumber,_, piano ,_),List)你通过了,你知道你在两首小提琴之间有一首钢琴曲子。
从一开始就要求订单是唯一的可能是一个好主意,也就是说,第二个插槽中没有两块(比方说):
List=[
musicians(1,_,_,_), % and so onhttps://stackoverflow.com/questions/43375342
复制相似问题