我正在尝试在prolog中实现vertex covering。我在考虑做以下事情:
以下列格式[(VertexSouce/VertexDest), ...]
使用图表,并在图表中传递多个总顶点。所以谓词看起来像vertexCover(NodeCount, Graph, MaxNodesInResult, Result)
。 Result
应小于MaxNodesInResult`
我得到了以下示例输出:
?- vertexCover(6,[(1/2),(1/3),(2/3),(2/4),(3/5),(4/5),(4/6)],3,L).
L = [1,3,4] ;
L = [2,3,4] ;
false.
?- vertexCover(6,[(1/2),(1/3),(2/3),(2/4),(3/5),(4/5),(4/6)],2,L).
false.
任何帮助表示赞赏!
答案 0 :(得分:3)
这应该是对Dartuso正确解决方案的评论,但它不适合。所以这里作为另一种选择。使用Dartuso的代码,您会得到重复的答案:
?- vertexCover(6,[(1/2),(1/3),(2/3),(2/4),(3/5),(4/5),(4/6)],3,L).
L = [1, 3, 4] ;
L = [1, 3, 4] ;
L = [2, 3, 4] ;
L = [2, 3, 4] ;
L = [2, 3, 4] ;
L = [2, 3, 4] ;
false.
获得重复的答案并没有错。但有时我们希望出于性能原因而避免使用它们,或者只是为了获得更好的输出。
在这种情况下,复制来自以下事实:单个边缘可以通过多种方式出现在封面中:
?- isIn([1, 3], (1/3)).
true ;
true ;
false.
这是因为Dartuso给出的isIn/2
条款并不相互排斥。第一个和第二个子句都匹配此查询,这就是您获得两次成功的原因。
有几种方法可以“修复”这个问题。最干净的是添加条件以排除先前条款已涵盖的案例:
isIn([A|_],(X/_)) :-
A = X.
isIn([A|_],(X/Y)) :-
dif(A, X),
A = Y.
isIn([A|T],(X/Y)) :-
dif(A, X),
dif(A, Y),
isIn(T,(X/Y)).
这里dif/2
谓词表达了不平等。因此,第二个子句在第一个子句中的等式已经涵盖的情况下不再能够成功,这消除了重复的成功和重复的答案:
?- isIn([1, 3], (1/3)).
true ;
false.
?- vertexCover(6,[(1/2),(1/3),(2/3),(2/4),(3/5),(4/5),(4/6)],3,L).
L = [1, 3, 4] ;
L = [2, 3, 4] ;
false.
一个不太好的解决方案使用“if-then-else”构造Condition -> TrueBranch ; FalseBranch
,这不是没有问题的(但非常实用!):
isIn([A|T],(X/Y)) :-
( A = X
-> true
; A = Y
-> true
; isIn(T, (X/Y)) ).
或者,正如我在实践中写的那样:
isIn([A|T],(X/Y)) :-
( ( A = X ; A = Y )
-> true
; isIn(T, (X/Y)) ).
使用后一种解决方案,上面的查询只会成功一次,甚至不会留下选择点:
?- isIn([1, 3], (1/3)).
true.
有了这个,整个谓词也不再有重复的答案:
?- vertexCover(6,[(1/2),(1/3),(2/3),(2/4),(3/5),(4/5),(4/6)],3,L).
L = [1, 3, 4] ;
L = [2, 3, 4] ;
false.
在这种特殊情况下,if-then-else只会删除不需要的重复解决方案,但一般情况下它可以消除您想要的解决方案。小心使用。
(其他人可能会告诉你使用剪切运算符!/0
,因为它比某些解决方案更短。不要让步。更短的代码不会自动更好的代码,并且削减使你的代码特别复杂和困难理解和修改。)
答案 1 :(得分:2)
这是一个有效的解决方案,感谢Isabelle的修复!正如她提到的另一个解决方案,我发现在第二行封面/ 2上添加了一个剪切,但她的解决方案更清晰。
var visited = sessionStorage.getItem('visit');
if (visited == null || document.location.href == sessionStorage.getItem('lastPage')) {
setTimeout(function() {
alert('Hello World')
}, 10000
)
sessionStorage.setItem('visit', 1);
};