如何获取 2 表数据,并提出符合限制的组合
How to take 2 Tables of data, and come up with combination that fit the restrictions
所以,我想做的是在这里使用这两个表,并从 Table 1 中得出项目组合,总计Table 2 + 1500 或更少的总和,但永远不能低于 Table 2[=33= 的值] + 500。然后在最后它应该 return 稍后将在其余代码中使用的组合。
例如,假设我们想出了一个组合,这个组合使用了 Table 2 中的所有 4 个项目,我们可以使用所有这些项目,因为它符合限制,现在如果我们添加所有Table 2 中的值得到 11,620。现在我们必须从 Table 1 中得出一个组合,其值至少为 12,120 但小于 13,120。
如果您需要有关我要在此处存档的内容的更多详细信息,请告诉我!
限制
- 每个组合最多只能有 4 个项目
- 每个项目的值由“值”定义。
Table 2
[
{
"UAID":143071570,
"assetId":19027209,
"name":"Perfectly Legitimate Business Hat",
"value":10549
},
{
"UAID":143334875,
"assetId":19027209,
"name":"Perfectly Legitimate Business Hat",
"value":10549
},
{
"UAID":1235149469,
"assetId":100425864,
"name":"Deluxe Game Headset",
"value":1795
},
{
"UAID":2756318596,
"assetId":20573078,
"name":"Shaggy",
"value":1565
},
{
"UAID":3499638196,
"assetId":20573078,
"name":"Shaggy",
"value":1565
},
{
"UAID":11002211144,
"assetId":102618797,
"name":"DJ Remix's Goldphones",
"value":7393
},
{
"UAID":50913661583,
"assetId":4390875496,
"name":"Diamond Crystal Circlet",
"value":4886
}
]
Table 2
[
{
"UAID":672099668,
"assetId":60888284,
"name":"DarkAge Ninjas: Dual Kamas",
"value":4461
},
{
"UAID":6599510068,
"assetId":554663566,
"name":"Manicbot 10000",
"value":4319
},
{
"UAID":63414825508,
"assetId":91679217,
"name":"Sailing Hat",
"value":1886
},
{
"UAID":150428091864,
"assetId":8785277745,
"name":"Cincinnati Bengals Super Bowl LVI Helmet",
"value":954
}
]
这是我多次展示过的技术,其他人似乎都没有听说过。
思路和Finding all possible combinations of numbers to reach a given sum一样,但是比较复杂,需要反复做。它是创建一个数据结构,从中可以很容易地找到总和为特定值的子集。
class SubsetSumIter:
def __init__ (self, data):
self.data = data
# Build up an auxilliary data structure to find solutions.
last_index = {0: [-1]}
for i in range(len(data)):
for s in list(last_index.keys()):
new_s = s + data[i]['value']
if new_s in last_index:
last_index[new_s].append(i)
else:
last_index[new_s] = [i]
self.last_index_by_target = last_index
self.targets = sorted(last_index.keys())
def subsets_at_target(self, target, max_i=None):
if max_i is None:
max_i = len(self.data)
for i in self.last_index_by_target[target]:
if i == -1:
yield [] # empty sum
elif max_i <= i:
break # went past our solutions
else:
for answer in self.subsets_at_target(target - self.data[i]["value"], i):
answer.append(self.data[i])
yield answer
def subsets_in_range(self, lower, upper):
i_min = 0
i_max = len(self.targets)
while 1 < i_max - i_min:
i_mid = (i_min + i_max) // 2
if self.targets[i_mid] < lower:
i_min = i_mid
else:
i_max = i_mid
i = i_min + 1
while i < len(self.targets) and self.targets[i] <= upper:
for answer in self.subsets_at_target(self.targets[i]):
yield answer
i = i+1
由此我们可以创建您想要的加入条件,如下所示:
def complex_join(table1, table2):
iter1 = SubsetSumIter(table1)
iter2 = SubsetSumIter(table2)
# For each sum from table2
for target in iter2.targets:
# For each combination from table 1 in our desired range
for subset1 in iter1.subsets_in_range(target + 500, target + 1500):
# For each combination from table 2 that gets that target
for subset2 in iter2.subsets_at_target(target):
yield (subset1, subset2)
并找到您的示例的所有 38 个解决方案:
t1 = [
{
"UAID":143071570,
"assetId":19027209,
"name":"Perfectly Legitimate Business Hat",
"value":10549
},
{
"UAID":143334875,
"assetId":19027209,
"name":"Perfectly Legitimate Business Hat",
"value":10549
},
{
"UAID":1235149469,
"assetId":100425864,
"name":"Deluxe Game Headset",
"value":1795
},
{
"UAID":2756318596,
"assetId":20573078,
"name":"Shaggy",
"value":1565
},
{
"UAID":3499638196,
"assetId":20573078,
"name":"Shaggy",
"value":1565
},
{
"UAID":11002211144,
"assetId":102618797,
"name":"DJ Remix's Goldphones",
"value":7393
},
{
"UAID":50913661583,
"assetId":4390875496,
"name":"Diamond Crystal Circlet",
"value":4886
}
]
t2 = [
{
"UAID":672099668,
"assetId":60888284,
"name":"DarkAge Ninjas: Dual Kamas",
"value":4461
},
{
"UAID":6599510068,
"assetId":554663566,
"name":"Manicbot 10000",
"value":4319
},
{
"UAID":63414825508,
"assetId":91679217,
"name":"Sailing Hat",
"value":1886
},
{
"UAID":150428091864,
"assetId":8785277745,
"name":"Cincinnati Bengals Super Bowl LVI Helmet",
"value":954
}
]
for answer in complex_join(t1, t2):
print(answer)
如果你想在最后得到一个(可能很大的)列表,你可以简单地 list(complex_join(t1, t2))
。
所以,我想做的是在这里使用这两个表,并从 Table 1 中得出项目组合,总计Table 2 + 1500 或更少的总和,但永远不能低于 Table 2[=33= 的值] + 500。然后在最后它应该 return 稍后将在其余代码中使用的组合。
例如,假设我们想出了一个组合,这个组合使用了 Table 2 中的所有 4 个项目,我们可以使用所有这些项目,因为它符合限制,现在如果我们添加所有Table 2 中的值得到 11,620。现在我们必须从 Table 1 中得出一个组合,其值至少为 12,120 但小于 13,120。
如果您需要有关我要在此处存档的内容的更多详细信息,请告诉我!
限制
- 每个组合最多只能有 4 个项目
- 每个项目的值由“值”定义。
Table 2
[
{
"UAID":143071570,
"assetId":19027209,
"name":"Perfectly Legitimate Business Hat",
"value":10549
},
{
"UAID":143334875,
"assetId":19027209,
"name":"Perfectly Legitimate Business Hat",
"value":10549
},
{
"UAID":1235149469,
"assetId":100425864,
"name":"Deluxe Game Headset",
"value":1795
},
{
"UAID":2756318596,
"assetId":20573078,
"name":"Shaggy",
"value":1565
},
{
"UAID":3499638196,
"assetId":20573078,
"name":"Shaggy",
"value":1565
},
{
"UAID":11002211144,
"assetId":102618797,
"name":"DJ Remix's Goldphones",
"value":7393
},
{
"UAID":50913661583,
"assetId":4390875496,
"name":"Diamond Crystal Circlet",
"value":4886
}
]
Table 2
[
{
"UAID":672099668,
"assetId":60888284,
"name":"DarkAge Ninjas: Dual Kamas",
"value":4461
},
{
"UAID":6599510068,
"assetId":554663566,
"name":"Manicbot 10000",
"value":4319
},
{
"UAID":63414825508,
"assetId":91679217,
"name":"Sailing Hat",
"value":1886
},
{
"UAID":150428091864,
"assetId":8785277745,
"name":"Cincinnati Bengals Super Bowl LVI Helmet",
"value":954
}
]
这是我多次展示过的技术,其他人似乎都没有听说过。
思路和Finding all possible combinations of numbers to reach a given sum一样,但是比较复杂,需要反复做。它是创建一个数据结构,从中可以很容易地找到总和为特定值的子集。
class SubsetSumIter:
def __init__ (self, data):
self.data = data
# Build up an auxilliary data structure to find solutions.
last_index = {0: [-1]}
for i in range(len(data)):
for s in list(last_index.keys()):
new_s = s + data[i]['value']
if new_s in last_index:
last_index[new_s].append(i)
else:
last_index[new_s] = [i]
self.last_index_by_target = last_index
self.targets = sorted(last_index.keys())
def subsets_at_target(self, target, max_i=None):
if max_i is None:
max_i = len(self.data)
for i in self.last_index_by_target[target]:
if i == -1:
yield [] # empty sum
elif max_i <= i:
break # went past our solutions
else:
for answer in self.subsets_at_target(target - self.data[i]["value"], i):
answer.append(self.data[i])
yield answer
def subsets_in_range(self, lower, upper):
i_min = 0
i_max = len(self.targets)
while 1 < i_max - i_min:
i_mid = (i_min + i_max) // 2
if self.targets[i_mid] < lower:
i_min = i_mid
else:
i_max = i_mid
i = i_min + 1
while i < len(self.targets) and self.targets[i] <= upper:
for answer in self.subsets_at_target(self.targets[i]):
yield answer
i = i+1
由此我们可以创建您想要的加入条件,如下所示:
def complex_join(table1, table2):
iter1 = SubsetSumIter(table1)
iter2 = SubsetSumIter(table2)
# For each sum from table2
for target in iter2.targets:
# For each combination from table 1 in our desired range
for subset1 in iter1.subsets_in_range(target + 500, target + 1500):
# For each combination from table 2 that gets that target
for subset2 in iter2.subsets_at_target(target):
yield (subset1, subset2)
并找到您的示例的所有 38 个解决方案:
t1 = [
{
"UAID":143071570,
"assetId":19027209,
"name":"Perfectly Legitimate Business Hat",
"value":10549
},
{
"UAID":143334875,
"assetId":19027209,
"name":"Perfectly Legitimate Business Hat",
"value":10549
},
{
"UAID":1235149469,
"assetId":100425864,
"name":"Deluxe Game Headset",
"value":1795
},
{
"UAID":2756318596,
"assetId":20573078,
"name":"Shaggy",
"value":1565
},
{
"UAID":3499638196,
"assetId":20573078,
"name":"Shaggy",
"value":1565
},
{
"UAID":11002211144,
"assetId":102618797,
"name":"DJ Remix's Goldphones",
"value":7393
},
{
"UAID":50913661583,
"assetId":4390875496,
"name":"Diamond Crystal Circlet",
"value":4886
}
]
t2 = [
{
"UAID":672099668,
"assetId":60888284,
"name":"DarkAge Ninjas: Dual Kamas",
"value":4461
},
{
"UAID":6599510068,
"assetId":554663566,
"name":"Manicbot 10000",
"value":4319
},
{
"UAID":63414825508,
"assetId":91679217,
"name":"Sailing Hat",
"value":1886
},
{
"UAID":150428091864,
"assetId":8785277745,
"name":"Cincinnati Bengals Super Bowl LVI Helmet",
"value":954
}
]
for answer in complex_join(t1, t2):
print(answer)
如果你想在最后得到一个(可能很大的)列表,你可以简单地 list(complex_join(t1, t2))
。