Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Random 来自掩码的均匀随机位_Random_Rust_Statistics_Bit Manipulation - Fatal编程技术网

Random 来自掩码的均匀随机位

Random 来自掩码的均匀随机位,random,rust,statistics,bit-manipulation,Random,Rust,Statistics,Bit Manipulation,假设我有一个64位无符号整数(u64)掩码,设置了一个或多个位 我想从m中随机均匀地选择一个设置位,以提供一个新的掩码x,从而x&mask具有一个位集。执行此操作的某些伪代码可能是: def uniform_random_bit_from_mask(mask): assert mask > 0 set_indices = get_set_indices(mask) random_index = uniform_random_choice(set_indices) new_m

假设我有一个64位无符号整数(u64)
掩码
,设置了一个或多个位

我想从
m
中随机均匀地选择一个设置位,以提供一个新的掩码
x
,从而
x&mask
具有一个位集。执行此操作的某些伪代码可能是:

def uniform_random_bit_from_mask(mask):
  assert mask > 0
  set_indices = get_set_indices(mask)
  random_index = uniform_random_choice(set_indices)
  new_mask = set_bit(random_index, 0)
  return new_mask

然而,我需要尽可能快地完成这项工作(类似于上面在低级语言中的代码正在减缓热循环)。有人有更有效的方案吗?

如何优化该方案的细节取决于您没有指定的几个因素–目标体系结构、掩码中预期的设置位数、您想要使用的语言、对随机性的要求等等。在不了解更多细节的情况下,很难给出一个有用的答案,但我将给出一些可能证明有用的提示

大多数现代体系结构都有一条指令来计算整数中的设置位数,通常称为“popcount”,该指令在大多数低级语言中公开。在锈迹斑斑的地方,你可以使用。这将提供要从中选择的位的总数
k

然后,您可以在
0
k-1
之间生成一个随机数
i
。下一步是选择
mask
中的
i
th设置位。执行此操作的有效方法是此循环(锈代码):

0..i中的uu的
{
掩码&=掩码-1;
}

让new_mask=1如何优化这一点的细节取决于您没有指定的几个因素–目标体系结构、掩码中预期的设置位数、您想要使用的语言、对随机性的要求等等。在不了解更多细节的情况下,很难给出一个有用的答案,但我将给出一些可能证明有用的提示

大多数现代体系结构都有一条指令来计算整数中的设置位数,通常称为“popcount”,该指令在大多数低级语言中公开。在锈迹斑斑的地方,你可以使用。这将提供要从中选择的位的总数
k

然后,您可以在
0
k-1
之间生成一个随机数
i
。下一步是选择
mask
中的
i
th设置位。执行此操作的有效方法是此循环(锈代码):

0..i中的uu的
{
掩码&=掩码-1;
}

让new_mask=1如果你只能得到,那么你就不必创建一个索引列表。是的,获取设置位的数量更便宜-但我仍然需要在最终掩码中设置位,所以我需要索引?随机函数应该告诉你翻转第I位,这样你就不需要跟踪列表了,但是我相信你仍然需要迭代这些比特。然而,
rand()
函数不是这里真正的瓶颈吗?如果您相信它可以优化,也许您可以说明实际问题。现在我要说的是,这些优化将使您的速度提高不到1%(尽管评测将为您提供准确的值)。@hellow我假设OP想要一个关于Rust的答案,而Pythonish伪代码只是为了说明问题。如果您只获得了,那么您就不必创建索引列表。是的,获取设置位的数量比较便宜-但是我仍然需要在最终掩码中设置位,所以我需要索引?随机函数应该告诉您翻转第I位,这样您实际上不需要跟踪列表,但我相信您仍然需要迭代位。然而,
rand()
函数不是这里真正的瓶颈吗?如果您相信它可以优化,也许您可以说明实际问题。现在我要说的是,这些优化将使您的速度提高不到1%(尽管评测将为您提供准确的值)。@hellow我假设OP想要一个关于Rust的答案,而Pythonish伪代码只是为了说明问题。您是如何想出
mask&=mask-1
?你以前见过类似的东西吗,还是刚刚想到的?我总是忘记你可以用算术运算符做聪明的小把戏too@trentcl很久以前我就见过了,但我不记得是在哪里捡到的。它通常非常有用。:)你是如何想出
掩码&=mask-1
?你以前见过类似的东西吗,还是刚刚想到的?我总是忘记你可以用算术运算符做聪明的小把戏too@trentcl很久以前我就见过了,但我不记得是在哪里捡到的。它通常非常有用。:)
for _ in 0..i {
    mask &= mask - 1;
}
let new_mask = 1 << mask.trailing_zeros();