我遇到一个问题,我有一个元素列表,我必须循环遍历特定/ 2谓词的所有实例,以找到其列表中具有最多匹配元素的那个。在实现方面,我似乎无法弄清楚到目前为止我应该如何更新最高匹配,然后在没有更新时停止。
findAnswer(MyList, HighMatchNum,_):-
answer(X,Y),
myIntersection(MyList, Y, NUM), //handles a single instance check and returns how many elements match.
NUM > HighMatchNum,
findAnswer(MyList, NUM, answer(X,Y)).
//Knowledge base
answer(sample1, [a,b,c,d]).
answer(sample2, [d,c,e]).
答案 0 :(得分:2)
为了找到最好的,我们必须搜索整个列表,直到最后。到目前为止,我们将保持最佳状态并将其得分作为额外的论据:
best_match(MyList,R-RN):-
findall(X, (answer(A,L), X=A-L), ALL),
ALL = [A-L|T],
myIntersection(MyList, L, N),
find_best(MyList,T,A,N,R,RN).
find_best(_,[],A,N,A,N).
find_best(MyList,[B-H|T],A,N,R,RN):-
myIntersection(MyList, H, K),
( K>N -> find_best( MyList, T, B, K, R, RN)
; find_best( MyList, T, A, N, R, RN ).
这会产生最佳匹配的名称和分数。
答案 1 :(得分:2)
有库(aggregate):
findAnswer(MyList, HighMatchNum, K) :-
aggregate_all(max(N, Key),
( answer(Key, List),
myIntersection(MyList, List, N)
),
max(HighMatchNum, K)).
myIntersection(MyList, List, N) :-
intersection(MyList, List, L),
length(L, N).
% Knowledge base
answer(sample1, [a,b,c,d]).
answer(sample2, [d,c,e]).
产量
?- findAnswer([a], C, K).
C = 1,
K = sample1.
?- findAnswer([d,e], C, K).
C = 2,
K = sample2.
答案 2 :(得分:1)
简单地断言,我看不出如何在解决方案中传播最大值。
:- dynamic maxval/1
:- maxval(0).
findAnswer(MyList, HighMatchNum) :-
answer(X,Y),
myIntersection(MyList, Y, NUM), %handles a single instance check and returns how many elements match.
NUM > HighMatchNum, %If this fails, try other answer
retract(maxval(_), assert(maxval(X)),!, %else retract the previous value and assert the new one
findAnswer(MyList, NUM).
最后检查maxval / 1的值为maxval(X)。此算法将始终失败,因此您将获得用户数据库中的解决方案,问题在于您的实现,您可能会检查您的逻辑。但它会断言正确的答案。您必须记住始终为任何递归过程实现基本案例。