基于整数向量执行位排列的有效方法?
Efficient way to perform bit permutations based on a vector of integers?
我有一组 64 位整数,我需要在其上应用一定数量的"对称操作"。对称运算只是一系列位排列,存储在 int 向量中为 {i0,i1,i2,..},其中 bit[0]->bit[i0]、bit[1]->bit[i1],等等......事实上,我只是使用 N 个前位,其中 N 是在运行时确定的,但原则上可以达到 64。
例如,我正在使用 N=4,输入是整数 3 或 0011,并且我在向量 symmetry_ops 的向量中存储了 4 个对称运算
symmetry_ops[0] = {0,1,2,3};
symmetry_ops[1] = {1,2,3,0};
symmetry_ops[2] = {2,3,0,1};
symmetry_ops[4] = {3,0,1,2};
我想要一个函数,它返回通过将这些运算应用于 3 获得的 4 个整数,即 0011、0110、1100 和 1001。这个例子是微不足道的,但在实践中,排列可能比向左移动要复杂得多。
我写了以下简单(天真?(的代码:
std::vector<unsigned long> apply_symmetries(const std::vector<std::vector<unsigned> > &symmetry_ops, unsigned long state)
{
unsigned N = symmetry_ops[0].size();
std::vector<unsigned long> s_moved(symmetry_ops.size(),0);
for (unsigned i = 0; i < N; i++) {
unsigned long s_i = (state&(1UL<<i))>>i; // extracts bit i in state
for (unsigned op = 0; op != symmetry_ops.size(); op++)
s_moved[op] = s_moved[op]|(s_i<<symmetry_ops[op][i]);
}
return s_moved;
}
它对整数"状态"执行所有对称操作。我只是在 i 的循环中一个接一个地进行,首先将其存储在 s_i 中,然后为每个对称操作移动它。
知道,这是我的程序中最耗时的部分之一,因为典型的大小是 ~100-200 个对称操作,应用于 ~10^10 个整数,N 约为 40。代码正常工作,但我想知道是否可以优化此功能?
提前谢谢。
首先,如果您在代码中添加注释来解释什么是什么,这将有所帮助。 还要选择描述性变量名称,不要选择"s_i"或"s_moved"作为变量名称,它会使代码不可读。 "symmetry_ops"是一个不错的名称选择,"州"也是如此,其他的则不然。
无论如何,为了加快代码速度:如果你有一个对称运算将位 i 发送到位 x,而下一个对称运算将位 x 发送到位 y,那么将两者结合起来就像在单个操作中将位 i 发送到位 y 相同。
因此,首先单独循环操作。
对于每个对称操作,将其应用于前一个,然后通过循环将该新操作用作前一个。 然后,您可以为整个事物构建一个对称操作。 我正在编写伪代码来明确这一点。
identity_op = {0, 1, 2, 3, 4, 5, 6, 7} //vector of int, maps each bit to same bit
previous_op = identity_op
for each op { //op is vector of ints, op[i] maps bit i to op[i]
//combine op with prev_op to make a new prev_op
for each i in op {
prev_op[i] = op[prev_op[i]] //bit i is mapped by prev_op and then mapped again by op, giving new value for prev_op
}
}
combined_op = previous_op
apply combined_op to the bits, this is only place you need to to bit shifting
您的C++代码看起来不错,只需重写即可使用此新算法。
- 比较并显示使用最小值(a,b)和最大值(a、b)升序排列的4个数字
- 欧拉项目#8答案是大以获得有效答案
- 为什么不;名字在地图上是按顺序排列的吗
- 调整大小后指向元素值的指针unordered_map有效?
- C++优先级队列,按对象的唯一指针的特定方法升序排列
- 为什么是0;C++中的有效语句
- 最高有效数字侧的第N位
- 按对象的特定方法按升序排列的C++优先级队列
- GCC对可能有效的代码抛出init list生存期警告
- 有效地使用std::unordered_map来插入或增加键的值
- c++中O(n^(1/3))中一个数的除数的有效计数
- 使用无符号字符数组有效存储内存
- 自定义先决条件对移动分配运算符有效吗
- 基于整数向量执行位排列的有效方法?
- 列出 n 个对象的所有 k 排列的有效方法,同时满足特定标准
- 如何有效地计算顶部排列
- 是否有一种记忆有效的方法来探索从输入排列产生的解决方案
- 使用递归的括号有效排列的输出差异
- 如何在C++中更有效地生成这么多排列
- 有效地计算随机排列中的第n项