ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 Excel Home精品图文教程库
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
300集Office 2010微视频教程 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 2866|回复: 16

[求助] 最近遇到的排列组合问题

[复制链接]

TA的精华主题

TA的得分主题

发表于 2015-5-18 09:55 | 显示全部楼层 |阅读模式
本帖最后由 Kelidai 于 2015-5-18 10:33 编辑

最近做自动排程,遇到了排列组合的问题,类似m行n列的排列组合问题,就是各列的数据全部排列起来,(相当于每列排好后再统一排起来)。
每列的行数可能不同,请各位高手帮忙看看。
模拟如下:
QQ截图20150518095709.jpg

排列组合.zip (12.8 KB, 下载次数: 15)


TA的精华主题

TA的得分主题

发表于 2015-5-18 10:06 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
m,n
多不多,类似上图的,用三层for循环可以解决的

TA的精华主题

TA的得分主题

 楼主| 发表于 2015-5-18 10:17 | 显示全部楼层
liulang0808 发表于 2015-5-18 10:06
m,n
多不多,类似上图的,用三层for循环可以解决的

m,n都是不确定的,背景是我们将一批订单安排在不同的产线上,订单数量,工序都有都不固定。
求出所有可能的排列组合后,找出比较好的排程方案。

TA的精华主题

TA的得分主题

发表于 2015-5-18 10:27 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
1. 没有附件。

2. 问题太笼统,无法判断你的最终目的。

TA的精华主题

TA的得分主题

 楼主| 发表于 2015-5-18 10:46 | 显示全部楼层
香川群子 发表于 2015-5-18 10:27
1. 没有附件。

2. 问题太笼统,无法判断你的最终目的。

群子老师,附件已经加上了。

TA的精华主题

TA的得分主题

发表于 2015-5-18 10:51 | 显示全部楼层
Kelidai 发表于 2015-5-18 10:17
m,n都是不确定的,背景是我们将一批订单安排在不同的产线上,订单数量,工序都有都不固定。
求出所有可 ...

查查 香川群子 老师的帖子吧
之前有过类似问题处理的

TA的精华主题

TA的得分主题

发表于 2015-5-18 11:49 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
  1. Public sj, jg(), m, n, r
  2. Sub 香川组合递归()
  3.     sj = ActiveCell.CurrentRegion: m = UBound(sj): n = UBound(sj, 2): Amn = m ^ n
  4.     If Amn > 65536 Then Exit Sub Else r = 0   'ReDim jg(Amn, 0)
  5.     Call mndg("", 0, 0, "")
  6.     ActiveCell.CurrentRegion.Cells(1).Offset(m + 3, n).Resize(r) = WorksheetFunction.Transpose(jg)
  7. End Sub
  8. Sub mndg(s$, i, t%, ts$)
  9.     If t = n Then
  10.         p = Split(s, ";")
  11.         ReDim Preserve jg(r)
  12.         For j = 1 To n
  13.             If sj(p(j), j) <> "" Then ts = ts & ";" & sj(p(j), j) Else Exit Sub
  14.         Next
  15.         jg(r) = Mid(ts, 2): r = r + 1: Exit Sub
  16.     End If
  17.     For j = i + 1 To m
  18.         Call mndg(s & ";" & j, 0, t + 1, "")
  19.     Next j
  20. End Sub
复制代码

TA的精华主题

TA的得分主题

发表于 2015-5-18 12:30 | 显示全部楼层
首先各列元素进行全排列,
然后进行香川多列组合,得到最后结果。

所以一共需要两个不同的递归过程:

  1. Dim sj(), jg(), j&, k&, n&
  2. Sub test() 'by kagawa 2015/5/18
  3.     Dim ar, i&, m&, s$, cnt&, tms#
  4.     tms = Timer
  5.     ar = [a1].CurrentRegion
  6.     n = UBound(ar, 2)
  7.    
  8.     cnt = 1
  9.     ReDim sj(1 To n, -1 To 0)
  10.     For j = 1 To n
  11.         s = ""
  12.         For i = 1 To UBound(ar)
  13.             If ar(i, j) = "" Then Exit For
  14.             s = s & ar(i, j) '各列元素合并为字符串s
  15.         Next
  16.         k = WorksheetFunction.Fact(Len(s)) '计算各列排列结果数
  17.         sj(j, 0) = s: sj(j, -1) = k
  18.         If k > m Then m = k '得到各列排列结果的最大值
  19.         cnt = cnt * k
  20.     Next
  21.    
  22.     ReDim Preserve sj(1 To n, -1 To m) '按最大值m定义数组sj存放各列排列结果
  23.     For j = 1 To n
  24.         k = 0: Call dgPL("", CStr(sj(j, 0)), Len(sj(j, 0))) '调用全排列递归过程
  25.     Next
  26.    
  27.     ReDim jg(1 To cnt, 1 To 1) '定义存放香川多列组合的结果数组
  28.     k = 0: Call dgMN("", 1) '调用香川多列组合递归过程
  29.    
  30.     MsgBox Format(Timer - tms, "0.000s ") & k
  31.     [a1].Offset(, n + 1).CurrentRegion = ""
  32.     [a1].Offset(, n + 1).Resize(k) = jg '输出结果
  33. End Sub

  34. Sub dgPL(x$, y$, n&) '各列元素进行全排列交换的递归过程
  35.     Dim i&
  36.     If n = 1 Then k = k + 1: sj(j, k) = x & y: Exit Sub
  37.     For i = 1 To n
  38.         Call dgPL(x & Mid(y, i, 1), Left(y, i - 1) & Right(y, n - i), n - 1)
  39.     Next
  40. End Sub

  41. Sub dgMN(s$, j&) '各列排列结果进行香川多列组合的递归过程
  42.     Dim i&
  43.     For i = 1 To sj(j, -1)
  44.         If j < n Then Call dgMN(s & sj(j, i), j + 1) Else k = k + 1: jg(k, 1) = s & sj(j, i)
  45.     Next
  46. End Sub
复制代码

PLZH.zip

23.33 KB, 下载次数: 148

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2015-5-18 13:18 | 显示全部楼层
按每一个元素一个单元格进行多行多列数组输出的代码。

这个比直接合并字符串处理要复杂。

PLZH-2.zip

42.31 KB, 下载次数: 30

评分

1

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2015-5-18 13:49 | 显示全部楼层
本帖最后由 Kelidai 于 2015-5-18 15:16 编辑
香川群子 发表于 2015-5-18 13:18
按每一个元素一个单元格进行多行多列数组输出的代码。

这个比直接合并字符串处理要复杂。

已经解决了我的问题。非常感谢!
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

关闭

最新热点上一条 /1 下一条

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

GMT+8, 2024-4-26 09:00 , Processed in 0.044720 second(s), 17 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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