[英]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.