有约束的分配:如何有效地产生可能性?

时间:2018-07-17 18:19:45

标签: python itertools

我有一个成本矩阵,将N0个工人链接到N1个任务。如果满足约束,则所有分配都是可行的:(1)每个任务至少分配一个工作人员;(2)可以将最后一个工作人员分配给任意数量的任务;(3)可以分配最后一个任务给任意数量的工人。

我想生成所有满足此约束的配置。我发现这样做的效率很低。任何指导表示赞赏。

编辑:

例如,成本矩阵可以是

costs = np.random.random((3,4))

然后,我需要找到满足约束条件的所有可能配置。一个可能是(可以将最后一个工作人员分配给多个任务)

config = [(0,0),(1,1),(2,2),(2,3)]

另一个是(最后一个任务分配给任意数量的工人)

config = [(0,3),(1,3),(2,3),(2,3),(2,0),(2,1),(2,2)]

所以我需要的是所有可能的元组列表,这些行将行链接到列,这些列表满足(1)每行链接到至少一列,(2)最后一行可以链接到任意数量的列,以及(3)最后一列可以链接到任意数量的行

编辑#2: 我相信这是一个合适的生成器。考虑成本矩阵具有无限的值,应将其忽略。那么所有允许的链接的集合是

n0,n1 = costs.shape
links = []
for i in range(n0):
    for j in range(n1):
        if not np.isinf(costs[i,j]): 
            links.append((i,j))

def filterfn(config):
    # (1) each row but the last should be represented in the config 
    cond1 = set(l[0] for l in config if l[0]!=n0-1) == set(range(n0-1))
    # (2) each column but the last should be represented in the config 
    cond2 = set(l[1] for l in config if l[1]!=n1-1) == set(range(n1-1))
    # (3) each row but the last should be represented exactly once 
    cond3 = len(set(l[0] for l in config if l[0]!=n0-1))==len([l[0] for l in config if l[0]!=n0-1])
    # (4) each column but the last should be represented exactly once
    cond4 = len(set(l[1] for l in config if l[1]!=n1-1))==len([l[1] for l in config if l[1]!=n1-1])

    return cond1 and cond2 and cond3 and cond4 

configs = []  
for r in range(max(s0,s1),s0+s1):
    r_configs  = itertools.combinations(links,r)
    r_configs = filter(lambda config: filterfn(config), r_configs)
    configs.extend(list(r_configs))

0 个答案:

没有答案