【问题标题】:permutations with restrictions on python对python有限制的排列
【发布时间】:2020-07-03 18:55:07
【问题描述】:

我想使用数字 0 到 9 创建所有可能的 10 位数字序列。每个数字只能使用一次,例如:

5 2 8 7 3 0 6 1 9 45 0 6 2 7 8 3 1 9 4

所以有 P(10,10) = 3 628 800 种可能的组合。然而,关于元素的排序有三个规则:

2 > 8 > 3 > 9 > 4(规则 1)和 5 > 9 > 4(规则 2)和 2 > 8 > 1(规则 3)。这里> 符号意味着左操作数应该在一个更高的有效数字上(意味着更靠近左边)。规则中未指定的数字 0 6 7 可以在组合中的任何位置使用。

所以我有这样的想法,即拥有所有可能组合的列表,然后逐个应用规则并丢弃不遵循的序列。但是,经过一番思考,发现我可以进一步评估某些数字的精确位置,比如说2。查看2,8,3,9,4(规则1),2右侧应该至少有4个元素-->(8,3,9,4)。这使得2 可以分配给数字D(1,2,3,4,5,6)(1 是 MSB,10 是 LSB)。进一步调查2,8,1(规则3)1 也应该在2 的右侧,这使得2 可以分配给D(1,2,3,4,5)。我没有想出进一步的简化,我猜就是这样。

那么什么样的方法可能在这里起作用?我不知道我建议的蛮力方法是否可行但必须检查它,但我正在寻找一种更简洁的pythonic方法来实现它。

附:一个想法是我们可以拆分规则,例如

(2>8),(2>3),(2>9),(2>4)

(8>3),(8>9),(8>4)

(3>9),(3>4)

(9>4) 用于规则 1。但在我看来,它仍然是一种蛮力。

【问题讨论】:

  • 有没有规定第一个数字不能是0?
  • 绝对不是。因为它们不是数字而是整数。
  • 好的,那么提供的答案有效(如果您对它们不满意,请告诉我们)。

标签: python loops permutation


【解决方案1】:

很简单,你可以使用itertools.permutations(),当它生成元组时,我们检查每个元组是否符合规则:

from itertools import permutations

for t in permutations(range(10), 10):
    if t.index(2) < t.index(8) < t.index(3) < t.index(9) < t.index(4) and t.index(5) < t.index(9) < t.index(4) and t.index(2) < t.index(8) < t.index(1):
        print(t)

【讨论】:

  • permutations(range(10),10)生成然后循环通过,还是随着循环的进行生成?
  • 随着循环的进行生成。
  • 这行得通,在发现将 3.6 m 元素保存到列表中只需要几秒钟后,我感到很震惊。
【解决方案2】:

对于蛮力方法&对于规则1和规则2,你可以这样做:

import itertools
allpermutations = list(itertools.permutations([x for x in range(10)]))

def rule1(seq):
    return seq.index(2) < seq.index(8) and seq.index(8) < seq.index(3) and seq.index(3) < seq.index(9) and seq.index(9) < seq.index(4)

def rule2(seq):
    return seq.index(5) < seq.index(9) and seq.index(9) < seq.index(4)

result = [eachsequence for eachsequence in allpermutations if rule1(eachsequence) and rule2(eachsequence)]

(同样适用于规则 3。)

对于itertools 的用法,请参阅this,对于.index() 方法,请参阅this

【讨论】:

  • 这效率不高。当不需要很大一部分时,它将所有可能的排列写入内存。
猜你喜欢
  • 2021-11-22
  • 1970-01-01
  • 2018-04-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多