【问题标题】:Inverse of random.shuffle()?random.shuffle() 的逆?
【发布时间】:2014-12-22 00:55:45
【问题描述】:

我有一个函数,为简单起见,我将其称为 shuffler,它接受一个列表,随机给出一个种子 17,然后打印该列表 shuffle。

def shuffler( n ):
   import random
   random.seed( 17 )
   print( random.shuffle( n ) )

如果我知道种子,我将如何创建另一个名为 unshuffler 的函数来“解洗”由 shuffler() 返回的列表,将其带回到我输入到 shuffler() 的列表中?

【问题讨论】:

  • 正在使用什么洗牌算法?你需要深入挖掘洗牌的内脏来扭转它。或者保存一个未洗牌的数组副本,还是作弊?
  • 是的,这是作弊。我不知道该怎么做...
  • 我需要能够获取任何我知道其种子的已洗牌列表,然后将其解洗
  • 我想你可以在这里找到答案stackoverflow.com/questions/4557444/…

标签: python python-3.x random


【解决方案1】:

只是想提供一个与 numpy 常用的功能模式更兼容的答案。最终,这个解决方案应该执行得最快,因为它将利用 numpy 的内部优化,这些优化本身可以通过使用像 numba 这样的项目来进一步优化。它应该比在 python 中使用传统的循环结构快很多

import numpy as np

original_data = np.array([23, 44, 55, 19, 500, 201]) # Some random numbers to represent the original data to be shuffled
data_length = original_data.shape[0]

# Here we create an array of shuffled indices
shuf_order = np.arange(data_length)
np.random.shuffle(shuf_order)

shuffled_data = original_data[shuf_order] # Shuffle the original data

# Create an inverse of the shuffled index array (to reverse the shuffling operation, or to "unshuffle")
unshuf_order = np.zeros_like(shuf_order)
unshuf_order[shuf_order] = np.arange(data_length)

unshuffled_data = shuffled_data[unshuf_order] # Unshuffle the shuffled data

print(f"original_data: {original_data}")
print(f"shuffled_data: {shuffled_data}")
print(f"unshuffled_data: {unshuffled_data}")

assert np.all(np.equal(unshuffled_data, original_data))

【讨论】:

    【解决方案2】:

    这里有两个功能可以满足您的需求:

    import random
    import numpy as np
    
    def shuffle_forward(l):
        order = range(len(l)); random.shuffle(order)
        return list(np.array(l)[order]), order
    
    def shuffle_backward(l, order):
        l_out = [0] * len(l)
        for i, j in enumerate(order):
            l_out[j] = l[i]
        return l_out
    

    示例

    l = range(10000); random.shuffle(l)
    l_shuf, order = shuffle_forward(l)
    l_unshuffled  = shuffle_backward(l_shuf, order)
    
    print l == l_unshuffled
    #True
    

    【讨论】:

      【解决方案3】:

      用有问题的种子重新设置随机生成器的种子,然后将列表 1、2、...、n 打乱。这会准确地告诉您随机播放的结果。

      【讨论】:

      • 但是我可以使用一个逆向字符串来做相反的事情吗?
      • 洗牌后的索引告诉你第 n 项在未洗牌列表中的位置。 IE。 Unshuffled[ShuffledIndex[i]] = Shuffled[i]。或者,您可以从该列表中构建一个反向索引,如下所示: InverseIndex[ShuffledIndex[i]] = i.这使您可以将原始项目 i 检索为 Shuffled[InverseIndex[i]]。
      【解决方案4】:

      在 Python3 中:

      import random
      import numpy as np
      
      def shuffle_forward(l):
          order = list(range(len(l)); random.shuffle(order))
          return list(np.array(l)[order]), order
      
      def shuffle_backward(l, order):
          l_out = [0] * len(l)
          for i, j in enumerate(order):
              l_out[j] = l[i]
          return l_out
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-05-11
        • 1970-01-01
        • 2023-04-04
        • 1970-01-01
        • 1970-01-01
        • 2018-01-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多