现在想根据table_a里的金额,从table_b中碰撞找出所有的可能的发票金额合并方案

现在想根据table_a里的金额,从table_b中碰撞找出所有的可能的发票金额合并方案:见图右边的表

img

如:总金额3300可以有多张发票组成这:可以有方案1、方案2、方案3…方案N(目的是找出所有
现在要找出所有的这些方案的可能性,table_a里的每条数据不相互影响(顺序循环就可以),关键是从tabel_a每拿出一个数据,要从table_b中找出所有的方案,实际工作中,table_b中数据非常多,需要大量的人工碰撞对出这个数据?
求.助哪位大.神写出关键的碰撞代码,谢谢!

import pandas as pd
table_a = pd.DataFrame({'日期': ['day1', 'day2', 'day3'],
                    '总金额': [12500, 8600, 3300]})
table_b = pd.DataFrame({'发票号': ['N8001','N8002','N8003','N8004','N8005','N8006','N8007','N8008','N8009','N8010','N8011','N8012','N8013'],
                    '金额': [1000,500,50,1100,300,3500,150,150,2500,100,5000,1500,2000]})

print(table_a)
print(table_b)
for i in range(0, table_a.shape[0]):

可使用递归找出每一金额的所有可能的组合. 简单写了下代码:

a = 3300
b = [1000, 500, 50, 1100, 300, 3500, 150, 150, 2500, 100, 5000, 1500, 2000]

def match(a: int, b: list) -> list:
    res = []
    if min(b) > a:
        return []
    for i in range(len(b)):
        for x in cal(a, b[i:]):
            if x not in res:
                res.append(x)
    return res

def cal(a: int, b: list) -> list:
    if a < b[0] :
        return []
    if a == b[0]:
        return [[b[0]]]
    a -= b[0]
    res = []
    for i in range(1, len(b)):
        for x in cal(a, b[i:]):
            res.append([b[0]] + x)
    return res

print(match(a, b))

代码中列表元素是金额数值, 可改成字典, 以发票号为键, 金额为值即可适用本方案.