1

我有一个问题,其中我有一个元素列表,我必须循环遍历特定 /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]).
4

3 回答 3

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 ).

这会产生最佳匹配的名称和分数。

于 2013-04-28T14:34:13.380 回答
2

有图书馆(聚合):

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.
于 2013-04-28T14:40:51.857 回答
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)。该算法将始终失败,因此您将在用户数据库中获得解决方案,问题出在您的实现上,您可以检查您的逻辑。但是,它将断言正确的答案。您必须记住始终为任何递归过程实现基本案例。

于 2013-04-28T14:34:05.460 回答