在先前的问题中:
Generating maximum number of 3-tuples from a list of 2-tuples
我从@AChampion得到了一个答案,如果2元组的数目可被3整除,这似乎是可行的。但是,例如,如果我们有10个2元组,则解决方案将失败。在摸索了一段时间之后,我觉得不可能找到一个完美的解决方案:
(1,2)(1,3),(1,4),(2,3),(2,4),(3,4)
因此,我有兴趣找到一种解决方案,以最大程度地减少剩余元组的数量。在上面的示例中,结果可能是:
(1,2,3) # derived from (1,2), (1,3), (2,3)
(1,4),(2,4),(3,4) # remainder tuples
从3个2元组生成3元组的规则是:
(a,b), (b,c), (c,a) -> (a, b, c)
即2元组是一个长度为3的循环。3元组中元素的顺序并不重要,即:
(a,b,c) == (c,a,b)
我实际上对我们有一个数字n的情况很感兴趣:
for x in range(1,n+1):
for y in range(1,n+1):
if x!=y:
a.append((x,y))
# a = [ (1,2),...,(1,n), (2,1),(2,3),...,(2,n),...(n,1),...,(n,n-1) ]
从a中,最小化生成3元组时剩余的2元组的数量。每个2元组只能使用一次。
我花了好几个小时来解决这个问题,但是对于一般情况,我似乎无法想出一个优雅的解决方案(嗯,我也没有找到一个丑陋的解决方案:-)。有什么想法吗?
答案 0 :(得分:1)
为此,您需要创建用于替换的组合数量。然后遍历您的数据以获取包含以上任意组合的3个项目并替换它们。 我已经完成了好几个步骤。
from itertools import combinations
# create replacements elements
number_combinations_raw = list(combinations(range(1, 5), 3))
# create proper number combinations
number_combinations = []
for item in number_combinations_raw:
if (item[0] + 1 == item[1]) and (item[1] + 1 == item[2]):
number_combinations.append(item)
# create test data
data = [(1, 2), (1, 3), (1, 4), (2, 3), (2, 4)]
# reduce data
reduce_data = []
for number_set in number_combinations:
count = 0
merged_data = []
for item in data:
if (number_set[0] in item and number_set[1] in item) or (number_set[1] in item and number_set[2] in item) \
or (number_set[0] in item and number_set[2] in item):
merged_data.append(item)
count += 1
if count == 3:
reduce_data.append((number_set, merged_data))
# delete merged elements from data list and add replacement
for item in data:
for reduce_item in reduce_data:
for element in reduce_item[1]:
if element in data:
data.remove(element)
data = [reduce_item[0]] + data
# remove duplicated replaced elements
final_list = list(dict.fromkeys(data))
输出:
[(1, 2, 3), (1, 4), (2, 4)]