【问题标题】:Determining if a bit array is in a collection of bit arrays确定位数组是否在位数组的集合中
【发布时间】:2021-01-01 13:54:48
【问题描述】:

给定二维 NxN 位数组,我正在尝试评估确定位数组是否已经在大量先前见过的位数组中的最佳方法。

一种直接的方法是将位数组放入哈希表中。但是比较数组需要一个 #'equalp :test 函数,这可能不是很有效。 (但也许 SBCL 会自动针对不同的密钥类型进行优化?)

另一个计划是将所有位数组转换为整数,并将整数放入哈希表中。那么测试可以是#'eql:

(defun bit-arr-to-int (bit-array)
  (reduce (lambda (bit1 bit2)
            (+ (* bit1 2) bit2))
          (make-array (array-total-size bit-array)
                      :displaced-to bit-array)))

但不确定这是否最终会比让 SBCL 处理事情更有效,因为它仍然单独处理每个元素。也许定制的哈希表会提供效率优势?

第三种选择可能涉及将基本表示从位数组更改为简单位向量(也称为整数),因为原始位数组的维度是已知的。为了允许数组等效的元素引用,这将需要一个将隐式数组 row,col 坐标转换为显式简单位向量索引的函数。根据需要计算索引可能比为每个哈希表查找将整个位数组转换为整数更有效,如上所述。

欣赏一些经验丰富的见解。

【问题讨论】:

    标签: arrays common-lisp bitarray bitvector


    【解决方案1】:

    我认为了解这一点的唯一方法是尝试一下,看看什么是最快的。

    您可以尝试的一个可怕的技巧是将位向量表示为(row-length . integer-of-bits) 的缺点。您需要行长度,以便可以计算位整数的偏移量。然后你可以做这样的事情(这些可能是错误的,因为我总是被dpbldb弄糊涂了):

    (deftype index ()
      `(integer 0 ,most-positive-fixnum))
    
    (defun make-bv (columns)
      (declare (type index columns))
      (cons columns 0))
    
    (defun bv-ref (bv row column)
      (declare (type (cons index integer) bv)
               (type index row column))
      (let ((columns (car bv)))
        (assert (< column columns) (column) "column out of range")
        (ldb (byte 1 (+ (* row columns) column)) (cdr bv))))
    
    (defun (setf bv-ref) (bit bv row column)
      (declare (type bit bit)
               (type (cons index integer) bv)
               (type index row column))
      (let ((columns (car bv)))
        (assert (< column columns) (column) "column out of range")
        (setf (cdr bv) (dpb bit (byte 1 (+ (* row columns) column)) (cdr bv)))
        bit))
    

    在现实生活中你当然想内联这些东西。

    这样的表示可能有利于散列(您可以只对 equal 进行散列,或者甚至为 cons 中的两个元素嵌套 eql 散列表),但值得注意的问题是它不关心有多少对象拥有的行数:它们本质上都有无限多的行数。

    如果“数组”非常大,并且您在其中更改了很多位,那就太糟糕了,因为每次更改位都会消耗一个新的大数。

    但我认为了解的唯一方法是衡量。

    【讨论】:

    • 感谢您概述了我可以尝试的有趣的第三个选项。我最正的fixnum是4611686018427387903,所以看起来我可以有效地处理多达7x7位数组= 49
    猜你喜欢
    • 2020-02-18
    • 2014-03-22
    • 2015-06-25
    • 1970-01-01
    • 2013-06-01
    • 2020-05-10
    • 1970-01-01
    • 2015-11-11
    • 2018-08-07
    相关资源
    最近更新 更多