【发布时间】:2023-11-16 02:49:01
【问题描述】:
我有一组 N 个项目,我想将它们分成 K 个大小为 n1、n2、...、nk(其中 n1 + n2 + ... + nk = N)
我还限制了哪些项目可以属于哪个子集。
对于我的问题,至少存在一种解决方案。
我希望在 Python 中实现一种算法来生成(至少)一个解决方案。
示例:
可能性:
| Item\Subset | 0 | 1 | 2 |
|---|---|---|---|
| A | True | True | False |
| B | True | True | True |
| C | False | False | True |
| D | True | True | True |
| E | True | False | False |
| F | True | True | True |
| G | False | False | True |
| H | True | True | True |
| I | True | True | False |
尺寸限制:(3, 3, 3)
可能的解决方案:[0, 0, 2, 1, 0, 1, 2, 2, 1]
实施:
到目前为止,我已经成功地尝试了暴力破解,但我现在想找到一个更优化的算法。
我在考虑回溯,但我不确定这是正确的方法,也不确定我的实现是否正确:
import pandas as pd
import numpy as np
import string
def solve(possibilities, constraints_sizes):
solution = [None] * len(possibilities)
def extend_solution(position):
possible_subsets = [index for index, value in possibilities.iloc[position].iteritems() if value]
for subset in possible_subsets:
solution[position] = subset
unique, counts = np.unique([a for a in solution if a is not None], return_counts=True)
if all(length <= constraints_sizes[sub] for sub, length in zip(unique, counts)):
if position >= len(possibilities)-1 or extend_solution(position+1):
return solution
return None
return extend_solution(0)
if __name__ == '__main__':
constraints_sizes = [5, 5, 6]
possibilities = pd.DataFrame([[False, True, False],
[True, True, True],
[True, True, True],
[True, True, True],
[True, False, False],
[True, True, True],
[True, True, True],
[True, True, True],
[True, False, False],
[True, True, True],
[True, True, True],
[True, True, True],
[False, True, True],
[True, True, True],
[True, True, True],
[True, False, False]],
index=list(string.ascii_lowercase[:16]))
solution = solve(possibilities, constraints_sizes)
一种可能的预期解决方案:[1, 0, 0, 1, 0, 1, 1, 1, 0, 2, 2, 2, 2, 2, 2, 0]
很遗憾,此代码无法找到解决方案(尽管它适用于前面的示例)。
我错过了什么?
非常感谢。
【问题讨论】:
标签: python algorithm partitioning backtracking recursive-backtracking