【问题标题】:python permutations with more randomization具有更多随机化的python排列
【发布时间】:2021-10-18 15:59:54
【问题描述】:

我正在尝试从索引列表中生成排列,目前,我正在使用itertools.permutation。没关系,除了我需要一个真正随机的索引,因为 我将无法选择所有排列,而是整个集合(初始)的一个非常短的子集用于模拟。 p>

对于itertools.permutation排列元组根据输入迭代的顺序以字典顺序发出。因此,如果输入的可迭代对象已排序,则组合元组将按排序顺序生成。

import itertools
for ind, idxs in enumerate(itertools.permutations(range(5))):
  print(ind)
  print(idxs)
  print('--------')
0
(0, 1, 2, 3, 4)
--------
1
(0, 1, 2, 4, 3)
--------
2
(0, 1, 3, 2, 4)
--------
3
(0, 1, 3, 4, 2)
--------
4
(0, 1, 4, 2, 3)
--------
5
(0, 1, 4, 3, 2)
--------
6
(0, 2, 1, 3, 4)
--------
7
(0, 2, 1, 4, 3)
--------
8
(0, 2, 3, 1, 4)
--------
9
(0, 2, 3, 4, 1)
--------
10
(0, 2, 4, 1, 3)
--------
11
(0, 2, 4, 3, 1)
--------
12
(0, 3, 1, 2, 4)
--------
13
(0, 3, 1, 4, 2)
--------

我想到的一个解决方案肯定是每次都打乱列表以获得随机顺序,但这使得排列的想法过时了,这是不希望的,因为有可能生成相同的样本超过一次。排列应该是迭代生成的,所以我不能只做list(itertools.permutation..),因为这会产生一个非常不必要的长列表。

【问题讨论】:

  • 我认为如果不将整个结果保存在内存中,您就无法跟踪随机化。否则,我们最终可能会重复已经生成的排列。我真的很喜欢你的问题,如果你可以在不考虑空间复杂度的情况下做到这一点,那么你实际上已经解决了 P=NP 千年问题。
  • 也许你可以从这里得到一些想法:github.com/markpiffer/pypourri
  • 如果你是随机生成排列,为了避免重复而保留一组已经看到的排列是否有问题?
  • 在蒙特卡洛模拟中,只要您的随机方法为您提供代表性样本,通常您不必担心两次获得相同对象的(小)风险> 所有可能的对象。正如 Sup 所提到的,这种唯一性约束迫使您将整个历史记录保存在内存中并重复搜索,这很昂贵。如果去掉约束,问题很简单,只需random.sample()即可解决。

标签: python python-3.x algorithm random permutation


【解决方案1】:

一种方法是在生成排列之前和/或之后洗牌。

供参考:

import itertools
import random
a = list(range(3))
print("original =",a)
random.shuffle(a)
print("shuffled =",a)
permutations = list(itertools.permutations(a))
print("permutations of shuffled array =",permutations)
random.shuffle(permutations)
print("shuffled permutations of shuffled array =",permutations)
original = [0, 1, 2]
shuffled = [1, 0, 2]
permutations of shuffled array = [(1, 0, 2), (1, 2, 0), (0, 1, 2), (0, 2, 1), (2, 1, 0), (2, 0, 1)]
shuffled permutations of shuffled array = [(0, 1, 2), (2, 0, 1), (2, 1, 0), (1, 0, 2), (1, 2, 0), (0, 2, 1)]

【讨论】:

    【解决方案2】:

    生成随机排列:如果您只使用其中的一小部分 k,则两次相同的机会是 k/n!。

    【讨论】:

      【解决方案3】:

      使用random.sample:

      permutations = list(itertools.permutations(range(5)))
      permutation = random.sample(permutations, k=4)
      
      # run 1
      >>> random.sample(permutations, k=4)
      [(0, 4, 1, 2, 3), (4, 0, 1, 3, 2), (3, 2, 0, 4, 1), (1, 2, 3, 4, 0)]
      
      # run 2
      >>> random.sample(permutations, k=4)
      [(2, 1, 4, 0, 3), (0, 3, 4, 1, 2), (3, 1, 4, 0, 2), (0, 3, 4, 2, 1)]
      
      # run 3
      >>> random.sample(permutations, k=4)
      [(3, 4, 1, 0, 2), (3, 0, 1, 2, 4), (0, 4, 1, 2, 3), (3, 4, 2, 0, 1)]
      
      # and so on
      

      【讨论】:

      • 感谢您的回答,但它首先使用list 创建完整的排列列表,考虑到我只需要初始排列中的一小部分,这不是很不理想吗?
      • 仅用于演示目的...一旦生成列表,请将其保存在变量中。
      猜你喜欢
      • 1970-01-01
      • 2018-04-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-15
      • 2012-06-24
      • 1970-01-01
      相关资源
      最近更新 更多