【问题标题】:solving simple musicians logic puzzle in prolog在序言中解决简单的音乐家逻辑难题
【发布时间】:2017-04-12 16:49:25
【问题描述】:

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

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

  1. 作曲家没有连续演奏。最后演奏维瓦尔第,先演奏莫扎特。

  2. 在两首小提琴曲之间演奏一首钢琴曲,在第一首和最后一首钢琴曲之间演奏两首小提琴曲。

  3. 没有莫扎特的钢琴曲。

  4. 凯特排名第三。

  5. 约翰演奏了莫扎特的一首曲子,紧随其后的是弹钢琴的尼克。

  6. 玛丽没有演奏维瓦尔第的作品。

这里是我的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,
  1. 我不知道如何写关于钢琴和小提琴的#2 语句。
  2. John N1==john_num+1, 之后我不知道怎么写 nick 声明
  3. 不,我只是坚持使用 Prolog 解决这个问题,即使我已经知道答案,但在 prolog 中是全新的,阅读教程后仍然感到困惑。

【问题讨论】:

    标签: prolog zebra-puzzle


    【解决方案1】:

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

     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)
    

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

    最好从一开始就要求订单是唯一的,也就是说,#2 插槽中没有两块(比如说):

    List=[
        musicians(1,_,_,_), % and so on
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-06-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-27
      • 2020-04-03
      • 1970-01-01
      相关资源
      最近更新 更多