解决迷宫的可能方法有哪些?
我有两个想法,但我认为它们不是很优雅.
基本情况:我们有一个矩阵,在这个矩阵中的元素,因为它代表一个迷宫的方式是有序的,在一个途径,一个出.
我的第一个想法是将一个机器人穿过迷宫,沿着一侧,直到它离开迷宫.我认为这是一个非常缓慢的解决方案.
第二个通过标记1,检查它可以去(上,右,下,左)每个连续的项目选择的一种方式,它有继续它的路径.这甚至比第一个慢.
当然,如果我在每个交叉点使两个机器人多线程,它会更快一些,但这也不是最好的方法.
需要更好的解决方案来通过迷宫发送机器人.
编辑
第一:谢谢你的好答案!
我的问题的第二部分是:如果我们有一个多维图,该怎么办?有没有特殊的做法,或Justin L.的答案也适用于此?
我认为这不是这种情况的最佳方式.
第三个问题:
这些迷宫求解器算法中哪一个是最快的?(纯粹假设)
如何在一个符合标准的方式写入avs_term_rearranged(AVs, T, AVsR)
与给定的AVs
和T
,使得AVsR
是的置换AVs
作为其变量发生在左到右的顺序与布置在相同的顺序中的元素T
.
AVs
是一个表单元素的列表,A = V
其中A
一个原子指定一个变量名称,'X'
并且V
是一个相应的变量.这些列表由read_term/2,3
read-option variable_names/1
(7.10.3)生成.另外,没有定义元素的精确顺序.
| ?- read_term(T,[variable_names(AVs)]).
A+B+A+_+C.
AVs = ['A'=A,'B'=B,'C'=C]
T = A+B+A+_+C
Run Code Online (Sandbox Code Playgroud)
T
是一个包含所有变量AVs
加上更多的变量的术语.
请注意,在标准符合程序中,不能依赖变量的术语顺序(7.2.1):
7.2.1变量
如果
X
和Y
是不相同的变量,则X
term_precedesY
应依赖于实现,除了在创建排序列表(7.1.6.5,8.10.3.1 j)期间,排序应保持不变.注 - 如果
X
和Y
都是匿名变量,则它们不是相同的术语(见6.1.2 a).
以8.4.3.4为例:
sort([f(U),U,U,f(V),f(U),V],L).
Succeeds, unifying L with [U,V,f(U),f(V)] or
[V,U,f(V),f(U)].
[The solution is implementation …
Run Code Online (Sandbox Code Playgroud) 我正在开发一个Java应用程序,它需要做一些复杂的逻辑规则推导作为其功能的一部分.我想在Prolog或其他逻辑/约束编程语言而不是Java中编写我的逻辑演绎编码,因为我相信生成的代码将更加简单和易于维护.
我在Prolog上搜索了嵌入式Java实现,并发现了它们的数量,每个都只有很少的文档.我的(适度)选择标准是:
我有什么选择,它们的优点和缺点是什么?
java prolog logic-programming embedded-language constraint-programming
我是Prolog的新手并注意到'和'给出了不同的行为,但我很好奇为什么.具体来说,加载文件时,?- ['test1.pl'].
工作,而?- ["test1.pl"].
不是.
我开始学习Prolog,并首先了解了继承符号.
这就是我在Prolog中发现编写Peano公理的地方.
参见PDF的第12页:
sum(0, M, M).
sum(s(N), M, s(K)) :-
sum(N,M,K).
prod(0,M,0).
prod(s(N), M, P) :-
prod(N,M,K),
sum(K,M,P).
Run Code Online (Sandbox Code Playgroud)
我把乘法规则放到了Prolog中.然后我做查询:
?- prod(X,Y,s(s(s(s(s(s(0))))))).
Run Code Online (Sandbox Code Playgroud)
这意味着基本上找到6的因子.
结果如下.
X = s(0),
Y = s(s(s(s(s(s(0)))))) ? ;
X = s(s(0)),
Y = s(s(s(0))) ? ;
X = s(s(s(0))),
Y = s(s(0)) ? ;
infinite loop
Run Code Online (Sandbox Code Playgroud)
这个结果有两个问题:
所以...我的问题是:
我在无限循环中阅读了另一个答案.但我很感激有人根据这个场景做出回答.这对我很有帮助.
prolog infinite-loop successor-arithmetics non-termination failure-slice
纯粹的Prolog程序以清晰的方式区分术语的平等和不平等,导致执行效率低下; 即使所有相关术语都是基础的.
关于SO的最近一个例子是这个答案.在此定义中,所有答案和所有失败都是正确的.考虑:
?- Es = [E1,E2], occurrences(E, Es, Fs).
Es = Fs, Fs = [E, E],
E1 = E2, E2 = E ;
Es = [E, E2],
E1 = E,
Fs = [E],
dif(E, E2) ;
Es = [E1, E],
E2 = E,
Fs = [E],
dif(E, E1) ;
Es = [E1, E2],
Fs = [],
dif(E, E1),
dif(E, E2).
Run Code Online (Sandbox Code Playgroud)
虽然程序从声明的角度来看是完美无缺的,但它在B,SICStus,SWI,YAP等当前系统上的直接执行效率却不必要地低效.对于以下目标,为列表的每个元素保留一个选择点.
?- occurrences(a,[a,a,a,a,a],M). M = [a, a, a, a, a] ; false. …
在ISO Prolog中,仅针对NSTO(不受发生检查)的情况定义统一.背后的想法是涵盖那些主要用于程序并且实际上得到所有Prolog系统支持的统一案例.更具体地说,ISO/IEC 13211-1:1995读取:
7.3.3发生检查(STO)但不受
发生检查(NSTO)
如果存在通过
Herbrand算法的步骤以便
发生7.3.2g 的方式,则一组方程(或两个项)是"经历发生 - 检查"(STO).
如果没有办法继续
Herbrand算法的步骤使得7.3.2g发生,则一组方程(或两个项)"不受发生检查"(NSTO)
....
此步骤7.3.2 g读取:
克)如果存在形式的公式X =吨这样
即X是一个变量,吨是非可变术语
包含该变量,然后用失败(退出不
unifiable,正发生检查).
完整的算法被称为Herbrand算法,并且通常被称为Martelli-Montanari统一算法 - 其基本上通过以非确定性方式重写方程组来进行.
请注意,引入了新的方程式:
d)如果存在形式为f(a 1,a 2,... a N)=
f(b 1,b 2,... b N)的等式,则将其替换为等式集
a i = b 我.
这意味着具有相同算符但具有不同arity的两个复合词将永远不会对STO-ness做出贡献.
这种非确定性使得STO测试难以实现.毕竟,仅仅测试是否需要发生检查是不够的,但为了证明对于执行算法的所有可能方式,这种情况永远不会发生.
这是一个案例来说明情况:
?- A/B+C*D = 1/2+3*4.
Run Code Online (Sandbox Code Playgroud)
统一可以从A = 1
,也可以是任何其他对开始,并以任何顺序继续.为了确保NSTO属性,必须确保没有可能产生STO情况的路径.考虑一个对当前实现没有问题的情况,但仍然是STO:
?- 1+A = …
Run Code Online (Sandbox Code Playgroud) 许多谓词定义了某种通过二元关系定义的边构建的非循环路径,与定义传递闭包非常相似.因此需要通用定义.
请注意,图论中定义的概念不容易与通常预期的匹配.最值得注意的是,我们对边缘的名称不感兴趣.
更糟糕的是,图论也发生了一些变化,引入了步行的概念,注意到了
传统上,路径指的是现在通常称为开放式步行的路径.如今,当没有任何限定地陈述时,路径通常被理解为简单,意味着没有重复顶点(因此没有边缘).(术语链也用于指代所有顶点和边缘都不同的步行.)
所以我的问题是:如何命名和定义此功能?
到目前为止我所做的是定义:
path(Rel_2, Path, X0,X)
Run Code Online (Sandbox Code Playgroud)
第一个论点必须是关系的延续.然后是Path
顶点或顶点.
n(a, b).
n(b, c).
n(b, a).
?- path(n,Xs, a,X).
Xs = [a], X = a ;
Xs = [a, b], X = b ;
Xs = [a, b, c], X = c ;
false.
Run Code Online (Sandbox Code Playgroud)
:- meta_predicate path(2,?,?,?).
:- meta_predicate path(2,?,?,?,+).
path(R_2, [X0|Ys], X0,X) :-
path(R_2, Ys, X0,X, [X0]).
path(_R_2, [], X,X, _).
path(R_2, [X1|Ys], X0,X, Xs) :-
call(R_2, X0,X1),
non_member(X1, Xs),
path(R_2, …
Run Code Online (Sandbox Code Playgroud) 这不是一个家庭作业问题,而是一个考试学习指导问题.Prolog Vs Haskell中的模式匹配有什么区别?
我做了一些研究,阅读背后的理论并没有真正让我对两者有充分的理解.我在Prolog中看到,模式匹配是不同的,因为它具有统一变量的能力,因此能够通过分辨率推断并吐出可能的答案
eg ?- [a,b] = [a,X]
X = b
Run Code Online (Sandbox Code Playgroud)
现在我不确定如何在Haskell中显示模式匹配.我知道Prolog中显示的上述相同查询在Haskell中不起作用,因为Haskell无法像Prolog那样统一.我记得在Haskell得到相同答案的地方,你必须通过警卫明确告诉它.
我知道我非常接近理解它,但是我需要有人为我打破Barney风格所以我可以完全理解它并向12岁的人解释它.这已经困扰了我很长一段时间,我似乎无法找到一个可靠的解释.
顺便说一句,上面显示的例子只是向你们展示我到目前为止所学到的东西,而我实际上是想找到答案.我的主要问题与上述例子无关,而是完全理解两者之间的差异.
Emacs方便地向我展示了git下单个文件的git日志C-x v l.但是我如何查看整个历史?在shell中,我git log
在git下的目录中.是否有更多emacs-affine方式来做到这一点?
prolog ×8
iso-prolog ×3
algorithm ×2
dcg ×1
emacs ×1
git ×1
graph ×1
haskell ×1
java ×1
maze ×1
prolog-dif ×1
unification ×1