@m_seki の

I like ruby tooから引っ越し

デッキの分類と整理

AIタイトルアシスト

デッキ検索の結果から重複するデッキを取り除きたい

ポケカのデッキ検索、10万デッキから検索できるのだけど、意味が重複するデッキがありすぎて、検索結果が同じデッキにばかりになってしまうことが多くなった。

そこで、検索時に同じ意味のデッキは検索されないようにしたくなってきた!

作戦

@deckという変数はキーがデッキのコード、値がデッキを表現するベクトル(Array)のHashである。

ストレージ(sqlite3)から読み出した順でHashを作っているのだが、この順を工夫すれば良いような気がする。

  1. @deckをvalueで分類する。分類っていうのはsortのことなので、sort_byでvalueで並べ替えれば良い
  2. デッキの検索のcoreのループは@deck.mapで全デッキのスコアを計算してる。ループの過程で、同じベクトルが連続する間はサボるようにしたい。そこでchunk_whileでまとめて先頭を取ればOK

できた

diff --git a/src/world.rb b/src/world.rb
index f2d9c86..005e918 100644
--- a/src/world.rb
+++ b/src/world.rb
@@ -42,7 +42,7 @@ class MasakiWorld
     def _search_by_deck_core(all_deck, v, n)
       norm = deck_norm(v)
       return [] if norm <= 0
-      all_deck.map do |b, deck_b|
+      all_deck.chunk_while{|pre, post| pre[1] == post[1]}.map(&:first).map do |b, deck_b|
         c = dot(v, deck_b) / (norm * deck_norm(deck_b)) # cos
         c = 0 if c + Float::EPSILON >= 1 # ignore same deck
         [c, b]
@@ -143,8 +143,13 @@ class MasakiWorld
     end
   end
 
+  def sort_deck
+    @deck = @deck.sort_by {|k,v| v}.to_h
+  end
+
   def make_index
     make_idf
+    sort_deck
     make_norm
     make_name_i
   end

github.com

かっこよ

あわせてよみたい

GitHub - seki/Masaki: Pokemon Card Game Util

Create my own search engine. - RubyKaigi 2022