ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[原创] 2014新年元旦第一强帖:实用凑数凑金额高效递归剪枝算法

  [复制链接]

TA的精华主题

TA的得分主题

发表于 2014-10-18 14:56 | 显示全部楼层
本帖已被收录到知识树中,索引项:递归
楼主在吗?请告之联系方式,有事请教,必谢!

TA的精华主题

TA的得分主题

发表于 2014-10-18 16:15 | 显示全部楼层
求楼主联系方式

TA的精华主题

TA的得分主题

发表于 2014-10-27 17:19 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
香川群子 发表于 2014-3-31 00:41
这个例子就是从一堆数中抽取符合条件的组合,直到剩余元数无法满足求和条件时停止。

但显然这样得到的结 ...


香川群子老师:我想增加一列日期,但不懂得改你的代码。能否帮处理一下。在此先谢谢了

凑金额.zip (29.79 KB, 下载次数: 47)

2014-10-27_171635.jpg

TA的精华主题

TA的得分主题

发表于 2014-10-27 21:05 | 显示全部楼层
本帖最后由 qinhuan66 于 2014-10-27 21:06 编辑

改了一下还是不行呢。
  1. Dim sj1, sj(), jg(), d&, l&, h&, h2&, m&, n&, n2&, k&, cnt&
  2. Sub kagawa_22()
  3. tms = Timer
  4. d = [H3]: l = [H6]: If l = 0 Then l = 65535
  5. h = [H1] * 10 ^ d: h2 = [h2] * 10 ^ d: If h2 > h Then h2 = h2 - h
  6. m = [C1].End(4).Row - 1
  7. [a2:a65536] = "": [a2] = 1: [a2].Resize(m).DataSeries Rowcol:=xlColumns
  8. n = [H4]: n2 = [H5]: If n2 = 0 Then If n = 0 Then n2 = m Else n2 = n

  9. [a2].Resize(m, 5).Sort [D2], 1, , , , , , 2
  10. sj0 = [a2].Resize(m, 4)
  11. sj1 = [a2].Resize(m, 7)
  12. For i = 1 To m
  13. sj1(i, 1) = "+A" & sj1(i, 1) 'Row
  14. sj1(i, 3) = "+" & sj1(i, 3) 'Code
  15. sj1(i, 4) = "+" & sj1(i, 4) 'Val
  16. sj1(i, 5) = "" 'Chk
  17. sj1(i, 6) = i 'i
  18. sj1(i, 7) = sj1(i, 4) * 10 ^ d 'Val2
  19. Next


  20. ReDim jg(l, 5): jg(0, 0) = "序号": jg(0, 1) = "组合号": jg(0, 2) = "目标金额": jg(0, 3) = "金额组合": jg(0, 4) = "所在单元格": jg(0, 5) = "单位名称组合"
  21. k = 0: cnt = 0
  22. For j = 1 To l
  23. l = 0
  24. ReDim sj(m, 1 To 8): m = 0
  25. For i = 1 To UBound(sj1)
  26. If sj1(i, 4) = "" Then
  27. m = m + 1
  28. sj(m, 1) = sj1(i, 1) 'Row
  29. sj(m, 3) = sj1(i, 3) 'Code
  30. sj(m, 4) = sj1(i, 4) 'Val
  31. sj(m, 5) = sj1(i, 5) 'Chk
  32. sj(m, 6) = sj1(i, 6) 'i
  33. sj(m, 7) = sj1(i, 7) 'Val2
  34. sj(m, 8) = sj(m - 1, 8) + sj(m, 7) 'Σ
  35. End If
  36. Next
  37. Call dgH22(h, "", "", "", "", m + 1, 1)
  38. ' [a2].Resize(m, 4) = sj1
  39. If k < j Then Exit For
  40. Next

  41. If k And k < 65535 Then [K1].CurrentRegion = "": [K1].Resize(k + 1, 6) = jg
  42. [H7] = cnt
  43. [H8] = Format(Timer - tms, "0.000s")
  44. MsgBox "Result: " & k & "/ Calc " & cnt & " Time: " & Format(Timer - tms, "0.000s")

  45. m = UBound(sj0)
  46. [a2].Resize(m, 5) = sj1
  47. [a2].Resize(m, 4) = sj0
  48. [a2].Resize(m, 5).Sort [D2], 1, [a2], , 1, , , 2
  49. End Sub
  50. Sub dgH22(r&, ri$, ra$, rc$, rv$, i&, t&)
  51. Dim j&, t1&, r2&
  52. If l Then Exit Sub
  53. cnt = cnt + 1

  54. If t >= n And t <= n2 Then
  55. r2 = r + h2
  56. For j = 1 To i - 1
  57. t1 = sj(j, 7)
  58. If r <= t1 And t1 <= r2 Then
  59. k = k + 1
  60. jg(k, 0) = k
  61. jg(k, 1) = t
  62. jg(k, 2) = (h - r + sj(j, 6)) * 10 ^ -d
  63. jg(k, 3) = rv & sj(j, 3)
  64. jg(k, 4) = ra & sj(j, 1)
  65. jg(k, 5) = rc & sj(j, 2)
  66. x = Split(ri & "," & j, ",")
  67. For l = 1 To UBound(x)
  68. sj1(sj(x(l), 5), 4) = k
  69. Next
  70. Exit Sub
  71. ElseIf t1 > r2 Then
  72. Exit For
  73. End If
  74. Next
  75. End If
  76. If t = n2 Then Exit Sub

  77. For j = i - 1 To 2 Step -1
  78. If sj(j, 6) < r + h2 Then
  79. If sj(j, 7) < r Then
  80. Exit For
  81. Else
  82. Call dgH42(r - sj(j, 6), ri & "," & j, ra & sj(j, 1), rc & sj(j, 2), rv & sj(j, 3), j, t + 1)
  83. End If
  84. End If
  85. Next

  86. End Sub
