ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
楼主: 香川群子

[分享] 求1-n个数总和符合目标值的 高效【组合递归方法】

  [复制链接]

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-11-14 09:58 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
本帖已被收录到知识树中,索引项:其他结构和算法
佛道紫皇 发表于 2013-11-14 08:29
高手,结果能不能删除已重复使用过的数值,输出的每种组合里面没有重复项?

如果找到1组组合就标记并不再使用,
那么全部计算完成后,得到的组合状态无法保证是最适合的。

建议你手动做:
1. 输出组合结果的参数选1
2. 运行以后删除这个组合,然后继续步骤1

直到最后无解为止。


上述过程当然也可以帮你改成自动化的程序代码……
不过你还是先手工模拟几次,如果这样的做法没有问题,我再考虑帮你写成自动化代码。

呵呵。

TA的精华主题

TA的得分主题

发表于 2013-11-14 11:37 | 显示全部楼层
香川群子 发表于 2013-11-14 09:58
如果找到1组组合就标记并不再使用,
那么全部计算完成后,得到的组合状态无法保证是最适合的。

我用的附件里面的一个,问题不大,就是缺少,我提的那个功能

凑金额问题-已修正.rar

23.92 KB, 下载次数: 69

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-11-14 16:22 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
你的附件是别人的算法代码……比较复杂。


我还是用我的算法,为你的目的写了个文件。

可指定求和范围(模糊匹配或精确匹配)
可指定个数范围(模糊匹配或精确匹配或所有解)
可指定小数点位置(向下兼容小数或向上取整)
可指定求解个数(或全部解指导无解为止)

……
但是需要注意的是,由算法限定,每次计算时得到的解,并非随机组合,也不一定是最佳组合。
仅仅是用我的递归算法找到的第一组解。


调试程序化了几个小时。
尚未考虑速度优化。

dgh.zip

16.85 KB, 下载次数: 95

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-11-15 00:20 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
【佛道紫皇】看一下,为你量身定做的【型材套料组合求解工具】

型材套料工具_kagawa.rar

16.47 KB, 下载次数: 282

TA的精华主题

TA的得分主题

发表于 2013-11-15 08:23 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
香川群子 发表于 2013-11-15 00:20
【佛道紫皇】看一下,为你量身定做的【型材套料组合求解工具】

谢谢,灰常感谢,无限接近我想要的输出结果了,但是能不能是我上传的附件的那种显示结果,这样方便导出数据,每种组合竖列显示。高人,能再优化不?

TA的精华主题

TA的得分主题

发表于 2013-11-15 08:25 | 显示全部楼层
香川群子 发表于 2013-11-14 16:22
你的附件是别人的算法代码……比较复杂。

高风亮节!感动

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-11-15 10:07 | 显示全部楼层
佛道紫皇 发表于 2013-11-15 08:23
谢谢,灰常感谢,无限接近我想要的输出结果了,但是能不能是我上传的附件的那种显示结果,这样方便导出数 ...

你按照第4列 【组合k】进行排序,就是你想要的竖排结果了。

这个只要把主过程代码中的最后一句改一下就可以了:
原代码:
     [a2].Resize(m, 4).Sort [a2], 1, , , , , , 2
End Sub

改成:
     [a2].Resize(m, 4).Sort [d2], 1, [a2], , 1, , , 2
End Sub




你自己改一下,试一试吧。

TA的精华主题

TA的得分主题

发表于 2013-11-15 11:18 | 显示全部楼层
香川群子 发表于 2013-11-15 10:07
你按照第4列 【组合k】进行排序,就是你想要的竖排结果了。

这个只要把主过程代码中的最后一句改一下就 ...

ok,谢谢。完美了

TA的精华主题

TA的得分主题

发表于 2013-12-31 17:22 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
mark 学习学习

TA的精华主题

TA的得分主题

发表于 2014-2-22 00:03 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
本帖最后由 小麦和小麦 于 2014-2-22 00:04 编辑

Sub bcfhdg(r%, s$, i%, t%) '不重复组合求和的递归过程代码
'参数s是组合结果的文本格式、r是组合结果的和值、i是递归进程位置指针、t是组合抽取个数指针
    Dim j%
    cnt = cnt + 1 '递归计算次数递增+1
   
    p = Split(s, "+")
    For j = 1 To UBound(p)
        jg(0, j) = p(j) '当前递归结果分解存入状态栈,以便下一次递归是检查比对
    Next
   
    If r >= h1 And r <= h2 Then '如果本次递归组合结果的和值已经在总和目标范围内,则:
        If n > m Or t = n Then '如果参数n>m是则结果都要,或者n在1-m之间时必须t=n即抽取个数正好符合条件。
            If t > jg(0, 0) Then jg(0, 0) = t
            jg(k, -1) = t出现下标越界,如何更改
            For j = 1 To UBound(p)
                jg(k, j) = p(j) '符合总和条件的本次递归结果写入结果数组。
            Next
            jg(k, 0) = "=" & Mid(s, 2) '第一列文本格式改写为=计算式,最后输出结果时直接得到计算式结果。
            k = k + 1 '结果序号递增+1
        End If
        'Exit Sub '退出以后的递归进程,加速计算过程。
        '注意:如果原始数据数值间隔小、目标和值的范围相对较大时,则这一句要注释掉,否则会漏掉一些正确的答案。
    End If
    If t = n Then Exit Sub 'n>m → go on 当n参数>m时应该继续,而n在1-m之间时因为t已经满足抽取个数则可退出递归进程。
   
    For j = i + 1 To m '递归遍历检查所有原始元素
        If r + sj(j, 1) > h2 Then Exit For '如果本次递归结果的和值已经大于总和目标范围上限,则可退出循环了。
        If CStr(sj(j, 1)) <> jg(0, t + 1) Then '检查本次递归进程中最新位置值,和前面上次递归状态栈比对,不重复才可继续
            If t < n - 1 Then jg(0, t + 2) = "" '递归最新状态栈位清空,否则会对下一次递归的比对造成错误干扰。
            Call bcfhdg(r + sj(j, 1), s & "+" & sj(j, 1), j, t + 1) '满足条件时,继续调用递归进行下一个组合位置的递归计算。
        End If
    Next j
End Sub
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-11-22 05:55 , Processed in 0.042077 second(s), 7 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表