我正在尝试创建社交图,我必须编写一些Prolog才能获得最小和最强的路径。
我的知识库只有以下声明:
边缘(来源,目的地,重量)
例子:(约翰,玛丽,2)。
现在权重只能是3:
1 - 朋友 2-亲密的朋友 3 - 家庭
这是我的最小路径代码(加权较少)。
findapath(X, Y, W, [X,Y], _) :- edge(X, Y, W).
findapath(X, Y, W, [X|P], V) :- \+ member(X, V),
edge(X, Z, W1),
findapath(Z, Y, W2, P, [X|V]),
W is W1 + W2.
:-dynamic(solution/2).
findminpath(X, Y, W, P) :- \+ solution(_, _),
findapath(X, Y, W1, P1, []),
assertz(solution(W1, P1)),
!,
findminpath(X,Y,W,P).
findminpath(X, Y, _, _) :- findapath(X, Y, W1, P1, []),
solution(W2, P2),
W1 < W2,
retract(solution(W2, P2)),
asserta(solution(W1, P1)),
fail.
findminpath(_, _, W, P) :- solution(W,P), retract(solution(W,P)).
如何包含一个变量来计算行进路径的数量,然后使用它来获得最强的路径?
最强的路径是路径重量/行进路径数。
例如,
重量= 8 N路径行进= 3
8/3 = 2.67力量
这意味着我和目的地之间有3个人(这是社交图),加权总和为8。
但在这种情况下
重量= 7 N路径行进= 7
这将是最小的路径,对吗?是的,因为它是7和7 < 8.然而,它不是最强的路径,因为7/7 = 1,这意味着我和我的目的地之间可能有很多人不像其他路径那样靠近我。
我该怎么做?
答案 0 :(得分:0)
如果您的Prolog系统有keysort/2
和findall/3
,则可以避免
assertz /收回。也就是说,你可以先定义力量
重量如何我理解它:
% path_list_and_weight(+Node,+Node,-Nodes,-Integer)
path_list_and_weight(...) :- ...
% path_list_and_neg_strength(+Node,+Node,-Nodes,-Float)
path_list_and_neg_strength(X, Y, L, S) :-
path_list_and_weight(X, Y, L, W),
length(L, N),
S is -W/N.
然后用他们的力量枚举所有路径列表,并且 钥匙扣。我将力量定义为负值, 所以keysort给了我最高的力量:
% max_path_list_and_strength(+Node,+Node,-Nodes,-Float)
max_path_list_and_strength(X, Y, L, S) :-
findall(T-M, path_list_and_neg_strength(X, Y, T, M), H),
keysort(H, [J-L|_]),
S is -J.
我猜以上某些图表在实践中不起作用,
当有组合爆炸时,path_list_and_neg_strength/4
会有太多的重做。在这种情况下,可能是基于表格的
解决方案更好。
再见