4

我想解决以下类型的最小集覆盖问题。所有列表仅包含 1 和 0。

我说如果您可以通过准确插入符号 来制作列表,则列表A涵盖了列表。BBAx

考虑所有 2^n 个长度为 1 和 0 的列表n和 set x = n/32n/3我会计算一组涵盖所有内容 的最小长度列表。

这是我开始的一种天真的方法。对于每个可能的长度列表,2n/3我创建了一组可以使用此函数(由 DSM 编写)从中创建的所有列表。

from itertools import product, combinations

def all_fill(source, num):
    output_len = len(source) + num
    for where in combinations(range(output_len), len(source)):
        # start with every possibility
        poss = [[0,1]] * output_len
        # impose the source list
        for w, s in zip(where, source):
            poss[w] = [s]
        # yield every remaining possibility
        for tup in product(*poss):
            yield tup

n = 6然后,我使用以下示例创建集合集。

n = 6
shortn = 2*n/3
x = n/3
coversets=set()
for seq in product([0,1], repeat = shortn):
    coversets.add(frozenset(all_fill(seq,x)))

我想从联合为allset = set(product([0,1], repeat=n)).

在这种情况下,set(all_fill([1,1,1,1],2)), set(all_fill([0,0,0,0],2)), set(all_fill([1,1,0,0],2)), set(all_fill([0,0,1,1],2))会做。

我的目标是解决问题n = 12。如果有帮助的话,我很乐意使用外部库,我希望在n最坏的情况下时间会成倍增长。

4

1 回答 1

3

我编写了一个小程序来编写一个整数程序,由 CPLEX 或其他 MIP 求解器求解。下面是 n=12 的解。


from collections import defaultdict
from itertools import product, combinations

def all_fill(source, num):
    output_len = (len(source) + num)
    for where in combinations(range(output_len), len(source)):
        poss = ([[0, 1]] * output_len)
        for (w, s) in zip(where, source):
            poss[w] = [s]
        for tup in product(*poss):
            (yield tup)

def variable_name(seq):
    return ('x' + ''.join((str(s) for s in seq)))
n = 12
shortn = ((2 * n) // 3)
x = (n // 3)
all_seqs = list(product([0, 1], repeat=shortn))
hit_sets = defaultdict(set)
for seq in all_seqs:
    for fill in all_fill(seq, x):
        hit_sets[fill].add(seq)
print('Minimize')
print(' + '.join((variable_name(seq) for seq in all_seqs)))
print('Subject To')
for (fill, seqs) in hit_sets.items():
    print(' + '.join((variable_name(seq) for seq in seqs)), '>=', 1)
print('Binary')
for seq in all_seqs:
    print(variable_name(seq))
print('End')

MIP - Integer optimal solution:  Objective =  1.0000000000e+01
Solution time =    7.66 sec.  Iterations = 47411  Nodes = 337

CPLEX> Incumbent solution
Variable Name           Solution Value
x00000000                     1.000000
x00000111                     1.000000
x00011110                     1.000000
x00111011                     1.000000
x10110001                     1.000000
x11000100                     1.000000
x11001110                     1.000000
x11100001                     1.000000
x11111000                     1.000000
x11111111                     1.000000
All other variables matching '*' are 0.
CPLEX> 
于 2013-09-25T21:15:52.273 回答