0

比較評価システムを実装しようとしていますが、特にデータベースの観点から、これを処理する最善の方法を見つけるのに苦労しています。

食べ物を例に挙げてみましょう。

ユーザーには 2 種類の食べ物の写真が表示され、どちらが好きかを選択します。次に、さらに 2 つの食品が表示され (1 つが同じ場合もあれば、両方が異なる場合もあります)、ユーザーは再び選択します。彼はこれを何度も繰り返し、そうする中で、アプリケーションはユーザーに彼の好きな食べ物が何であるかを伝えます。これは、彼が他の人よりも好きな食べ物を言い、これらすべての比較を比較し、結果を表示することだけに基づいています。

各アイテムの好き嫌いの合計を追跡することだけを考えました。また、大規模なデータベースですべての選択肢を追跡することも考えました。この種のシステムに効率的な、私が見落としている方法があると確信しています。

基本的に、私は効率的なアルゴリズムだけでなく、これをデータベースに格納する最良の方法も探しています。

助けてくれてありがとう。

4

1 に答える 1

2

(user_id, preferred_id, dispreferred_id)それぞれの選択肢に対応するトリプレットのデータベースを保持するだけです。

編集:これで遊ぶのに少し時間がありました。以下は、何百万もの評価に対して遅く、メモリをむさぼり食いますが、アイデアを与えるかもしれません. これを行う場合は、オンデマンドではなく、おそらく crontab から非同期で実行する必要があります。

require 'set'                                                                                                                                                                                                                    

choices = [
  [1, 4],
  [1, 5],
  [2, 3],
  [2, 4],
  [3, 1],
  [4, 2],
  [4, 3],
  [5, 1],
  [6, 7],
  [8, 4],
]

dominates = Hash.new { |hash, key| hash[key] = Set.new }
choices.each do |p, d|
  dominates[p].add(d)
end

prev_dominates = nil
while dominates != prev_dominates
  prev_dominates = Hash.new
  dominates.each { |big, smalls| prev_dominates[big] = smalls.clone }
  prev_dominates.each do |big, smalls|
    smalls.each do |small|
      if prev_dominates.include?(small)
        prev_dominates[small].each do |smaller|
          if smaller != big and !prev_dominates[smaller].include?(big)
            dominates[big] << smaller
          end
        end
      end
    end
  end
end

top = dominates.max_by { |big, smalls| smalls.size }[0]

puts dominates.inspect
puts "BEST: #{top}"

最上位ノードは、最終的に他のほとんどのノードを支配するノードです。ただし、グラフが循環する可能性があることを考えると、別のノードがサイクルをより早く完了する場合は、サイクルをカットします。

于 2013-02-20T07:33:22.567 に答える