创建资源组合

时间:2014-10-07 17:55:02

标签: python itertools

我们有一些离职可以分配给不同的抵达者,就像这样:

Dep1.arrivals = [A1, A2]
Dep2.arrivals = [A2, A3, A4]
Dep3.arrivals = [A3, A5]

此功能的输出应该是一个包含所有可能的到达组合的列表:

输出:[[A1, A2, A3], [A1, A2, A5], [A1, A3, A5], [A1, A4, A5], ...]

请注意,[A1, A3, A3]并未包含在列表中,因为您无法使用到达两次。另请注意,[A1, A2, A3][A3, A1, A2][A3, A2, A1]的元素相同。

编辑:

在这种情况下,许多解决方案都适用,但不是一般解决方案,例如,如果3套或到达时相同:

Dep1.arrivals = [A1, A2, A3]
Dep2.arrivals = [A1, A2, A3]
Dep3.arrivals = [A1, A2, A3]

然后它返回:

('A1', 'A2', 'A3')
('A1', 'A3', 'A2')
('A2', 'A1', 'A3')
('A2', 'A3', 'A1')
('A3', 'A1', 'A2')
('A3', 'A2', 'A1')

这是错误的,因为('A1', 'A2', 'A3')('A3', 'A2', 'A1')是相同的解决方案。

无论如何,谢谢!

3 个答案:

答案 0 :(得分:0)

您可以使用product生成所有可能的离开组合,然后在事实之后过滤掉包含重复项的组合:

import itertools

arrivals = [
    ["A1", "A2"],
    ["A2", "A3", "A4"],
    ["A3", "A5"]
]

for items in itertools.product(*arrivals):
    if len(set(items)) < len(arrivals): continue
    print items

结果:

('A1', 'A2', 'A3')
('A1', 'A2', 'A5')
('A1', 'A3', 'A5')
('A1', 'A4', 'A3')
('A1', 'A4', 'A5')
('A2', 'A3', 'A5')
('A2', 'A4', 'A3')
('A2', 'A4', 'A5')

答案 1 :(得分:0)

您可以使用list comprehension itertools.product

来执行此操作
>>> import itertools
>>> lol = [["A1", "A2"], ["A2", "A3", "A4"], ["A3", "A5"]]
>>> print [x for x in itertools.product(*lol) if len(set(x)) == len(lol)]

结果

[('A1', 'A2', 'A3'),
 ('A1', 'A2', 'A5'),
 ('A1', 'A3', 'A5'),
 ('A1', 'A4', 'A3'),
 ('A1', 'A4', 'A5'),
 ('A2', 'A3', 'A5'),
 ('A2', 'A4', 'A3'),
 ('A2', 'A4', 'A5')]

请注意,这在概念上等同于@Kevin给出的代码。

编辑 :正如OP在其编辑中提到的那样,当组合顺序不同时,此解决方案不起作用。

要解决此问题,可以将最后一个语句更改为以下内容,我们首先获取已到达的已排序元组列表,然后将列表转换为一组,如下所示:

>>> lol = [["A1", "A2", "A3"], ["A1", "A2", "A3"], ["A1", "A2", "A3"]]
>>> set([tuple(sorted(x)) for x in itertools.product(*lol) if len(set(x)) == len(lol)])
{('A1', 'A2', 'A3')}

>>> lol = [["A1", "A2"], ["A2", "A3", "A4"], ["A3", "A5"]]
>>> set([tuple(sorted(x)) for x in itertools.product(*lol) if len(set(x)) == len(lol)])
{('A1', 'A2', 'A3'),
 ('A1', 'A2', 'A5'),
 ('A1', 'A3', 'A4'),
 ('A1', 'A3', 'A5'),
 ('A1', 'A4', 'A5'),
 ('A2', 'A3', 'A4'),
 ('A2', 'A3', 'A5'),
 ('A2', 'A4', 'A5')}

答案 2 :(得分:-1)

问题标有itertools,但我怀疑您没有看itertools.combinations

arrivals = ['A1', 'A2', 'A3', 'A4']
[a for a in itertools.combinations(arrivals, 3)]
#[('A1', 'A2', 'A3'),
#('A1', 'A2', 'A4'),
# ('A1', 'A3', 'A4'),
#('A2', 'A3', 'A4')]