我有一个列表是
test = [10,20,30,40,50,60,70,80,90,100]
我希望找到分割总和彼此接近的分割数= 3所有可能的组合,并选择总和差异最小的分割。
答案 0 :(得分:0)
第一个脚本使用双for
循环将输入列表拆分为所有可能的列表三元组。对于每个三元组,它计算三元组中每个列表的总和,然后创建一个名为diffs
的排序列表,其中包含这些总和的绝对差异。它将由diffs
后跟三元组组成的元组保存到名为all_splits
的列表中。最后,它排序all_splits
,因为all_splits
中的每个项目都以diffs
开头,所保存的元组按其diffs
从最低到最高的顺序排序。
def split_list_test(lst):
all_splits = []
for i in range(1, len(lst) - 1):
for j in range(i + 1, len(lst)):
splits = [lst[:i], lst[i:j], lst[j:]]
a, b, c = map(sum, splits)
diffs = sorted((abs(c-a), abs(c-b), abs(b-a)), reverse=True)
all_splits.append((diffs, splits))
all_splits.sort()
return all_splits
test = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
for row in split_list_test(test):
print(row)
<强>输出强>
([60, 40, 20], [[10, 20, 30, 40, 50], [60, 70, 80], [90, 100]])
([60, 40, 20], [[10, 20, 30, 40, 50, 60], [70, 80], [90, 100]])
([140, 110, 30], [[10, 20, 30, 40, 50, 60], [70, 80, 90], [100]])
([140, 120, 20], [[10, 20, 30, 40, 50], [60, 70], [80, 90, 100]])
([160, 90, 70], [[10, 20, 30, 40], [50, 60, 70, 80], [90, 100]])
([170, 90, 80], [[10, 20, 30, 40], [50, 60, 70], [80, 90, 100]])
([180, 110, 70], [[10, 20, 30, 40, 50, 60, 70], [80, 90], [100]])
([200, 110, 90], [[10, 20, 30, 40, 50, 60, 70], [80], [90, 100]])
([200, 140, 60], [[10, 20, 30, 40, 50, 60], [70], [80, 90, 100]])
([200, 150, 50], [[10, 20, 30, 40, 50], [60, 70, 80, 90], [100]])
([210, 160, 50], [[10, 20, 30], [40, 50, 60, 70], [80, 90, 100]])
([240, 130, 110], [[10, 20, 30], [40, 50, 60, 70, 80], [90, 100]])
([240, 220, 20], [[10, 20], [30, 40, 50, 60, 70], [80, 90, 100]])
([240, 230, 10], [[10, 20, 30, 40], [50, 60], [70, 80, 90, 100]])
([250, 250, 0], [[10, 20, 30, 40], [50, 60, 70, 80, 90], [100]])
([260, 260, 0], [[10], [20, 30, 40, 50, 60, 70], [80, 90, 100]])
([270, 260, 10], [[10, 20, 30, 40, 50, 60, 70, 80], [90], [100]])
([280, 190, 90], [[10, 20, 30], [40, 50, 60], [70, 80, 90, 100]])
([280, 190, 90], [[10, 20, 30, 40, 50], [60], [70, 80, 90, 100]])
([300, 160, 140], [[10, 20], [30, 40, 50, 60, 70, 80], [90, 100]])
([310, 160, 150], [[10, 20], [30, 40, 50, 60], [70, 80, 90, 100]])
([330, 190, 140], [[10], [20, 30, 40, 50, 60], [70, 80, 90, 100]])
([330, 290, 40], [[10, 20, 30], [40, 50, 60, 70, 80, 90], [100]])
([340, 180, 160], [[10], [20, 30, 40, 50, 60, 70, 80], [90, 100]])
([340, 310, 30], [[10, 20, 30], [40, 50], [60, 70, 80, 90, 100]])
([350, 300, 50], [[10, 20, 30, 40], [50], [60, 70, 80, 90, 100]])
([370, 280, 90], [[10, 20], [30, 40, 50], [60, 70, 80, 90, 100]])
([390, 260, 130], [[10], [20, 30, 40, 50], [60, 70, 80, 90, 100]])
([390, 320, 70], [[10, 20], [30, 40, 50, 60, 70, 80, 90], [100]])
([410, 390, 20], [[10, 20, 30], [40], [50, 60, 70, 80, 90, 100]])
([420, 380, 40], [[10, 20], [30, 40], [50, 60, 70, 80, 90, 100]])
([430, 340, 90], [[10], [20, 30, 40, 50, 60, 70, 80, 90], [100]])
([440, 360, 80], [[10], [20, 30, 40], [50, 60, 70, 80, 90, 100]])
([460, 460, 0], [[10, 20], [30], [40, 50, 60, 70, 80, 90, 100]])
([480, 440, 40], [[10], [20, 30], [40, 50, 60, 70, 80, 90, 100]])
([510, 500, 10], [[10], [20], [30, 40, 50, 60, 70, 80, 90, 100]])
下一个脚本更紧凑,它只返回一个解决方案。它使用不同的规则来决定最小分割。如果(a, b, c)
是三元组中列表的总和,从最低到最高排序,则这些总和的绝对差异为c-a
,c-b
和b-a
。差异的总和为c-a + c-b + b-a
,等于2*(c-a)
,因此我们可以通过查找具有最小值c-a
的分割来找到最小分割(使用此规则)。 / p>
def keyfunc(seq):
sums = sorted(sum(u) for u in seq)
return sums[2] - sums[0]
def split_list(lst):
gen = ([lst[:i], lst[i:j], lst[j:]]
for i in range(1, len(lst) - 1)
for j in range(i + 1, len(lst)))
return min(gen, key=keyfunc)
test = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
print(split_list(test))
<强>输出强>
[[10, 20, 30, 40, 50], [60, 70, 80], [90, 100]]
如您所见,对于此test
列表,此版本提供与上述最小解决方案相同的解决方案。