我有一个成本矩阵,将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))