Prolog无流解算器

Prolog无流解算器,prolog,swi-prolog,prolog-toplevel,Prolog,Swi Prolog,Prolog Toplevel,我对Prolog完全陌生,正在做家庭作业。我的程序应该先用深度来解决无流问题,我不需要它的全部代码,但我需要知道如何思考来解决它,或者它将包含哪些部分 要点如下: dot('R',[3,1],[0,3]). 这2个点是红色的,假设将它们连接起来 所以我在想,从一个点到另一个点会有移动,而且已经开始工作了 move([R,C],[NR,NC]):- move_right(R,C,NR,NC). move([R,C],[NR,NC]):- move_Left(R,C,NR,

我对Prolog完全陌生,正在做家庭作业。我的程序应该先用深度来解决无流问题,我不需要它的全部代码,但我需要知道如何思考来解决它,或者它将包含哪些部分

要点如下:

dot('R',[3,1],[0,3]).
这2个点是红色的,假设将它们连接起来

所以我在想,从一个点到另一个点会有移动,而且已经开始工作了

move([R,C],[NR,NC]):-

    move_right(R,C,NR,NC).

move([R,C],[NR,NC]):-
     move_Left(R,C,NR,NC).

move([R,C],[NR,NC]):-

    move_Up(R,C,NR,NC).

move([R,C],[NR,NC]):-

    move_Down(R,C,NR,NC).
我想现在我需要考虑起点和目标,所以起点是初始网格,包含有三种颜色的点,它们都没有连接,所以我需要从起点提取元素,例如红点,通过移动找到2个点之间的所有路径,然后对于每个元素,我将有多条路径,所以我应该做些什么,并且有一个目标我会停下来吗?

也许这个问题让人困惑,但我真的不知道如何解决它,特别是在试图解决这个问题时 从回溯中获得有用信息。


我需要知道的是,例如,我需要一个函数来获取某个内容并返回另一个内容,等等,如果没有它的实现,我将这样做,这是一个广泛的问题

以下是一些快速提示:

将搜索空间的状态表示为5x5个分幅,每个分幅都是非彩色的或以5种可用颜色之一着色。有了SWI Prolog,您就有了奇妙的数据结构(一个关联数组),因此我们可以很好地利用它,而不是在低级别的索引计算中乱搞(可能会慢一点,但谁在乎呢!)

我们的约定是行数第一,列数第二

我们的清洁董事会代表如下:

Board =
 _{ 0 : _{ 0 : black, 1: black, 2: black, 3: black, 4: black },
    1 : _{ 0 : black, 1: black, 2: black, 3: black, 4: black },
    2 : _{ 0 : black  1: black, 2: black, 3: black, 4: black },
    3 : _{ 0 : black, 1: black, 2: black, 3: black, 4: black },
    4 : _{ 0 : black, 1: black, 2: black, 3: black, 4: black } }.
我们也有5支笔,从一条路的一端开始。 这些笔的状态为
fesh
(它们甚至还没有放到电路板上)、
done
(已跟踪有效路径,笔不会变为nove)或
ready

Pens = 
_{ blue   : { row: 0, col: 0, status: fresh },
   red    : { row: 0, col: 3, status: fresh },  
   yellow : { row: 1, col: 3, status: fresh }, 
   orange : { row: 0, col: 4, status: fresh }, 
   green  : { row: 3, col: 4, status: fresh } }. 
因此,搜索空间的状态由下式给出:

State = [ Board, Pens ].
现在是深度优先搜索

谓词
移动(电路板、笔)
被赋予
状态
,并确定:

  • 选择尚未完成的笔(颜色是按固定顺序选择的,但可以自由选择;一种有趣的方法是从电路板状态确定地生成随机的颜色序列)
  • 为该笔选择一个可能的移动(同样,在“重做”下一个可能的移动时)。如果不可能移动,则失败,导致回溯。
    • 特殊情况:如果笔是
      新鲜的
      ,唯一可能的移动是给笔下的瓷砖上色,并将笔设置为
      就绪
  • 从现有的线路板dict生成新的线路板dict
  • 检查笔的路径是否已完成。在这种情况下,笔的颜色设置为
    done
  • 检查是否已完成所有路径。
    • 在这种情况下,它成功了
    • 否则,使用新的
      调用自身

想象一下你必须换乘火车,你的时刻表会告诉你换乘轨道。对于时刻表搜索算法,换乘火车只是一个可能的动作。我们在搜索第1、2、3、4和5栏时也会这样做:

  +-----+-----+-----+-----+-----+
  |  1  |     |     |  2  |  4  |
  +-----+-----+-----+-----+-----+
  |     |     |     |  3  |     |
  +-----+-----+-----+-----+-----+
  |     |     |  3  |     |     |
  +-----+-----+-----+-----+-----+
  |     |  2  |  4  |     |  5  |
  +-----+-----+-----+-----+-----+
  |     |  1  |  5  |     |     |
  +-----+-----+-----+-----+-----+
(不再是颜色,而是数字,然后称之为拼图)

首先是搜索单支笔,这是经典的path/4谓词:

path(X, X, L, L) :- !.
path(X, Z, L, R) :-
   next(X, Y),
   \+ member(Y, L),
   path(Y, Z, [Y|L], R).
我们可以使用已经访问过的列表L,以方便多笔搜索:

multi([], L, L).
multi([X-Y|M], L, R) :-
   \+ member(X, L),
   path(X, Y, [X|L], H),
   multi(M, H, R).
似乎有效,因为示例板相当小:

?- multi([(0,4)-(1,0),(1,1)-(3,4),(2,2)-(3,3),
       (2,1)-(4,4),(2,0)-(4,1)],[],L), write(L), nl.
[(4,1),(4,0),(3,0),(2,0),(4,4),(4,3),(4,2),(3,2),
(3,1),(2,1),(3,3),(2,3),(2,2),(3,4),(2,4),(1,4),
(1,3),(1,2),(1,1),(1,0),(0,0),(0,1),(0,2),(0,3),(0,4)]
开源:

蛮力数字链接求解器

我不明白整个答案1-下一个点在哪里,因为笔只包含一行和一列,我应该添加它吗?2-如果我按顺序在笔中移动会发生什么情况(不使用随机颜色)3-我将更改移动谓词以获取笔和板,然后获取一支笔并尝试移动(上、下、左、右)在改变颜色(如果是新的)后返回新的电路板。从其他方面来说,电路板仍然是一样的,如果没有达到终点,笔也将是一样的?1)-给定一个“状态”,您可以自由决定下一个点应该是什么(根据确定性程序)。储存它没有意义。您将有一个谓词
move_single_pen(Board,Pens,Color,NewBoard,NewPens)
,它从当前
Board
Pens
和固定的
Color
构建
NewBoard
NewPens
。回溯时,它将为带有color
color
的笔生成所有可能的移动。2) 那也行。3) 如果没有有效的移动,谓词应该失败,不会更改任何内容。输入错误?你写了“…并且决定性地:…选择”。这不应该说是非决定性的吗?它可能会减慢搜索速度,在草图中“选择一支笔”的额外自由。比如,如果你有两支钢笔A和B,假设你搜索了4个步骤。然后你搜索AABB,ABAB,BAAB,BABA和BBAA。但它们都是关于董事会效应的等价序列。(阿贝尔群中的正规形应该是A^2*B^2,你只需要搜索这些正规形就可以了)。尽管如此,这个想法还是有一些好处的。范式不必是A^n*B^m,也可以是其他形式。一些交替选择钢笔的策略,只要你不回溯不同的策略。SAT解算器在标记过程中会做这样的事情。这个谜题也被称为“数字链接”。如果你能很快解决这个问题,我想你会被一家非常大规模的集成(VLSI)公司雇用。这就像引脚布线。我从未听说过多格洛:-)
?- multi([(0,4)-(1,0),(1,1)-(3,4),(2,2)-(3,3),
       (2,1)-(4,4),(2,0)-(4,1)],[],L), write(L), nl.
[(4,1),(4,0),(3,0),(2,0),(4,4),(4,3),(4,2),(3,2),
(3,1),(2,1),(3,3),(2,3),(2,2),(3,4),(2,4),(1,4),
(1,3),(1,2),(1,1),(1,0),(0,0),(0,1),(0,2),(0,3),(0,4)]