简体   繁体   English

从一组2元组生成3元组

[英]Generating 3-tuples from a set of 2-tuples

In an earlier question: 在先前的问题中:

Generating maximum number of 3-tuples from a list of 2-tuples 从2元组列表中生成3元组的最大数量

I got an answer from @AChampion that seems to work if the number of 2-tuples is divisible by 3. However, the solution fails if we, for example, have 10 2-tuples. 我从@AChampion得到了一个答案,如果2元组的数目可被3整除,这似乎有效。但是,例如,如果我们有10个2元组,则解决方案将失败。 After fumbling with it for a while I'm under the impression that it is impossible to find a perfect solution for say: 在摸索了一段时间之后,我觉得不可能找到一个完美的解决方案:

(1,2)(1,3),(1,4),(2,3),(2,4),(3,4)

So I'm interested in finding one solution that minimizes the number of remainder tuples. 因此,我对寻找一种最小化剩余元组数量的解决方案感兴趣。 In the example above the result could be: 在上面的示例中,结果可能是:

(1,2,3)           # derived from (1,2), (1,3), (2,3)
(1,4),(2,4),(3,4) # remainder tuples 

The rule for generating 3-tuple from 3 2-tuple is: 从3个2元组生成3元组的规则是:

(a,b), (b,c), (c,a) -> (a, b, c)

ie the 2-tuples is a cycle with length 3. The order of the elements in a 3-tuple is not important, ie: 即2元组是一个长度为3的循环。3元组中元素的顺序并不重要,即:

(a,b,c) == (c,a,b)

I'm actually interested in the case where we have a number n: 我实际上对我们有数字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) ]

From a, minimize the number of 2-tuples that is left when producing 3-tuples. 从a中,最小化生成3个元组时剩余的2个元组的数量。 Each 2-tuple can only be used once. 每个2元组只能使用一次。

I wrapped my brain around this for several hours but I can't seem to come up with an elegant solution (well, neither have I found an ugly one:-) for the general case. 我花了好几个小时来解决这个问题,但是对于一般情况,我似乎无法提出一个优雅的解决方案(嗯,我也没有找到一个丑陋的解决方案:-)。 Any thoughts? 有什么想法吗?

For this you need to create number of combinations that will use for replacement. 为此,您需要创建用于替换的组合数量。 Then loop over you data for 3 item that contains any of above combinations and replace them. 然后遍历您的数据以获取包含以上任意组合的3个项目并替换它们。 I have done thi in several steps. 我已经完成了几个步骤。

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))

Output: 输出:

[(1, 2, 3), (1, 4), (2, 4)]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM