C++ 二维网格中的不同随机点

C++ 二维网格中的不同随机点,c++,random,C++,Random,我有一个大的二维网格,比如说10000 X 10000。从这些网格中,我需要选择1000个随机点,但我还需要注意这两个点都不相同。我想到的标准方法是,在选择每个点之后,我应该检查之前的所有条目,看看是否已经选择了该点,但对于大型网格和大量点,这将变得效率低下。有更好的方法吗? 我使用的是C++您可以实现如下算法: 创建从散列到点的空映射 选择随机点 计算散列 如果映射中存在哈希,则转到1 保存散列点(&P) 如果分数不够,请转到1 您可以实现如下算法: 创建从散列到点的空映射 选择随机点 计算散

我有一个大的二维网格,比如说10000 X 10000。从这些网格中,我需要选择1000个随机点,但我还需要注意这两个点都不相同。我想到的标准方法是,在选择每个点之后,我应该检查之前的所有条目,看看是否已经选择了该点,但对于大型网格和大量点,这将变得效率低下。有更好的方法吗?
我使用的是C++

您可以实现如下算法:

  • 创建从散列到点的空映射
  • 选择随机点
  • 计算散列
  • 如果映射中存在哈希,则转到1
  • 保存散列点(&P)
  • 如果分数不够,请转到1

  • 您可以实现如下算法:

  • 创建从散列到点的空映射
  • 选择随机点
  • 计算散列
  • 如果映射中存在哈希,则转到1
  • 保存散列点(&P)
  • 如果分数不够,请转到1
  • 似乎对于大型网格和大量点,这将变得效率低下

    不一定。效率低下的潜在原因有两个:

  • 拒绝采样造成的开销(也就是说,必须一直尝试,直到找到一个尚未选择的点)。考虑到你选择了0.001%的分数,随机选择同一个分数两次的机会非常小。因此,重新尝试的成本应该可以忽略不计
  • 检查随机选择的点是否已被选择的开销。如果将所有以前选择的点存储在适当的数据结构中,则可以在
    O(1)
    时间内完成。为此,
    std::unordered_set
    将是一个很好的候选。集合的大小将随着需要选择的图元数线性增长,并且与网格大小完全无关
  • 似乎对于大型网格和大量点,这将变得效率低下

    不一定。效率低下的潜在原因有两个:

  • 拒绝采样造成的开销(也就是说,必须一直尝试,直到找到一个尚未选择的点)。考虑到你选择了0.001%的分数,随机选择同一个分数两次的机会非常小。因此,重新尝试的成本应该可以忽略不计
  • 检查随机选择的点是否已被选择的开销。如果将所有以前选择的点存储在适当的数据结构中,则可以在
    O(1)
    时间内完成。为此,
    std::unordered_set
    将是一个很好的候选。集合的大小将随着需要选择的图元数线性增长,并且与网格大小完全无关

  • 随机选择任何点,然后丢弃它(如果它存在于“选定点”列表中)不应该是低效的,只要您有经过良好排序的选定点集合,您也可以轻松地将其插入


    此外,根据点的定义方式(即它们是否都与已定义的类或结构相关联),您可以向点对象添加一个名为
    Selected
    的布尔变量。选择一个点后,请检查该点是否已标记为选定的
    。如果没有,请将其添加到列表中,并将
    所选
    值更改为
    。否则,请继续选择随机点。

    随机选择任何点,然后如果该点存在于“选定点”列表中,则丢弃该点并不低效,只要您已将选定点的集合进行了良好排序,您也可以轻松地将其插入


    此外,根据点的定义方式(即它们是否都与已定义的类或结构相关联),您可以向点对象添加一个名为
    Selected
    的布尔变量。选择一个点后,请检查该点是否已标记为选定的
    。如果没有,请将其添加到列表中,并将
    所选
    值更改为
    。否则,请继续选择随机点。

    对不起,我不懂“哈希”,请详细说明一下。哈希是单向“加密”;有关详细说明,请参阅。如果可用,最好使用现有的哈希映射的确是@Attilla,但这不会改变算法背后的想法。一旦选择了一个点,剩余的点将不再以相同的概率被选择(那些哈希值与第一个点相同的点被选择的概率为零)对不起,我不懂“哈希”,你能详细解释一下吗?哈希是单向“加密”;有关详细说明,请参阅。如果可用,最好使用现有的哈希映射的确是@Attilla,但这不会改变算法背后的想法。一旦选择了一个点,剩余的点将不再以相同的概率被选择(那些哈希值与第一个点相同的点被选择的概率为零)@nim:我甚至建议在这里使用
    std::unordered\u set
    ,因为这些值不需要排序。查找将是
    O(1)
    而不是
    O(logN)
    @LucTouraille,当然,不确定OP是否可以访问C++11,否则我想boost是一个很好的替代品。@nim:我甚至建议在这里使用
    std::unordered\u set
    ,因为这些值不需要排序。查找将是
    O(1)
    而不是
    O(logN)
    @LucTouraille,当然,不确定OP是否可以访问C++11,否则我想boost是一个很好的替代品。你可能不想创建10000 X 10000个对象(每个点一个),尤其是如果只选择了1000个。你想写“高效”吗在你的第一句话里?@Attila:你是对的。不过,我不是在暗示。但是,如果这些点已经是表示点的大型结构数组的一部分,则