【问题标题】:What are some other options for generating bit grids of size N生成大小为 N 的位网格还有哪些其他选项
【发布时间】:2015-11-20 17:21:51
【问题描述】:

众所周知,方位网格的排列可以使用蛮力算法计算,其中从 0...((2^cells)-1) 的整数循环可以转换为每个网格排列使用一个位掩码。几个例子:

Grid size 2 (4 cells): 0-->15

Grid size 3 (9 cells): 0-->511

这对于达到一定大小的网格效果很好,但对于大小为 7 或更大的网格,循环操作的绝对数量会达到数万亿。

还有哪些其他选择?

我已经有最大为 6 的网格的工作代码,但一个快速的Fermi estimate 有一个大小为 7 的网格,在我的工作站上大约 76 年出现,所有 CPU 最多...:-(

目标应用

关于所述网格的实际应用,这与Nurikabe puzzle 几乎相同,但我只对可以在其 X 或 Y 轴(最好是两者)上镜像的网格感兴趣。所以一些合适的图案可能是菱形 (X & Y)、字母 D (Y) 或字母 A (X)。

现有效率

由于目标应用程序的变幻莫测,有很多候选人可以被丢弃:

  • 那些不在网格边缘创建单元格的方法
  • 无法跨 X 或 Y 轴镜像的那些
  • 细胞被分离的地方

样本输出(N=4)

Current value is : 28662
 ## 
####
####
 ## 

Current value is : 40953
#  #
####
####
#  #

Current value is : 63087
####
 ## 
 ## 
####

Current value is : 63903
####
#  #
#  #
####

Current value is : 65535
####
####
####
####

Grid size 4, done in 22 milliseconds

【问题讨论】:

  • 您是否尝试生成所有可能的网格?
  • 对不起,什么是位 grid ?你的意思是位 array 吗?
  • 抱歉,是的 - 位数组。
  • @MichaelSPriz 由于我正在处理网格,它只是其中的一小部分,因为我希望所有形状都接触网格的侧面。因此,鉴于最后一行必须有一些东西,实际上我可以从左下角的位值开始(例如 4096 用于 4x4 网格)。

标签: algorithm language-agnostic


【解决方案1】:

信息守恒表明没有办法以比 O(2^cells) 更好的速度生成所有数组模式 - 您必须至少考虑每种情况一次。

但是,您可以通过并行生成每个数组模式、使用打包位集或 SIMD 来优化它。

有一种系统地生成位模式的技术,称为最大长度序列。生成算法的关键特征是每个可能的位模式(对于一定数量的单元)EXACTLY ONCE。它使用 XOR 迭代计算连续值,可以使用 SSE/MMX 对其进行优化(达到合理的大小)。

链接:http://web.iitd.ac.in/~saifkm/docs/EEL319/Practical/expt3_319.pdf

【讨论】:

  • 为什么选择 MLS?这会比仅仅增加更好吗?
  • @harold 总体来说很好,但特别是对于 SIMD 并行化,x86 架构上的 xorps 指令比 addps 快​​。见agner.org/optimize/instruction_tables.pdf
  • @harold 当然 SSE 4.2+ 仍然不支持对 128 位整数求和 - 无论如何它也没有针对整数计算进行优化。而 XOR 是按位的,不考虑数据的解释方式
  • 为什么要浮动指令?我只是在想 paddq(一次做两个),确定它不是 128 位,但无论如何迭代 128 位空间是没有希望的
  • @harold 正如我所说,xorps 不能将数据作为浮点数工作 - 只是一个位模式(并且它没有进位)。我不知道您所说的迭代是什么意思,因为 SSE 是并行进行的
【解决方案2】:

有 2^n 个大小为 n 的位掩码。您不可能希望以小于 2^n 的复杂度生成它们。您需要一个替代解决方案来解决您不生成所有位掩码的问题,或者您将无法提高此值。

【讨论】:

  • 我认为他指的是 width 7 的方形网格 - 相当于 49-long 位模式
  • @willywonka_dailyblah 为什么是 49?网格的尺寸是多少?根据他自己的评论,OP 指的是位数组。假设网格的大小是正方形你当然是对的,但答案的本质仍然是正确的
  • 如果它是正方形的,那么它将是 O(4^n) >> O(2^n)。但你是对的
  • @willywonka_dailyblah 在 OP 的最后一次编辑之后,我相信他真的是指方形网格。答案已编辑
  • 我已经在问题中添加了一些我已经内置的效率
【解决方案3】:

如果您只对可以镜像的网格感兴趣,那么只需生成四分之一或一半的网格,然后进行镜像。

对于 7x7:

X 和 Y 镜像: 生成所有可能的 X 和 Y 轴排列 2^(7 + 7 - 1) 乘以所有可能的 3x3 排列 2^(3 * 3)。由于 3x3 将在 4 个角上进行镜像,因此仅生成 2^13 * 2^9 排列 4,194,304。

X 或 Y 镜像:为 1 轴 2^7 生成排列,为 3x7 网格 2^21 生成排列,总共 268,435,456

对于 8x8:

X 和 Y 镜像:所有 4x4 排列 2^16 或 65536。

X 或 Y 镜像:所有 4x8 排列 2^32 ~40 亿(现代计算机应该能够在一分钟内完成此操作)。

【讨论】:

    猜你喜欢
    • 2010-10-12
    • 1970-01-01
    • 2022-01-03
    • 2020-05-14
    • 1970-01-01
    • 1970-01-01
    • 2011-05-16
    • 2011-06-02
    • 1970-01-01
    相关资源
    最近更新 更多