Excel精英培训网

 找回密码
 注册
数据透视表40+个常用小技巧,让你一次学会!
查看: 3910|回复: 9

[已解决]请教列组合问题

[复制链接]
发表于 2014-8-13 19:20 | 显示全部楼层 |阅读模式
本帖最后由 yvll 于 2014-8-13 21:11 编辑

请教列组合问题,就是:
1、在EJ145中选择0,则由EI145要求的列数组合中的每行至少有一个单元格有“有”字。
2、在EJ145中选择大于0的数字,则由EI145要求的列数组合中没有”有“字的行不得大于EJ145规定的行数。
谢谢!
请教列组合问题.rar (14.38 KB, 下载次数: 9)
excel精英培训的微信平台,每天都会发送excel学习教程和资料。扫一扫明天就可以收到新教程
发表于 2014-8-13 19:42 | 显示全部楼层
楼主这是要干啥呢?彩票?!

如果选5
那么要检查的列数组合=Combin(47,5)=1,533,939
没一种组合可能需要检查 240-145=95行。

估计每次计算至少5分钟。呵呵。

回复

使用道具 举报

发表于 2014-8-13 19:46 | 显示全部楼层
香川群子 发表于 2014-8-13 19:42
楼主这是要干啥呢?彩票?!

如果选5

哇,香川大神,崇拜已久,终见真身{:2812:}
回复

使用道具 举报

 楼主| 发表于 2014-8-13 20:12 | 显示全部楼层
香川群子 发表于 2014-8-13 19:42
楼主这是要干啥呢?彩票?!

如果选5

蒙您眷顾,非常感谢
,知道您有能力,请帮助,因为有EI145和EJ145两个选项,实际使用中可以减少时间。
回复

使用道具 举报

发表于 2014-8-13 20:45 | 显示全部楼层    本楼为最佳答案   
本帖最后由 香川群子 于 2014-8-13 20:59 编辑

因为组合4、5、6都有 错误值=0时的解。

还好,几秒钟就能算完。

  1. Dim a&(), b$(), c&(), AC&, m&, n&, k&, z&, cnt&, tms# '定义公用变量
  2. Sub kagawa()
  3.     Dim i&, j&
  4.     tms = Timer
  5.    
  6.     ar = [CN146:EH240]
  7.     ReDim a&(1 To 95, 1 To 47)
  8.     For i = 1 To 95
  9.         For j = 1 To 47
  10.             If ar(i, j) = "有" Then a(i, j) = 1 '整理原始数据以便快速检查
  11.         Next
  12.     Next
  13.     ReDim b$(100) '存放结果的数组b初始化
  14.    
  15.     m = 47: n = [EI145]: z = [EJ145]
  16.     AC = WorksheetFunction.Combin(m, n)
  17.     ReDim c&(1 To n)
  18.     k = 0: cnt = 0: Call dgZH("", 0, 1) '调用递归组合算法
  19.     Application.StatusBar = Format(Timer - tms, "0.000s ") & cnt & " / " & Format(k, "#,##0")
  20.    
  21.     If cnt Then [EL145].CurrentRegion = "": [EL145].Resize(cnt) = WorksheetFunction.Transpose(b)
  22.     MsgBox Format(Timer - tms, "0.000s ") & Format(cnt, "#,##0")
  23. End Sub

  24. Sub dgZH(s$, i&, t&) '递归组合计算过程
  25.     Dim j&
  26.     For j = i + 1 To m - n + t
  27.         c(t) = j
  28.         If t < n Then
  29.             Call dgZH(s & "," & j, j, t + 1)
  30.         Else
  31.             k = k + 1
  32.             If Chk(n) Then
  33.                 b(cnt) = Mid(s & "," & j, 2)
  34.                 cnt = cnt + 1: If cnt > UBound(b) Then ReDim Preserve b$(cnt + 100)
  35.                 Application.StatusBar = Format(Timer - tms, "0.000s ") & cnt & Format(k / AC, " 0.0% ") & Format((AC / k - 1) * (Timer - tms), " 0.0s")
  36.             End If
  37.         End If
  38.     Next
  39. End Sub

  40. Function Chk(t&) As Boolean '检查过程
  41.     Dim i&, j&, r&
  42.     Chk = True: r = z
  43.     For i = 1 To 95
  44.         For j = 1 To n
  45.             If a(i, c(j)) Then Exit For
  46.         Next
  47.         If j > n Then If r Then r = r - 1 Else Chk = False: Exit Function
  48.     Next
  49. End Function
复制代码
寻找相同列.rar (26.88 KB, 下载次数: 14)
回复

使用道具 举报

发表于 2014-8-13 21:01 | 显示全部楼层
本帖最后由 香川群子 于 2014-8-13 21:06 编辑

附件有更新,第2选项也加入了……意外地很容易。


计算速度实际只要数秒……因为很多列组合错误结果很容易就被排除了,所以实际计算量很小。

刚确认了一下,以5为例,实际检查行的次数=21,177,524  即平均每个组合大约检查13-14行左右。


回复

使用道具 举报

 楼主| 发表于 2014-8-13 21:05 | 显示全部楼层
香川群子 发表于 2014-8-13 20:45
因为组合4、5、6都有 错误值=0时的解。

还好,几秒钟就能算完。

您太伟大了,非常感谢!
如果您有时间,请您把EJ145的功能加上。
回复

使用道具 举报

 楼主| 发表于 2014-8-13 21:10 | 显示全部楼层
香川群子 发表于 2014-8-13 21:01
附件有更新,第2选项也加入了……意外地很容易。

万分万分感谢您,您的水平非常高,无论是在EH还是在这里您的帖子经常看,这次能得到您的帮助,非常幸运。再次感谢您!
回复

使用道具 举报

发表于 2014-8-13 21:31 | 显示全部楼层
在EH 发表于 2014-8-13 19:22:53 ……

呵呵,这里是原发啊。
回复

使用道具 举报

 楼主| 发表于 2015-1-21 14:55 | 显示全部楼层
香川群子 发表于 2014-8-13 21:31
在EH 发表于 2014-8-13 19:22:53 ……

呵呵,这里是原发啊。

香川群子您好,还是这个问题我改变了一下提问,请您抽时间帮助一下。谢谢您。
改变的内容在附件中。
寻找相同列.rar (16.15 KB, 下载次数: 0)
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|Excel精英培训 ( 豫ICP备11015029号 )

GMT+8, 2024-4-20 22:40 , Processed in 0.341401 second(s), 10 queries , Gzip On, Yac On.

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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