复制代码

TA的精华主题

TA的得分主题

发表于 2014-10-28 14:01 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
这...这...这哪是强帖,明明是神器呀!

TA的精华主题

TA的得分主题

发表于 2014-10-28 23:41 | 显示全部楼层
香老师你的凑数法真是太强大了。真是我们做财务的福星。在此我代表我们财务人员谢谢你。并祝你越来越年轻漂亮。越来越多精华贴给我们学习。

评分

1

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2014-10-29 08:37 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
qinhuan66 发表于 2014-10-27 17:19
香川群子老师:我想增加一列日期,但不懂得改你的代码。能否帮处理一下。在此先谢谢了

你的问题、要求是什么?

一、如果只是增加了1列日期,但这个日期不需要参与运算,
那么就只需要更改数据取值范围和结果输出范围即可。是这样子吗?


二、如果这个日期需要在输出时体现出来……那么有输出结果的例子吗?

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2014-10-29 12:44 | 显示全部楼层
香川群子 发表于 2014-10-29 08:37
你的问题、要求是什么?

一、如果只是增加了1列日期,但这个日期不需要参与运算,

谢谢 香老师  今天上午停电所以没看到你的回复。
我的想法是做成像你在其他网站做的一个附件那样(下图)
你在其他网站的附件: 例子.rar (20.31 KB, 下载次数: 52)
QQ图片20141029122850.jpg
需要提取部分还是不变(下图)
QQ图片20141029123311.jpg
本次需要做的附件: 求助.rar (26.75 KB, 下载次数: 25)

谢谢

TA的精华主题

TA的得分主题

发表于 2014-10-29 16:32 | 显示全部楼层
qinhuan66 发表于 2014-10-29 12:44
谢谢 香老师  今天上午停电所以没看到你的回复。
我的想法是做成像你在其他网站做的一个附件那样(下图) ...

香老师有一个问题(如下图),凑合金额能否优先按A列(日期多的情况)相同的日期先组合后,(例如:有9月23日,9月24日,9月25日,先在9月23日找组合,然后再到9月24日)谢谢
1230462pfpeupzw5setpel.jpg

TA的精华主题

TA的得分主题

发表于 2014-10-29 21:10 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
你好!香老师能否抽空帮我看一下108楼的求助附件。谢谢
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-11-17 14:24 , Processed in 0.048844 second(s), 12 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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