在Python中,如何获得一个列表中等于结果数的所有数学组合

在Python中,如何获得一个列表中等于结果数的所有数学组合,python,algorithm,math,combinations,Python,Algorithm,Math,Combinations,背景 我们有一个家庭传统,我和我兄弟姐妹的圣诞礼物由一个代码来识别,这个代码只能用与我们相关的数字来解决。例如,代码可以是出生月*年龄+毕业年。这是一个简单的代码。如果数字是8*22+2020=2196,那么数字2196就会写在我所有的圣诞礼物上 我已经创建了一个Python类,该类为每个兄弟姐妹创建一个列表,其中包含与他们相关的每个数字。目前名单上有30多个数字,但可能会增加到40多个 问题: 有没有办法测试一组数字的所有数学组合,这些数字等于一个结果数?例如,findPossibleComb

背景

我们有一个家庭传统,我和我兄弟姐妹的圣诞礼物由一个代码来识别,这个代码只能用与我们相关的数字来解决。例如,代码可以是出生月*年龄+毕业年。这是一个简单的代码。如果数字是8*22+2020=2196,那么数字2196就会写在我所有的圣诞礼物上

我已经创建了一个Python类,该类为每个兄弟姐妹创建一个列表,其中包含与他们相关的每个数字。目前名单上有30多个数字,但可能会增加到40多个

问题:

有没有办法测试一组数字的所有数学组合,这些数字等于一个结果数?例如,findPossibleCombinations[8,7,4,22,2020,573],2196返回可以创建结果编号的列表列表?因此,这个函数将返回[8,22,2020]和它发现的任何其他列表,这些列表可以用于等于2196。任何号码都不会被多次使用

当然,我相信有一种方法会导致一个ON^47算法开玩笑,但我想知道实现这种结果的最优化算法是什么

为了节省计算时间,将操作总数限制为5-6。我的父母并不疯狂,可能永远不会使用超过5-6个数字来计算最终结果。我还将操作限制为+、-、*和/,尽管我可能需要在未来几年添加其他操作

谢谢你的帮助!我希望你至少能从我古怪的家庭传统中得到一点乐趣

编辑:这是我的班级结构。它可以进行更多的优化,但现在已经足够好了。任何字符串都将转换为字母数字和逆字母数字,并按字母添加。listofnums是我想要使用的列表

def getalpha( str, inverse ):
   "Converts string to alphanumeric array of chars"
   array = []
   for i in range(0, len(str)): 
      alpha = ord(str[i]) - 96
      if inverse:
        array.append(27 - alpha)
      else:
        array.append(alpha)
   return array;

class Person:
  def __init__(self, name, middlename, birthmonth, birthday, birthyear, age, orderofbirth, gradyear, state, zip):
    #final list
    self.listofnums = []
    self.listofnums.extend((birthmonth, birthday, birthyear, birthyear - 1900, age, orderofbirth, gradyear, gradyear - 2000, zip))
    letters = name + middlename + state
    #add all related alphanumeric letters
    self.listofnums.extend(getalpha(letters, False))
    self.listofnums.extend(getalpha(letters, True))
你需要。它给出了一个生成器,它生成给定序列的笛卡尔乘积的所有元组

来自itertools进口产品 values1=范围3替换为您的候选出生月份值 values2=范围3,6替换为您的候选年龄值 values3=范围7,9替换为您的候选人毕业年份值 目标值={10,20,30}替换为目标值结果 需要设置目标_值以实现高效查找。 对于productvalues1、values2、values3中的val1、val2、val3: 如果目标值中的val1+val2+val3:替换为您的函数 printval1,val2,val3 你需要。它给出了一个生成器,它生成给定序列的笛卡尔乘积的所有元组

来自itertools进口产品 values1=范围3替换为您的候选出生月份值 values2=范围3,6替换为您的候选年龄值 values3=范围7,9替换为您的候选人毕业年份值 目标值={10,20,30}替换为目标值结果 需要设置目标_值以实现高效查找。 对于productvalues1、values2、values3中的val1、val2、val3: 如果目标值中的val1+val2+val3:替换为您的函数 printval1,val2,val3
伊斯梅尔的反应很好,使我走上了正确的道路。我必须将所有操作的排列与所有数字的组合结合起来,以得到一个数字列表的所有可能集合的列表,以及一个将达到目标值中某个数字的操作列表

这个答案假定一个常数来定义解决方案中的操作数

#Master algorithm (Get the result set of all combinations of numbers and cartesian products of operations that reach a target_value, using only the number_of_numbers_in_solution)
#Example: sibling1.results[1] = [(3, 22, 4), (<built-in function add>, <built-in function add>), 29]. This means that 3 + 22 + 4 = 29, and 29 is in target_values

