首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在prolog中解决简单的音乐家逻辑难题

在prolog中解决简单的音乐家逻辑难题
EN

Stack Overflow用户
提问于 2017-04-12 16:49:25
回答 1查看 589关注 0票数 0

大家好,我还是新手,我仍然不知道如何用Prolog来解决这个难题,我做了一些尝试,看起来是错误的和不完整的,这就是问题:

在一次音乐会上,五个学生(约翰、凯特、拉里、玛丽和尼克)演奏了五首乐曲。两个是巴赫,两个是莫扎特,一个是维瓦尔第。有三位小提琴手和两位钢琴家。每个学生只演奏一首曲子,只演奏一支乐器。找出学生的顺序,他们各自的乐器和作曲家,有以下条件:

  1. 作曲家没有连续演奏。维瓦尔第最后一次演奏,莫扎特第一次演奏。
  2. 在两首小提琴之间有一首钢琴曲,第一首和最后一首钢琴曲之间有两首小提琴曲。
  3. 没有莫扎特的钢琴作品。
  4. 凯特演第三名。
  5. 约翰演奏了莫扎特的一首曲子,接着是尼克,他弹了钢琴。
  6. 玛丽没有演奏维瓦尔第的一首曲子。

在这里,我的half-code

代码语言:javascript
复制
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,
  1. 我不知道怎么写关于钢琴和小提琴的第二条声明。
  2. 我不知道如何在约翰N1==john_num+1,之后写尼克声明
  3. 不,我只是坚持用Prolog来解决这个问题,即使是我已经知道了答案,但在prolog中完全是新的,在阅读了教程之后仍然很困惑。
EN

回答 1

Stack Overflow用户

发布于 2017-04-12 19:30:22

我做过这种事很多次了。首先,您需要一个函数来解决这个问题:

代码语言:javascript
复制
 solve(List) :- % and now you can go on to define List, etc.

下面是我的方法:生成和测试方法。

代码语言:javascript
复制
solve(List) :-
   generate(List),
   verify(List).

generate(List)将生成所有可能的解决方案,而verify只允许与约束匹配的解决方案。这是最基本的方法。我通常会在生成部件的过程中进行交叉验证,以便尽快抛出糟糕的解决方案。

使用member的解决方案很有趣,而且可能会工作,但在测试它之前,您仍然需要生成一个东西。例如,这是行不通的:

代码语言:javascript
复制
member(musicians(_,mary,_,C1),List) ,C1\==vivaldi

因为在member的末尾,C1是不绑定的,所以C1\=vivaldi必然会失败。但这样做是可行的:

代码语言:javascript
复制
member(C1,[bach, mozart]), member(musicians(_,mary,_,C1),List)

#2a问题也由此而来:

代码语言:javascript
复制
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)

你通过了,你知道你在两首小提琴之间有一首钢琴曲子。

从一开始就要求订单是唯一的可能是一个好主意,也就是说,第二个插槽中没有两块(比方说):

代码语言:javascript
复制
List=[
    musicians(1,_,_,_), % and so on
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43375342

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档