1

こんにちは、申し訳ありませんが、Prolog は初めてです。事実のリストがあるとします。たとえば、6 つの事実があるとします。数字の最初の列は個人の ID を表し、2 番目の列は個人の勝利数を表します。勝率が最も高い人を見つけたい場合、どうすればよいでしょうか?

wins(1, 22).
wins(2, 24).
wins(3, 23).
wins(4, 20).
wins(5, 21).
wins(6, 19).

そんな感じ?笑 正直なところ、自分が何をしているのかよくわかりません

X = wins(_, Xs) 
Y = wins(_, Ys)
most wins(X) :- Xs > Ys  
4

1 に答える 1

2

その情報を取得する方法は他にもあります。

most_wins(Id) :-
    wins(Id, W), \+ (wins(_, W1), W1 > W).

または、Prolog に library( aggregate ) がある場合:-

most_wins(Id) :-
    aggregate(max(W, Id), wins(Id, W), max(_, Id)).

またはsetof /3を使用できます

most_wins(Id) :-
    setof(N-Id, W^(wins(Id, W), N is -W), [_-Id|_]).

明らかに速度とメモリのトレードオフがあります。最初の方法はメモリ効率が良い O(1) ですが、候補のセットを 2 回スキャンするため、時間の複雑さは O(N^2) になります。2番目と3番目は(私が思うに)実質的に同等です.SWI-prologの現在の実装では、両方とも候補のリストを作成し(その後、空間でO(N)になります)、要素を選択します-時間でO(N log N)。

候補が事実である場合は、最初のものを使用してください。

editさらに別の方法として、効率の観点からは、バックトラック不可能な代入を利用します。外出先で最大を維持しながら、候補をスキャンするだけです。Plain Prolog では、そのようなタスクを実行するために assert/retract が必要になるため、かなり非効率になります。しかし、多くのプロローグには、「グローバル」変数を保存するためのより効率的な方法があります...

于 2013-03-03T16:34:54.773 に答える