【问题标题】:Pythonic way to get all the unique factorial combination of 3d matrix获取 3d 矩阵的所有独特阶乘组合的 Pythonic 方法
【发布时间】:2017-03-04 17:09:52
【问题描述】:

所以我有 2 个列表,一个看起来像:

drivers = ['bob','Lenny','frank','sunny']

另一个看起来像:

cities = ['Austin','San Antonio','Houston']

这可以很容易地用如下表格表示:

            |  bob  | lenny | frank | sunny
Austin      |  $45  |  $15  |  $77  |  $33
San Antonio |  $12  |  $23  |  $10  |  $18
Houston     |  $44  |  $99  |  $78  |  $12

所以我想计算所有 VALID 组合,这意味着我可以在时间表之外离开一个驱动器,但我不能将一个司机同时安排在 2 个城市,而且我不能在没有司机的情况下离开一个城市。

有什么想法吗?

【问题讨论】:

  • 你能假设cities中的所有元素都是唯一的吗?

标签: python numpy math combinations itertools


【解决方案1】:

如果您可以假设cities 中的所有城市都是唯一的,您可以简单地生成长度为len(cities) 的所有itertools.permutations,并(可选)将它们与城市一起压缩,例如:

def valid_combinations(cities,drivers):
    return itertools.permutations(drivers,len(cities))

或者,如果您想将它们与城市一起压缩:

def valid_combinations(cities,drivers):
    for perm in itertools.permutations(drivers,len(cities)):
        yield zip(cities,perm)

对于我们生成的最后一个:

>>> list(map(tuple,valid_combinations(cities,drivers)))
[(('Austin', 'bob'), ('San Antonio', 'Lenny'), ('Houston', 'frank')),
(('Austin', 'bob'), ('San Antonio', 'Lenny'), ('Houston', 'sunny')),
(('Austin', 'bob'), ('San Antonio', 'frank'), ('Houston', 'Lenny')),
(('Austin', 'bob'), ('San Antonio', 'frank'), ('Houston', 'sunny')),
(('Austin', 'bob'), ('San Antonio', 'sunny'), ('Houston', 'Lenny')),
(('Austin', 'bob'), ('San Antonio', 'sunny'), ('Houston', 'frank')),
(('Austin', 'Lenny'), ('San Antonio', 'bob'), ('Houston', 'frank')),
(('Austin', 'Lenny'), ('San Antonio', 'bob'), ('Houston', 'sunny')),
(('Austin', 'Lenny'), ('San Antonio', 'frank'), ('Houston', 'bob')),
(('Austin', 'Lenny'), ('San Antonio', 'frank'), ('Houston', 'sunny')),
(('Austin', 'Lenny'), ('San Antonio', 'sunny'), ('Houston', 'bob')),
(('Austin', 'Lenny'), ('San Antonio', 'sunny'), ('Houston', 'frank')),
(('Austin', 'frank'), ('San Antonio', 'bob'), ('Houston', 'Lenny')),
(('Austin', 'frank'), ('San Antonio', 'bob'), ('Houston', 'sunny')),
(('Austin', 'frank'), ('San Antonio', 'Lenny'), ('Houston', 'bob')),
(('Austin', 'frank'), ('San Antonio', 'Lenny'), ('Houston', 'sunny')),
(('Austin', 'frank'), ('San Antonio', 'sunny'), ('Houston', 'bob')),
(('Austin', 'frank'), ('San Antonio', 'sunny'), ('Houston', 'Lenny')),
(('Austin', 'sunny'), ('San Antonio', 'bob'), ('Houston', 'Lenny')),
(('Austin', 'sunny'), ('San Antonio', 'bob'), ('Houston', 'frank')),
(('Austin', 'sunny'), ('San Antonio', 'Lenny'), ('Houston', 'bob')),
(('Austin', 'sunny'), ('San Antonio', 'Lenny'), ('Houston', 'frank')),
(('Austin', 'sunny'), ('San Antonio', 'frank'), ('Houston', 'bob')),
(('Austin', 'sunny'), ('San Antonio', 'frank'), ('Houston', 'Lenny'))]

