簡體   English   中英

如何從整數向量生成唯一的 hash 鍵?

[英]How to generate a unique hash key from a vector of integers?

只是為了好玩,我正在嘗試實現 A* 搜索來尋找解謎者。 我想在 hash 中保留迄今為止訪問過的所有州。 state 基本上是從015的整數向量。 (為了不破壞這個謎題,我暫時不會提供更多信息。)

(defstruct posn
  "A posn is a pair struct containing two integer for the row/col indices."
  (row 0 :type fixnum)
  (col 0 :type fixnum))

(defstruct state
  "A state contains a vector and a posn describing the position of the empty slot."
  (matrix '#(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0) :type simple-vector)
  (empty-slot (make-posn :row 3 :col 3) :type posn))

因為似乎我必須檢查大約 100.000 個states ,所以我認為生成一些數字作為 hash 鍵而不是直接使用 state 會更有效,並且每次都需要檢查使用equal

我從

(defun gen-hash-key (state)
  "Returns a unique(?) but simple hash key for STATE which is used for tracking
if the STATE was already visited."
  (loop
     with matrix = (state-matrix state)
     for i from 1
     for e across matrix
     summing (* i e)))

但必須知道,這並不會導致真正獨特的 hash 密鑰。 例如,向量'#(14 1 4 6 15 11 7 12 9 10 3 0 13 8 5 2))'#(15 14 1 6 9 0 4 12 10 11 7 3 13 8 5 2))都會導致940導致 A* 搜索錯過狀態,因此破壞了我的整個想法。

在我繼續以業余方式調整計算之前,我想問一下是否有人可以指出一種以有效方式生成真正唯一密鑰的方法? 我缺乏正規的 CS 教育來了解是否有生成此類密鑰的標准方法。

您無需創建一些特殊的 hash 密鑰:語言會為您完成!

特別是equalp在 arrays 和結構上具有您想要的行為。

對於 arrays:

如果兩個 arrays 的維數相同,則維數匹配,對應的活動元素相等。 arrays 專用的類型不需要匹配; 例如,一個字符串和一個恰好包含相同字符的通用數組是equalp。 因為 equalp 對字符串進行逐個元素的比較並忽略字符的大小寫,所以在 equalp 比較字符串時會忽略大小寫區別。

對於結構:

如果兩個結構體 S1 和 S2 有相同的 class 並且 S1 中的每個槽的值在 equalp 下與 S2 中相應槽的值相同。

equalpmake-hash-table的可用測試函數之一,這意味着您可以制作哈希表,您的 state 結構將正確地 hash 。

16個整數,取值范圍從0到15,可以用一個64位的integer表示:64位除以16表示每個數字4位, (expt 2 4)是16。例如:

CL-USER> #(14 1 4 6 15 11 7 12 9 10 3 0 13 8 5 2)
#(14 1 4 6 15 11 7 12 9 10 3 0 13 8 5 2)

CL-USER> (loop
        for c across *
        for i = 1 then (* i 16)
          sum (* i c))
2705822978855101470

使用第二個向量:

CL-USER> #(15 14 1 6 9 0 4 12 10 11 7 3 13 8 5 2)
#(15 14 1 6 9 0 4 12 10 11 7 3 13 8 5 2)

CL-USER> (loop
        for c across *
        for i = 1 then (* i 16)
          sum (* i c))
2705880226411930095

您還可以預先計算所有因素:

CL-USER> (coerce (loop for i = 1 then (* i 16) repeat 16 collect i) 'vector)
#(1 16 256 4096 65536 1048576 16777216 268435456 4294967296 68719476736
  1099511627776 17592186044416 281474976710656 4503599627370496
  72057594037927936 1152921504606846976)

我不確定你從中獲得了多少。 請注意,如果您花費大量時間將數字轉換為向量,則不使用equal進行散列的好處可能會超過計算這些散列的成本。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM