【问题标题】:Find combinations (without "of size=r") from a set with decreasing sum value using Python使用Python从总和值递减的集合中查找组合(没有“大小= r”)
【发布时间】:2021-02-07 13:23:09
【问题描述】:

(为清晰起见已于 2021 年 2 月 8 日修订)

这类似于这里的问题: Find combinations of size r from a set with decreasing sum value
这与上面链接中发布的答案不同,因为我正在寻找没有“size r=3”的答案。

我有一组(数组)数字。
我需要将数字组合的总和从最大到最小排序,并显示数组中用于获取该行总数的数字。

数组中的任何数字每行只能使用一次,但随着总数的减少,不必在每行中使用所有数字。

如果未使用数字,则应使用零作为占位符,以便我可以创建列对齐的 CSV 文件。

输入示例 #1,数组中有 7 个数字:[30,25,20,15,10,5,1]

所需的输出示例#1格式,其中每行中的最后一个数字是该行的总和(总和):

Beginning of list

30,25,20,15,10,5,1,106
30,25,20,15,10,5,0,105
30,25,20,15,10,0,1,101
30,25,20,15,10,0,0,100
...(all number combinations in between)
30,0,0,0,0,0,0,30
0,25,0,0,0,5,0,30
...(all number combinations in between)
0,0,0,15,0,0,1,16
0,0,0,15,0,0,0,15
0,0,0,0,10,5,0,15
0,0,0,0,10,0,1,11
0,0,0,0,0,5,1,6
0,0,0,0,0,5,0,5
0,0,0,0,0,0,1,1

End of list

此外,允许重复总计,并且首选显示具有相同行总计(总和)的不同组合。 例如#1:

30,0,0,0,0,0,0,30
0,25,0,0,0,5,0,30

例如,这是基于上面输入示例 #1 的一行输出:

30,25,0,0,0,5,1,61

行中的最后一个数字是总数。总数也可以是第一个数字,但重要的是输出列表按总数降序排列。

输入示例 #2,数组中有 5 个数字:[20,15,10,5,1]

所需的输出示例#2格式,其中每行中的最后一个数字是该行的总数(总和):

Beginning of list

20,15,10,5,1,51
20,15,10,5,0,50
20,15,10,0,1,46
20,15,10,0,0,45
...(all number combinations in between)
20,0,10,0,0,30
0,15,10,5,0,30
...(all number combinations in between)
0,15,0,0,1,16
0,15,0,0,0,15
0,0,10,5,0,15
0,0,10,0,1,11
0,0,10,0,0,10
0,0,0,5,1,6
0,0,0,5,0,5
0,0,0,0,1,1

End of list

输入示例 #1:[30,25,20,15,10,5,1]

输出的每一行都应该显示数组中的每个数字,每行最多只使用一次,以获得该行的总数。 行必须按用于获得总数的数字之和以降序排序。

列表中的第一个输出行将显示 30 + 25 + 20 + 15 + 10 + 5 + 1 = 106 的结果
列表中的第二个输出行将显示 30 + 25 + 20 + 15 + 10 + 5 + 0 = 105
列表中的第三个输出行将显示 30 + 25 + 20 + 15 + 10 + 0 + 1 = 101 的结果
...其余行将继续,该行的总和(总和)越来越小,直到达到 1...
列表中倒数第三个输出行将显示结果 0 + 0 + 0 + 0 + 0 + 5 + 1 = 6
列表中倒数第二个输出行将显示结果 0 + 0 + 0 + 0 + 0 + 5 + 0 = 5
列表中的最后一个输出行将显示 0 + 0 + 0 + 0 + 0 + 0 + 1 = 1 的结果

我从用户Divyanshu 提供的代码开始,修改了不同的输入数字,并将 () 添加到最后一行(但我需要使用数组中的所有数字而不是 size=4,如下所示):

import itertools

array = [30,25,20,15,10,5,1]
size = 4

answer = [] # to store all combination
order = [] # to store order according to sum
number = 0 # index of combination

for comb in itertools.combinations(array,size):
    answer.append(comb)
    order.append([sum(comb),number]) # Storing sum and index
    number += 1

order.sort(reverse=True)  # sorting in decreasing order

for key in order:
    print (key[0],answer[key[1]]) # key[0] is sum of combination

所以这就是我需要的输入(在本例中): [30,25,20,15,10,5,1]

上述代码中的