所以在第一种情况下,'bob' 驱动到 'Austin''Lenny''San Antonio''frank''Houston';在第二种情况下,'bob' 驱动到 'Austin''Lenny''San Antonio''sunny''Houston';等等。此处有效配置的总数 2×3×4=24 这也是 yielded 的元素数。

但是,如果您想找到最佳组合 - 您的问题还不清楚 - 您可以使用 匈牙利算法 的变体在 O(n3).

【讨论】:

  • 既然 OP 说他可以从日程表中排除司机,但不能同时将两个司机放在同一个城市,难道没有更多的有效组合可以忽略一个或多个司机吗?我不确定我的理解是否正确,所以我希望能得到澄清。
  • @batbrat:好吧,因为每个时间表中有三个城市和四个司机,所以排除了一个司机。例如'sunny' 不会在第一个计划中开车。
  • 啊!我错过了明显的!感谢您清除它。如果我们可以在一个城市有两个司机,那可以包括在内,对吧?我意识到这与 OP 的问题有所不同:我只是觉得自己很好奇。
  • 确实,我正在寻找最佳组合,现在我正在使用的矩阵大约为 15x20,使用这种方法计算需要很长时间,但是,这是正确的回答我最初的问题。
  • @WillemVanOnsem 能否分享一下如何用匈牙利算法解决最优组合问题?这显然不是我的专业领域。非常感谢。
【解决方案2】:

一种使用 Pandas Dataframe 进行分层表示的方式:

与 df :

            bob  lenny  frank  sunny
Austin       45     15     77     33
SanAntonio   12     23     10     18
Houston      44     99     78     12

我们可以做到:

m,n=df.shape
idx=[list(t) for t in itertools.permutations(range(n),m) ]
cash=df.values[range(m),idx]
staff=np.take(df.columns.tolist(),idx)
total=pd.DataFrame(index=staff,data=cash,columns=df.index)
total['amount']=cash.sum(axis=1)
print (total.sort_values('amount',ascending=False))

对于:

                       Austin  SanAntonio  Houston  amount
(frank, sunny, lenny)      77          18       99     194
(frank, bob, lenny)        77          12       99     188
(bob, sunny, lenny)        45          18       99     162
(bob, frank, lenny)        45          10       99     154
(bob, lenny, frank)        45          23       78     146
(frank, lenny, bob)        77          23       44     144
(sunny, bob, lenny)        33          12       99     144
(sunny, frank, lenny)      33          10       99     142
(bob, sunny, frank)        45          18       78     141
(frank, sunny, bob)        77          18       44     139
(sunny, lenny, frank)      33          23       78     134
(sunny, bob, frank)        33          12       78     123
(frank, lenny, sunny)      77          23       12     112
(lenny, sunny, frank)      15          18       78     111
(lenny, bob, frank)        15          12       78     105
(frank, bob, sunny)        77          12       12     101
(sunny, lenny, bob)        33          23       44     100
(sunny, frank, bob)        33          10       44      87
(bob, lenny, sunny)        45          23       12      80
(lenny, sunny, bob)        15          18       44      77
(lenny, frank, bob)        15          10       44      69
(bob, frank, sunny)        45          10       12      67
(lenny, bob, sunny)        15          12       12      39
(lenny, frank, sunny)      15          10       12      37

【讨论】:

  • 我一直在尝试这个,但一直在点击:IndexError: shape mismatch: indexing arrays could not be broadcast together with shapes (3,) (0,)
  • mmmh.... idx 似乎是空的。 df.shape 必须是 (3,4),len(idx) 必须是 24,len(idx[0]) =3。你能检查一下吗?
猜你喜欢
  • 2020-04-02
  • 1970-01-01
  • 2010-11-09
  • 1970-01-01
  • 2020-04-09
  • 1970-01-01
  • 2016-05-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多