python回溯算法(组合相加等于某值的所有组合)

文章介绍了两个Python函数,find_combinations和helper,用于解决从给定数组中找到元素组合,使它们的和等于特定的目标值(单个值或列表),并处理浮点数。还讨论了后续的优化方向:处理目标列表和避免重复组合。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

import copy
import json


def find_combinations(arr, target):
    res = []
    helper(arr, target, [], res)
    return res


def helper(arr, target, path, res):
    if target == 0:
        res.append(path)
        return
    if target < 0:
        return
    for i in range(len(arr)):
        helper(arr[i + 1:], target - arr[i], path + [arr[i]], res)


arr = [1, 2, 3, 4, 5, 6, 7]
target = 8
res = find_combinations(arr, target)
result2 = {}
print("总和的值===", sum(arr))
print(res)
for i, j in enumerate(res):
    arr_copy = copy.deepcopy(arr)
    a = []
    b = {}
    for m in j:
        arr_copy.remove(m)
    print('remove后===', arr_copy)
    total_j = sum(j)
    total_arr_copy = sum(arr_copy)
    j = {(i + 1): v for i, v in enumerate(j)}
    arr_copy = {(i + 1): v for i, v in enumerate(arr_copy)}
    b[total_j] = j
    b[total_arr_copy] = arr_copy
    a.append(b)
    print('a=====', a)
    result2[i + 1] = a

print(json.dumps(result2))

在这里插入图片描述

2.0–支持浮点数 以及多个数分别求出(实际问题:多笔订单认多笔款的问题)

from decimal import Decimal


def find_combinations(arr, target):
    # 如果 target 是单个值,则将其转化为单元素列表
    if isinstance(target, (int, float)):
        target = [Decimal(str(target))]

    # 递归函数,返回 arr 中找出 sum 值为 target 的组合
    def helper(arr, target, path, res):
        if target == 0:
            res.append(path)
            return
        if target < 0:
            return
        for i in range(len(arr)):
            num = arr[i]
            # 将 num 转成 Decimal 对象进行计算
            if isinstance(num, (int, float)):
                num = Decimal(str(num))
            helper(arr[i + 1:], target - num, path + [num], res)

    result = {}
    for t in target:
        res = []
        helper(arr, Decimal(str(t)), [], res)
        # 将结果中的 Decimal 对象转成浮点数
        res = [[float(num) for num in r] for r in res]
        # 将结果存储到字典中
        result[float(t)] = res
    return result


arr = [42.9, 257.6, 550, 1200, 2302, 2302, 88.8, 6182.8, 480, 147, 2220, 798, 237.8, 40805, 45654.4, 282, 9982.5, 448,
       788, 3097, 9472, 200, 970, 327]

target = [37950.6, 90884.2]
res = find_combinations(arr, target)

# 按照 target 中的数值排序打印结果
for k in sorted(res.keys()):
    print("{}: {}".format(k, res[k]))

后续优化方向:taget传一个list,求arr中的元素之和等于list中的数,且不重复的组合

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值