【发布时间】:2015-01-22 20:01:54
【问题描述】:
当尝试在没有循环的情况下测试直线上的可达性时,您可以使用 Bitboard 表示。想象一下国际象棋,棋盘的一行或一列表示为一个字节,以及一个问题,如果 X 方格上的 Rook 可以捕获方格 T 上的目标。
令T:目标,X:开始,O:其他占用方格,_:空方格
我发现使用这些符号来可视化可能的场景很方便:
// __OXO___ -> X is between others on both sides
// __XOO___ -> X is leftmost of others
// __OOX___ -> X is rightmost of other others
//A: T_OOX___ -> Target left of X x not leftmost -> T > X and O > X -> NOT reachable
//B: T_XOO___ -> Target left of X, X leftmost -> T > X and O < X -> reachable
//C: __OXO_T_ -> Target right of X, X embedded -> T < X and ???? -> NOT reachable
//D: __OOX_T_ -> Target right of X, X rightmost -> T < X and ???? -> reachable
这里有 4 个感兴趣的案例 - 从 A-D 标记。情况 A 和 B 很容易处理。
但案例 C 和 D 不是。您不能简单地测试 > 或
但是,可以做的是通过镜像字节中的位将 C,D 转换为 A,B。所以位 0 -> 位 7,位 1 -> 位 6,...
有谁知道是否有优化的实现来进行翻转?
编辑:我刚刚注意到另一种情况是:E:OT__X___ ...我的理论变坏了,但问题仍然存在。 :)
【问题讨论】:
-
如果您只使用一个字节(8 位)而不是更长的整数类型,那么简单的查找表可能是最有效的。我确信它可以通过一些位操作序列来完成(即使它只是一个幼稚的逐位移位),但是除非您的 CPU 具有针对该类型位的本机指令集,否则这不太可能快得多洗牌……
-
是的,我能想到的最便宜的位改组涉及一个具有 8 次迭代的循环,一个和一个或一个或两个移位。没有比这更便宜的了?
-
这对我来说似乎很复杂,但也许我不明白。没有区别;
can T moving to X和can X moving to T。在任何一种情况下,它们总是相等的,所以不要试图反转位,而是反转逻辑。 -
如果您尝试执行bit-reversal permutation,那么会有一种有效的方法,但我认为没有一种方法可以有效地反转位。