NUMBER_OF_OPERATIONS_IN_SOLUTION = 3
NUMBER_OF_NUMBERS_IN_SOLUTION = NUMBER_OF_OPERATIONS_IN_SOLUTION + 1
TARGET_VALUES = {22,27,29,38,39}

import operator
from itertools import product
from itertools import combinations

def getresults( list ):
  #Add the cartesian product of all possible operations to a variable ops
  ops = []
  opslist = [operator.add, operator.sub, operator.mul, operator.truediv]
  for val in product(opslist, repeat=NUMBER_OF_OPERATIONS_IN_SOLUTION):
    ops.append(val)

  #Get the result set of all combinations of numbers and cartesian products of operations that reach a target_value
  results = []
  for x in combinations(list, NUMBER_OF_NUMBERS_IN_SOLUTION):
      for y in ops:
          result = 0
          for z in range(len(y)):
              #On the first iteration, do the operation on the first two numbers (x[z] and x[z+1])
              if (z == 0):
                  result = y[z](x[z], x[z+1])
              #For all other iterations, do the operation on the current result and x[z+1])
              else:
                  result = y[z](result, x[z+1])
      if result in TARGET_VALUES:
          results.append([x, y, result])
  print(len(results))
  return results

伊斯梅尔的反应很好,使我走上了正确的道路。我必须将所有操作的排列与所有数字的组合结合起来,以得到一个数字列表的所有可能集合的列表,以及一个将达到目标值中某个数字的操作列表

这个答案假定一个常数来定义解决方案中的操作数

#Master algorithm (Get the result set of all combinations of numbers and cartesian products of operations that reach a target_value, using only the number_of_numbers_in_solution)
#Example: sibling1.results[1] = [(3, 22, 4), (<built-in function add>, <built-in function add>), 29]. This means that 3 + 22 + 4 = 29, and 29 is in target_values

NUMBER_OF_OPERATIONS_IN_SOLUTION = 3
NUMBER_OF_NUMBERS_IN_SOLUTION = NUMBER_OF_OPERATIONS_IN_SOLUTION + 1
TARGET_VALUES = {22,27,29,38,39}

import operator
from itertools import product
from itertools import combinations

def getresults( list ):
  #Add the cartesian product of all possible operations to a variable ops
  ops = []
  opslist = [operator.add, operator.sub, operator.mul, operator.truediv]
  for val in product(opslist, repeat=NUMBER_OF_OPERATIONS_IN_SOLUTION):
    ops.append(val)

  #Get the result set of all combinations of numbers and cartesian products of operations that reach a target_value
  results = []
  for x in combinations(list, NUMBER_OF_NUMBERS_IN_SOLUTION):
      for y in ops:
          result = 0
          for z in range(len(y)):
              #On the first iteration, do the operation on the first two numbers (x[z] and x[z+1])
              if (z == 0):
                  result = y[z](x[z], x[z+1])
              #For all other iterations, do the operation on the current result and x[z+1])
              else:
                  result = y[z](result, x[z+1])
      if result in TARGET_VALUES:
          results.append([x, y, result])
  print(len(results))
  return results

实际上有无限的组合。您需要限制操作的数量,并定义应该使用哪些操作。一旦你知道了,这只是一个循环的问题。我假设这是标准情况,但是如果限制数学运算符,或者限制结果中可能使用的操作数,是否有可能将问题缩小到足够小的程度?好吧,这取决于你对“足够”的理解。一天的计算时间是极限吗?1小时?一分钟?操作有多复杂?只是简单的算术?你必须提出这些限制,我们可以帮助你实现代码。我将限制一天的计算时间。至于运营,今年我会坚持+、-、*、和/或。通常,如果涉及到更多,我们可以判断和/或得到一个提示,所以也许明年我会添加一个平方指数运算符,例如。我很乐意决定需要的任何其他约束,我只是还没有完全弄清楚这需要有多大的界限。谢谢如果您想取消闭包,请给出一些建议:以。
给我们具体的信息来处理。实际上有无限的组合。您需要限制操作的数量,并定义应该使用哪些操作。一旦你知道了,这只是一个循环的问题。我假设这是标准情况,但是如果限制数学运算符,或者限制结果中可能使用的操作数,是否有可能将问题缩小到足够小的程度?好吧,这取决于你对“足够”的理解。一天的计算时间是极限吗?1小时?一分钟?操作有多复杂?只是简单的算术?你必须提出这些限制,我们可以帮助你实现代码。我将限制一天的计算时间。至于运营,今年我会坚持+、-、*、和/或。通常,如果涉及到更多,我们可以判断和/或得到一个提示,所以也许明年我会添加一个平方指数运算符,例如。我很乐意决定需要的任何其他约束,我只是还没有完全弄清楚这需要有多大的界限。谢谢如果您想取消闭包,请给出一些建议:以。给我们提供具体的信息以供合作。