簡體   English   中英

如何獲得等於 Python 中結果數的列表的所有數學組合

[英]How to get all mathematical combinations of a list that equal a result number in Python

背景

我們有一個家庭傳統,我和我的兄弟姐妹的聖誕禮物是用一個代碼來識別的,這個代碼只能使用與我們相關的數字來解決。 例如,代碼可以是birth month * age + graduation year (這是一個簡單的)。 如果數字是8 * 22 + 2020 = 2196 ,那么 2196 將寫在我所有的聖誕禮物上。

我已經創建了一個 Python class ,它為每個兄弟姐妹創建了一個列表,其中包含與之相關的每個數字。 目前該列表有 30 多個數字,但可能會增長到 40 多個。

問題

有沒有辦法測試等於結果數的數字列表的所有數學組合? 比如findPossibleCombinations( [8, 7, 4, 22, 2020, 573], 2196 )返回可以創建結果數的列表列表? 因此,此 function 將返回 [8, 22, 2020] 以及它發現的任何其他可用於等於 2196 的列表。任何數字都不會被使用超過一次。

我確信有一種方法可以實現 O(N^47) 算法(當然是開玩笑),但我想知道實現這種結果的最優化算法是什么?

為了計算時間,將操作數限制為總共 5-6 個。 我的父母並不瘋狂,可能永遠不會使用超過 5-6 個數字來計算最終結果。 我還將操作限制為 +、-、* 和 /,盡管我可能需要在未來幾年添加其他操作。

感謝您的任何幫助。 我希望你至少能從我奇怪的家庭傳統中得到一笑。

編輯:這是我的 class 結構。 它可以進行更多優化,但現在已經足夠了。 任何字符串都將轉換為字母數字和反字母數字並按字母添加。 “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.product 它給出了一個生成器,它產生給定序列的笛卡爾積的所有元組。

from itertools import product

values1 = range(3)     # replace with your candidate birth month values
values2 = range(3, 6)  # replace with your candidate age values
values3 = range(7, 9)  # replace with your candidate graduation year values 
target_values = {10, 20, 30}  # replace with your target values (results)
# target_values need to be a set for efficient lookup.
for val1, val2, val3 in product(values1, values2, values3):
    if val1 + val2 + val3 in target_values:  #replace with your function
        print(val1, 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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM