C++ 随机置换非重复序列

C++ 随机置换非重复序列,c++,r,algorithm,C++,R,Algorithm,一年前,我在R论坛上询问如何排列1000次序列,但决不允许重复元素。对于我的需求来说,R中的任何解决方案仍然太慢 问题是这样的: A B C D E F G H I J K L M N O P Q R Z 6537 3156 1736 198 445 138 1129 3849 818 287 2339 1190 275 1035 222 484 242 338

一年前,我在R论坛上询问如何排列1000次序列,但决不允许重复元素。对于我的需求来说,R中的任何解决方案仍然太慢

问题是这样的:

 A    B    C    D    E    F    G    H    I    J    K    L    M    N    O    P    Q    R    Z 
6537 3156 1736  198  445  138 1129 3849  818  287 2339 1190  275 1035  222  484  242  338   59 
对于每个字母都是独立元素的序列,例如

"...IDPGCGDCIDPGCGCDIDPGCGDCPGCIDPFJAIAHAHAHABAHAHABKPGCPGCGCECDGCPGCGCIDIPFCPGEPAJIAEPGCECJIPGCGPGCGCGADPDJDPGCPCPGCDIPEPGCJAJMAHZABAHAHAHABHAHBKRZALOBKAHABKLAHAHAHABKLKLAKLBKABABLAHAHABKBKLOKIABKLAHAHABKLABKALKABKLKAHBAKLABKBAHABLALKABABJLKAKLKHABKCRAHAKLKAKLABKLKLBKAHAKLKECECGDCGECGEDGCDGDGECECEGDCACACAHABABCDCHAHBKCQGCGCQCQGCQCGCACACBKCDCAHACQGCPGCDACAPCQAHAHBKACHAHAHBABCGCGCAHAHAMHMABAHAKLABKCPCFCABCQCQGCGCABHAHANBKQAHAHANANABKLABAKLPCGCGCPCAHABAHAHAHAHANBKALCQCGCECAHABANAHBKAKBKAHABAHBKALBHAHABKLKCPCECALCGCAKPHBAHAHAHAHAHAHABAHAHBKAMJABAHBAHAHBKALKABKPCQBANAHANHABKHBALAHALAHANBANBHABKAHANHAHABKAHAHAHAHAMANIAHABANHABABKBKLHLKLBKLKBKBKBALAHAKLBKLBHKBABHAMABKZAHAHABLKAHABAKABKOKHAKAHAHBKAHAHAHABKLHAHBKAHABKLAHAHABKAIAIAHABKLBAIAIKLKLAHAH..."
我需要排列(随机洗牌)这个序列10000次。原始序列从来没有任何重复的元素。随机抽样序列需要具有与原始序列相同的元素比例,但也没有重复元素。序列长度可达50000个元素。每个元素的总数如下所示:

 A    B    C    D    E    F    G    H    I    J    K    L    M    N    O    P    Q    R    Z 
6537 3156 1736  198  445  138 1129 3849  818  287 2339 1190  275 1035  222  484  242  338   59 
我试着用
R
来解决这个问题。尝试过的每件事都太慢,而且也不太善于发现不重复的元素。我对
C++
不太了解,但我有兴趣通过
Rcpp
尝试利用它来获得一个有效的解决方案

我认为这将是一个有趣的问题,并将在允许的情况下增加悬赏


示例长序列是。

一种方法是通过在随机位置添加新元素,而不是按顺序选择每个元素,一次构建一个元素的序列

使用以下算法:

  • 随机排列列表而不使用非重复约束,以获得插入元素的随机顺序。将此列表称为a
  • 从空列表开始
    b
  • 对于
    a
    中的每个元素
    e
    • 尝试次数设置为零
    • 尝试时
      <
      最大尝试次数
      • 0
        b.size()
        ,选择一个随机位置
        p
        ,第一个元素前为0,最后一个元素后为
        b.size()
        ,并检查是否可以在此位置插入
        e
        ,而不会导致重复。如果可能,将
        e
        插入
        b
        位置
        p
        ,否则增加
        尝试次数
        ,然后重试
    • 如果在
      max\u尝试中未插入任何元素,请从头开始
我不能证明这会产生一个均匀的分布,但我认为它不会有任何偏差,这些偏差会将某些元素聚集在序列的开始或结束处,在这些地方,使用序列方法的可能性会变得更加确定。它可能会失败(例如,如果为要插入的第一个和第二个元素选择了相同的元素),但这是便宜的,而
b
很短,并且越长,失败的可能性就越小(假设频率分布类似于您向我们展示的频率分布)。OTOH,你可以很容易地得出一个病理分布,这将导致它失败(例如,10000 As和10000 Bs,没有其他字母)


这可以在C++中使用线性时间,使用列表列表>代码> b>代码>,以及一个迭代器数组,引用列表中的每个元素。添加新元素时,在数组末尾添加指向该元素的迭代器。要在列表中选择一个随机位置,请从数组中随机选择一个迭代器。

您应该澄清“重复元素”的含义。从你的老问题看来,你不想要相同的连续元素。@Jarod42是的,不重复意味着两个连续元素不能相同。ABABAB正常-AABCDE不正常。是否有必要使符合标准的每个可能序列具有相同的生成概率?看起来答案是肯定的,但你没有明确地说。@samgak我不是100%肯定这个问题。我想你是在问,任何潜在的解决方案都应该同样有可能发生——如果是的话,答案是肯定的。是的,这就是我要问的。谢谢你的澄清,谢谢。这是一个更加深思熟虑和完整的版本,我正在考虑(尝试随机放置剩余元素)。我使用的序列的主要问题是试图保持分布的一致性,而不是在序列的尾部聚集最常见的元素。我会在C++中尝试这个-谢谢。