Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Search 在列表中获取所有颜色组合?_Search_Prolog_Logic - Fatal编程技术网

Search 在列表中获取所有颜色组合?

Search 在列表中获取所有颜色组合?,search,prolog,logic,Search,Prolog,Logic,我有三种可能的颜色:红、绿、蓝 我有一个初始列表:[蓝,蓝,蓝,蓝] 我基本上需要创建一个搜索算法来查找给定的列表Find(这也是一个包含四种颜色的列表)。这就是搜索算法的框架: look(Find):- search([red, red, red, red], Find). search([A,B,C,D], [A,B,C,D]):- do-something(A,B,C,D). search(Node, Find):- successor(Node, Next), search(

我有三种可能的颜色:红、绿、蓝

我有一个初始列表:[蓝,蓝,蓝,蓝]

我基本上需要创建一个搜索算法来查找给定的列表
Find
(这也是一个包含四种颜色的列表)。这就是搜索算法的框架:

look(Find):- search([red, red, red, red], Find).

search([A,B,C,D], [A,B,C,D]):- do-something(A,B,C,D).

search(Node, Find):-
  successor(Node, Next),
  search(Next, Find).

我的问题是如何定义继承者。我如何才能找到一个我确信我以前没有访问过的继承者,直到我找到一个与列表
find
-特别是当我没有使用谓词中的域({red,blue,green})时。感谢您的帮助。谢谢

您可以使用
member/2
maplist/2
轻松生成4种颜色的所有可能性:

% give me a list of 4 fresh variables
% select a member of [red,blue,green] for each item of L, backtrackably

length(L,4),                                   
maplist([I]>>(member(I,[red,blue,green])),L).  
以上事实与

L=[L0,L1,L2,L3],
member(L0,[red,blue,green]),
member(L1,[red,blue,green]),
member(L2,[red,blue,green]),
member(L3,[red,blue,green]).
小心组合爆炸

如果首选“无状态下一步”。 我们想从现有的红-绿-蓝组合中派生出下一个红-绿-蓝组合

让我们使用CLP(FD)实现颜色和数字列表之间的双射映射

:- use_module(library(clpfd)).

rgbnumber(red,0).
rgbnumber(blue,1).
rgbnumber(green,2).

rgbnumberlist([L0,L1,L2],N) :- 
   rgbnumber(L0,N0), N0 in 0..2,
   rgbnumber(L1,N1), N1 in 0..2,
   rgbnumber(L2,N2), N2 in 0..2,
   N #= N0+N1*3+N2*3*3.

rgbnext(Current,Next,Wrap) :- 
   rgbnumberlist(Current,N),
   succ(N,Nx),
   Nxm is (Nx mod (3*3*3)), % Beware precedence: mod is as strong as *
   (Nx > Nxm -> Wrap = true ; Wrap = false),
   rgbnumberlist(Next,Nxm).
因此:

?- rgbnext([red,red,red],A,Wrap).
A = [blue, red, red],
Wrap = false ;
false.

?- rgbnext([blue,red,red],A,Wrap).
A = [green, red, red],
Wrap = false ;
false.

?- rgbnext([green,red,red],A,Wrap).
A = [red, blue, red],
Wrap = false ;
false.

?- rgbnext([green,green,green],A,Wrap).
A = [red, red, red],
Wrap = true ;
false.

现在,您可以使用它从当前状态查找下一个状态。

感谢您的回复。这是一个很酷的把戏。我还有两个额外的问题:第一,有没有不使用maplist的简单方法?其次(更重要的是),我如何在后续谓词中实现这一点,以确保已检查的颜色组合不会再次检查?谢谢。是的,您可以不用
maplist/2
来完成,但这可以通过如上所示硬编码
L
的长度来完成,也可以通过滚动您自己版本的
maplist/2
来完成,它向下递归
L
,并通过调用
member/2
将每个列表位置约束为一个值。这里没什么好赢的。现在你有了一个用于所有组合的“生成器”,你就不需要递归地调用继任者了。您只需调用映射列表,然后验证颜色是否符合您的要求。如果没有,则验证失败,Prolog返回到映射列表并生成下一个颜色列表,然后再次进行everified等:
search(X):-generate_with_maplist(X)、verify(X)、format(“find solution~q”、[X])。
不幸的是,我的目的是保持算法的框架不变,并且只定义相应的后续算法。这是一个简单的谓词,但我不知道如何简单地实现它。如果你对如何做到这一点有任何想法,我很乐意听到。尽管如此,你给我的解决方案非常有趣,尽管我不能使用它。再次感谢!添加了一个“next”谓词。这不是效率低的,而是效率高的。它还使用CLP(FD)。在模计算中遇到了一些障碍,简直疯了。。。