size=4 将输出限制为数组中的 4 个数字。 如果我取出 size=4 我会得到一个错误。我需要使用整个数字数组。

我可以手动将 size=4 更改为 size=1 并运行它然后 size=2 然后运行它等等。
在代码中输入 size=1 到 size=7 并运行它(在本例中为 7 次)以获取所有可能组合的列表,这给了我 7 个不同的输出。
然后我可以手动将列表放在一起,但这不适用于更大的数字集(数组)。

我可以修改上面引用的代码还是需要使用其他方法?

【问题讨论】:

    标签: python algorithm combinations combinatorics discrete-mathematics


    【解决方案1】:

    我认为你可以这样做:

    导入以下内容:

    import pandas as pd
    import numpy as np
    

    问题中代码的开头:

    import itertools
    array = [30,25,20,15,10,5,1]
    size = 4
    
    answer = [] # to store all combination
    order = [] # to store order according to sum
    number = 0 # index of combination
    
    for comb in itertools.combinations(array,size):
        answer.append(comb)
        order.append([sum(comb),number]) # Storing sum and index
        number += 1
    
    order.sort(reverse=True)  # sorting in decreasing order
    
    for key in order:
        print (key[0],answer[key[1]]) # key[0] is sum of combination
    

    代码,我认为可以帮助获得最终选项:

    array_len = array.__len__()
    # Auxiliary to place in reference to the original array
    dict_array = {}
    for i in range(0,array_len):
        print(i)
        dict_array[array[i]]=i
    # Reorder the previous combinations
    aux = []
    for key in order:
        array_zeros = np.zeros([1, array_len+1])
        for i in answer[key[1]]:
            print(i,dict_array[i] )
            array_zeros[0][dict_array[i]] = i
            # Let add the total
            array_zeros[0][array_len]=key[0]
        aux.append(array_zeros[0])
    # Tranform into a dataframe
    aux = pd.DataFrame(aux)
    # This is to add the names to the columns 
    # for the dataframe
    aux.columns=array + ['total']
    aux = aux.astype(int)
    print(aux.head().astype(int))
       30  25  20  15  10  5  1  total
    0  30  25  20  15   0  0  0     90
    1  30  25  20   0  10  0  0     85
    2  30  25   0  15  10  0  0     80
    3  30  25  20   0   0  5  0     80
    4  30  25  20   0   0  0  1     76
    

    现在对所有尺寸进行概括

    import itertools
    import pandas as pd
    import numpy as np
    
    array = [30,25,20,15,10,5,1]
    array_len = array.__len__()
    
    
    answer = [] # to store all combination
    order = [] # to store order according to sum
    number = 0 # index of combination
    
    for size in range(1,array_len+1):
        print(size)
        for comb in itertools.combinations(array,size):
            answer.append(comb)
            order.append([sum(comb),number]) # Storing sum and index
            number += 1
    
    order.sort(reverse=True)  # sorting in decreasing order
    
    for key in order:
        print (key[0],answer[key[1]]) # key[0] is sum of combination
    
    
    # Auxiliary to place in reference to the original array
    dict_array = {}
    for i in range(0,array_len):
        print(i)
        dict_array[array[i]]=i
    # Reorder the previous combinations
    aux = []
    for key in order:
        array_zeros = np.zeros([1, array_len+1])
        for i in answer[key[1]]:
            print(i,dict_array[i] )
            array_zeros[0][dict_array[i]] = i
            # Let add the total
            array_zeros[0][array_len]=key[0]
        aux.append(array_zeros[0])
    # Tranform into a dataframe
    aux = pd.DataFrame(aux)
    # This is to add the names to the columns
    # for the dataframe
    aux.columns=array + ['total']
    aux = aux.astype(int)
    print(aux.head().astype(int))
       30  25  20  15  10  5  1  total
    0  30  25  20  15  10  5  1    106
    1  30  25  20  15  10  5  0    105
    2  30  25  20  15  10  0  1    101
    3  30  25  20  15  10  0  0    100
    4  30  25  20  15   0  5  1     96
    

    【讨论】:

    • 感谢您的回复拉斐尔。我是编程新手,所以我试图理解并遵循您的代码。尝试在在线 Python 编译器中运行它后,我遇到了几个错误,我研究并意识到需要导入
    • 您可能需要 import pandas as pd 和 import numpy as np 。
    • 感谢您的回复拉斐尔。编程新手,所以我试图理解并遵循您的代码。我发现了几个错误,我研究并意识到我需要添加这些行:import numpy as np import pandas as pd programiz.com/python-programming/online-compiler> 这是我得到的输出:0 1 2 3 4 5 6 30 0 23 1 19 2 13 3 8 4 5 5 3 6 30 23 19 13 8 5 3 0 30 23 19 13 8 5 3 > 在您的示例中,第一列是索引?我需要将其作为其他数字的总和,或者将总和作为最后一个数字。
    • 在我回复后看到您关于“将 pandas 导入为 pd 并将 numpy 导入为 np”的评论。
    • 是的,它是来自 pandas 数据帧的索引。
    【解决方案2】:

    感谢@RafaelValero (Rafael Valero),我能够了解 pandas、numpy 和数据帧。我查找了 pandas 的选项以获得所需的输出。

    这是最后的代码,还有一些额外的行供参考,但被注释掉了:

    import itertools
    import pandas as pd
    import numpy as np
    
    array = [30,25,20,15,10,5,1]
    array_len = array.__len__()
    
    answer = [] # to store all combination
    order = [] # to store order according to sum
    number = 0 # index of combination
    
    for size in range(1,array_len+1):
    # Commented out line below as it was giving extra information
    #    print(size)
        for comb in itertools.combinations(array,size):
            answer.append(comb)
            order.append([sum(comb),number]) # Storing sum and index
            number += 1
    
    order.sort(reverse=True)  # sorting in decreasing order
    
    # Commented out two lines below as it was from the original code and giving extra information
    #for key in order:
    #    print (key[0],answer[key[1]]) # key[0] is sum of combination
    
    # Auxiliary to place in reference to the original array
    dict_array = {}
    for i in range(0,array_len):
    # Commented out line below as it was giving extra information
    #    print(i)
        dict_array[array[i]]=i
    # Reorder the previous combinations
    aux = []
    for key in order:
        array_zeros = np.zeros([1, array_len+1])
        for i in answer[key[1]]:
    # Commented out line below as it was giving extra information
    #        print(i,dict_array[i] )
            array_zeros[0][dict_array[i]] = i
            # Let add the total
            array_zeros[0][array_len]=key[0]
        aux.append(array_zeros[0])
    # Tranform into a dataframe
    aux = pd.DataFrame(aux)
    # This is to add the names to the columns
    # for the dataframe
    # Update: removed this line below as I didn't need a header
    # aux.columns=array + ['total']
    aux = aux.astype(int)
    # Tried option below first but it was not necessary when using to_csv
    # pd.set_option('display.max_rows', None)
    
    print(aux.to_csv(index=False,header=None))
    
    

    搜索的参考文献:

    类似问题:
    Find combinations of size r from a set with decreasing sum value

    熊猫参考:
    https://thispointer.com/python-pandas-how-to-display-full-dataframe-i-e-print-all-rows-columns-without-truncation/

    https://pandas.pydata.org/pandas-docs/version/0.17.0/generated/pandas.DataFrame.to_csv.html

    使用的在线编译器:
    https://www.programiz.com/python-programming/online-compiler/

    使用输入示例 #1 输出,数组中有 7 个数字:[30,25,20,15,10,5,1]:

    30,25,20,15,10,5,1,106
    30,25,20,15,10,5,0,105
    30,25,20,15,10,0,1,101
    30,25,20,15,10,0,0,100
    30,25,20,15,0,5,1,96
    30,25,20,15,0,5,0,95
    30,25,20,0,10,5,1,91
    30,25,20,15,0,0,1,91
    30,25,20,0,10,5,0,90
    30,25,20,15,0,0,0,90
    30,25,0,15,10,5,1,86
    30,25,20,0,10,0,1,86
    30,25,0,15,10,5,0,85
    30,25,20,0,10,0,0,85
    30,0,20,15,10,5,1,81
    30,25,0,15,10,0,1,81
    30,25,20,0,0,5,1,81
    30,0,20,15,10,5,0,80
    30,25,0,15,10,0,0,80
    30,25,20,0,0,5,0,80
    0,25,20,15,10,5,1,76
    30,0,20,15,10,0,1,76
    30,25,0,15,0,5,1,76
    30,25,20,0,0,0,1,76
    0,25,20,15,10,5,0,75
    30,0,20,15,10,0,0,75
    30,25,0,15,0,5,0,75
    30,25,20,0,0,0,0,75
    0,25,20,15,10,0,1,71
    30,0,20,15,0,5,1,71
    30,25,0,0,10,5,1,71
    30,25,0,15,0,0,1,71
    0,25,20,15,10,0,0,70
    30,0,20,15,0,5,0,70
    30,25,0,0,10,5,0,70
    30,25,0,15,0,0,0,70
    0,25,20,15,0,5,1,66
    30,0,20,0,10,5,1,66
    30,0,20,15,0,0,1,66
    30,25,0,0,10,0,1,66
    0,25,20,15,0,5,0,65
    30,0,20,0,10,5,0,65
    30,0,20,15,0,0,0,65
    30,25,0,0,10,0,0,65
    0,25,20,0,10,5,1,61
    30,0,0,15,10,5,1,61
    0,25,20,15,0,0,1,61
    30,0,20,0,10,0,1,61
    30,25,0,0,0,5,1,61
    0,25,20,0,10,5,0,60
    30,0,0,15,10,5,0,60
    0,25,20,15,0,0,0,60
    30,0,20,0,10,0,0,60
    30,25,0,0,0,5,0,60
    0,25,0,15,10,5,1,56
    0,25,20,0,10,0,1,56
    30,0,0,15,10,0,1,56
    30,0,20,0,0,5,1,56
    30,25,0,0,0,0,1,56
    0,25,0,15,10,5,0,55
    0,25,20,0,10,0,0,55
    30,0,0,15,10,0,0,55
    30,0,20,0,0,5,0,55
    30,25,0,0,0,0,0,55
    0,0,20,15,10,5,1,51
    0,25,0,15,10,0,1,51
    0,25,20,0,0,5,1,51
    30,0,0,15,0,5,1,51
    30,0,20,0,0,0,1,51
    0,0,20,15,10,5,0,50
    0,25,0,15,10,0,0,50
    0,25,20,0,0,5,0,50
    30,0,0,15,0,5,0,50
    30,0,20,0,0,0,0,50
    0,0,20,15,10,0,1,46
    0,25,0,15,0,5,1,46
    30,0,0,0,10,5,1,46
    0,25,20,0,0,0,1,46
    30,0,0,15,0,0,1,46
    0,0,20,15,10,0,0,45
    0,25,0,15,0,5,0,45
    30,0,0,0,10,5,0,45
    0,25,20,0,0,0,0,45
    30,0,0,15,0,0,0,45
    0,0,20,15,0,5,1,41
    0,25,0,0,10,5,1,41
    0,25,0,15,0,0,1,41
    30,0,0,0,10,0,1,41
    0,0,20,15,0,5,0,40
    0,25,0,0,10,5,0,40
    0,25,0,15,0,0,0,40
    30,0,0,0,10,0,0,40
    0,0,20,0,10,5,1,36
    0,0,20,15,0,0,1,36
    0,25,0,0,10,0,1,36
    30,0,0,0,0,5,1,36
    0,0,20,0,10,5,0,35
    0,0,20,15,0,0,0,35
    0,25,0,0,10,0,0,35
    30,0,0,0,0,5,0,35
    0,0,0,15,10,5,1,31
    0,0,20,0,10,0,1,31
    0,25,0,0,0,5,1,31
    30,0,0,0,0,0,1,31
    0,0,0,15,10,5,0,30
    0,0,20,0,10,0,0,30
    0,25,0,0,0,5,0,30
    30,0,0,0,0,0,0,30
    0,0,0,15,10,0,1,26
    0,0,20,0,0,5,1,26
    0,25,0,0,0,0,1,26
    0,0,0,15,10,0,0,25
    0,0,20,0,0,5,0,25
    0,25,0,0,0,0,0,25
    0,0,0,15,0,5,1,21
    0,0,20,0,0,0,1,21
    0,0,0,15,0,5,0,20
    0,0,20,0,0,0,0,20
    0,0,0,0,10,5,1,16
    0,0,0,15,0,0,1,16
    0,0,0,0,10,5,0,15
    0,0,0,15,0,0,0,15
    0,0,0,0,10,0,1,11
    0,0,0,0,10,0,0,10
    0,0,0,0,0,5,1,6
    0,0,0,0,0,5,0,5
    0,0,0,0,0,0,1,1
    
    

    【讨论】:

      猜你喜欢
      • 2017-11-08
      • 1970-01-01
      • 2014-12-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多