生成带约束的列表

时间:2013-03-28 18:33:41

标签: python list

我需要生成一个长度为n的列表:

  1. 包含域[-1,0,1]
  2. 中的元素
  3. 具有k个非零元素
  4. 据我所知,我的元素将是[-1,0,1]的交叉积的一个子集,其中有很多次,然而只是使用iterables包生成交叉产品,然后删除"错误& #34;对于n大于10的人来说,及时是不可能的。

    我想知道是否有可行的办法?

    N.B。对于上下文,问题是使用搜索算法生成循环称重矩阵。从概念上对问题的任何洞察也是值得赞赏的。

3 个答案:

答案 0 :(得分:1)

问题在于查找具有n-k零和k非零的列表,然后将非零值专门化为-1和1。

您可以使用索引组合轻松完成此操作:

def gen_lists(n, k):
    for nzinds in itertools.combinations(range(n), n-k):
        l = [0] * n
        for nz in itertools.product([-1,1], repeat=n-k):
            for i,v in zip(nzinds, nz):
                l[i] = v
            yield l

示例输出:

>>> for l in gen_lists(3, 1):
...     print l
... 
[-1, -1, 0]
[-1, 1, 0]
[1, -1, 0]
[1, 1, 0]
[-1, 0, -1]
[-1, 0, 1]
[1, 0, -1]
[1, 0, 1]
[0, -1, -1]
[0, -1, 1]
[0, 1, -1]
[0, 1, 1]

答案 1 :(得分:0)

而不是试图制作一个大清单并删除一些东西,你可以尝试从底部构建它。使k非零元素。制作n-k 0个元素。把它们放在一起,然后洗混合物:

import random
k = 5
n = 10
non_zero = k * [1,-1]
random.shuffle(non_zero)
z = (n-k)*[0]
result = non_zero[0:k] + z
random.shuffle(result) # [0, 1, -1, 0, 1, 0, 1, -1, 0, 0]

答案 2 :(得分:0)

如何:生成一个包含所需数量-1,0和1的有序列表,并迭代该排序的所有排列。像这样:

import itertools

def generateLists(n, k):
    numberOfZeroes = n - k
    for numberOfOnes in range(0, k+1):
        numberOfNegativeOnes = k - numberOfOnes
        orderedList = [-1] * numberOfNegativeOnes + [0] * numberOfZeroes + [1] * numberOfOnes
        for possibleOrderings in itertools.permutations(orderedList):
            yield possibleOrderings

for i in generateLists(3, 2):
    print i

输出:

(-1, -1, 0)
(-1, 0, -1)
(-1, -1, 0)
(-1, 0, -1)
(0, -1, -1)
(0, -1, -1)
(-1, 0, 1)
(-1, 1, 0)
(0, -1, 1)
(0, 1, -1)
(1, -1, 0)
(1, 0, -1)
(0, 1, 1)
(0, 1, 1)
(1, 0, 1)
(1, 1, 0)
(1, 0, 1)
(1, 1, 0)