我目前通过使用一种贪婪算法,通过从最大集到最小集迭代集来实现这一点。如果我更关心找到最佳解决方案而不是效率,那么选择什么样的算法呢?
详细说明:
1)每组具有预定范围
2)我的目标是最终得到大量密集的集合,而不是减少集合的总数。
示例:假设范围为8
。
这些集可能是:[1,5,7]
,[2,6]
,[3,4,5]
,[1,2]
,[4]
,[1]
一个好的结果是[1,5,7,2,6,4]
,[3,4,5,1,2]
,[1]
答案 0 :(得分:1)
这是一个非常复杂的问题。很可能使用更复杂的图形算法,这可以用比我想象的更有效的方式解决,但这就是我所拥有的。生成所有解决方案的速度相当慢,但由于它是一个生成器,因此根据具体情况,从第一个 n 中选择解决方案可能是一个选项。
它没有解决哪个解决方案最好的问题,它只是生成所有可能的解决方案。此外,您没有明确说明“最佳”密集包装是什么。在原始示例中(没有[4]
),解决方案12567-12345-1
是否优于123456-157-12
?如果是这样,为什么?说到长度,解决方案1将是(5,5,1),而解决方案2将是(6,2,3)。哪个更好?
input = map(set, [ [1,5,7], [2,6], [3,4,5], [1,2], [4], [1] ])
def eachCombination(input):
if input:
for combination, rest in eachCombination(input[1:]):
yield combination, input[0:1] + rest
if not (input[0] & combination): # fits?
yield input[0] | combination, rest
else:
yield set(), []
def eachPacked(input):
for combination, rest in eachCombination(input):
for restPart in rest:
if not (combination & restPart): # not densely packed?
break
else:
yield combination, rest
def eachSolution(input):
for packed, rest in eachPacked(input):
if rest:
for subsolution in eachSolution(rest):
yield [ packed ] + subsolution
else:
yield [ packed ]
for solution in eachSolution(input):
print ' '.join('-'.join('%d' % n for n in set) for set in solution)
这将打印
1-2-3-4-5 1-2-4-5-6-7 1
1-2-3-4-5 1-2-4-6 1-5-7
1-2-4-5-6-7 1-2-3-4-5 1
1-2-4-5-6-7 1-3-4-5 1-2
1-2-4 1-2-5-6-7 1-3-4-5
1-2-4 1-2-3-4-5-6 1-5-7
1-2-3-4-5-6 1-4-5-7 1-2
1-2-3-4-5-6 1-2-4 1-5-7
1-2-4-6 1-5-7 1-2-3-4-5
1-2-4-6 1-2-3-4-5 1-5-7
答案 1 :(得分:1)
这是一个近似值,使用动态编程:
from operator import itemgetter
def find_maximum_set(sets):
results = []
for si,s in enumerate(sets):
sn = len(s)
new_set = set(s) # if nothing else works, add the set by itself
new_len = sn
new_is = [si]
# try to combine it with all the previous results, picking the one that
# would produce the largest union
for rn,ris,r in results:
if r.isdisjoint(s):
rs = r.union(s)
if rn+sn > new_len:
new_set = rs
new_len = rn+sn
new_is = ris + [si]
# add the new set to the result collection
results.append((new_len,new_is,new_set))
# return the largest result
return max(results, key=itemgetter(0))
def find_all_maximum_sets(sets):
sets = list(sets)
result = []
while len(sets) > 0:
_, indexes, largest = find_maximum_set(sets)
result.append(largest)
sets = [s for i,s in enumerate(sets) if i not in indexes]
return result
示例:强>
>>> find_all_maximum_sets([[1,5,7], [2,6], [3,4,5], [1,2] , [4], [1]])
[set([1, 2, 4, 5, 6, 7]), set([1, 2, 3, 4, 5]), set([1])]
答案 2 :(得分:0)
我不确定它是否会提供最佳解决方案,但只是反复合并两个最大的非重叠集合不起作用?