ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[求助] 香川随机乱序在会计上的广泛应用!

[复制链接]

TA的精华主题

TA的得分主题

 楼主| 发表于 2015-3-15 20:54 | 显示全部楼层
香川群子 发表于 2015-3-15 20:50
如果是这样考虑的话,
只要把代码中 If ar(i, j)  "" Then 这一个条件判断句的条件作变更,
就能适应更 ...

是的,我已经考虑到了,工作中主要是三类:空值,奇数,偶数。

TA的精华主题

TA的得分主题

发表于 2015-3-15 23:32 | 显示全部楼层
香川群子 发表于 2015-3-15 15:04
显然必须由我亲自出马:

很牛逼的高手

TA的精华主题

TA的得分主题

发表于 2015-3-16 00:16 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
香川群子 发表于 2015-3-15 15:04
显然必须由我亲自出马:

香川老师的思路高明,直接取非空值的行列号,乱序后再重新写入数组。比我想的排除空值行列号的方法效率多了!(减少了多炊循环)

TA的精华主题

TA的得分主题

发表于 2015-3-16 00:23 | 显示全部楼层
本帖最后由 jpj123 于 2015-3-16 07:01 编辑
香川群子 发表于 2015-3-15 15:04
显然必须由我亲自出马:


请教下香川老师:
1、'      t = cr(R, 0): cr(R, 0) = cr(i, 0): cr(i, 0) = t '[数组洗牌法]交换
个人感觉这行代码其实没什么意义,可以不要。下一句直接写成这样就行了(随机数行和正常行交换取数):
      S = br(cr(R, 2), cr(R, 3))
      br(cr(R, 2), cr(R, 3)) = br(cr(i, 2), cr(i, 3))
      br(cr(i, 2), cr(i, 3)) = S '
本次随机乱序结果 赋值到数组br
'本次随机乱序结果 赋值到数组br
2、 'R = Int(Rnd * (k - i)) + i '[数组洗牌法]不重复随机乱序
    这一句好像也可以换成这样: R = Int(Rnd * 1000) Mod k '不重复随机乱序

TA的精华主题

TA的得分主题

发表于 2015-3-16 09:24 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
jpj123 发表于 2015-3-16 00:23
请教下香川老师:
1、'      t = cr(R, 0): cr(R, 0) = cr(i, 0): cr(i, 0) = t '[数组洗牌法]交换
个 ...

你的做法确实可行,并且也算是更容易理解(数组洗牌法的更直接应用。)


但是,我的做法也是多年经验的积累:
虽然代码多转了几圈,但由于我的中间变量计算、处理过程都是Long整型数据,
只在最后有一次直接赋值 br(cr(i, 1), cr(i, 2)) = ar(cr(t, 1), cr(t, 2))……

所以,比起你的3次变量交换操作,实际运算效率会高一点。(大约是15%-20%的样子。)


呵呵。

不过,我的代码中确实还可以精简一些……: cr(i, 0) = t 这最后一步交换可以省去不做。
但对实际计算效率的影响似乎不大。(<3%)

TA的精华主题

TA的得分主题

发表于 2015-3-16 09:32 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
本帖最后由 jpj123 于 2015-3-16 09:35 编辑
香川群子 发表于 2015-3-16 09:24
你的做法确实可行,并且也算是更容易理解(数组洗牌法的更直接应用。)


谢谢香川老师指点,收获颇多!

TA的精华主题

TA的得分主题

发表于 2015-3-16 09:48 | 显示全部楼层
本帖最后由 香川群子 于 2015-3-16 09:58 编辑
jpj123 发表于 2015-3-16 00:23
请教下香川老师:
1、'      t = cr(R, 0): cr(R, 0) = cr(i, 0): cr(i, 0) = t '[数组洗牌法]交换
个 ...

2、 'R = Int(Rnd * (k - i)) + i '[数组洗牌法]不重复随机乱序
    这一句好像也可以换成这样: R = Int(Rnd * 1000) Mod k '不重复随机乱序

…………
这一句只能和你的三交换代码匹配使用。

如果和我的代码配套,就无法得到正确结果……呵呵。

因为我的是位置序号,即索引值的不重复随机乱序,
而你的是实际数组结果的随机交换……原理稍有不同。

…………
而且,你的参数1000必须比k大……是否每次写代码都需要检测呢?呵呵。

或许可以改成:R = Int(Rnd * k * 10) Mod k
或者:R = Int(Rnd * k * 100) Mod k


但你这样的随机算法,有一个潜在的缺陷:
无法按顺序进行随机抽签并立即输出每一次的抽取结果。(比如抽奖、抽签。)
……因为,这以后的任何一次随机,都可能抽到第1个。 (R=0时)

呵呵

所以,不建议使用你这样的算法。

TA的精华主题

TA的得分主题

发表于 2015-3-16 10:03 | 显示全部楼层
本帖最后由 jpj123 于 2015-3-16 10:04 编辑
香川群子 发表于 2015-3-16 09:48
2、 'R = Int(Rnd * (k - i)) + i '[数组洗牌法]不重复随机乱序
    这一句好像也可以换成这样: R = In ...


嗯,明白了,谢谢香川老师的耐心讲解!
那如果写成: R = Int(Rnd * 1000) Mod( k-1)+1    是不是就可以避免出现0了呢?但确实会出现重复的机率。

TA的精华主题

TA的得分主题

发表于 2015-3-16 11:11 | 显示全部楼层
jpj123 发表于 2015-3-16 10:03
嗯,明白了,谢谢香川老师的耐心讲解!
那如果写成: R = Int(Rnd * 1000) Mod( k-1)+1    是不是就可以 ...

如果写成: R = Int(Rnd * k * 2) Mod (k- i) + i  那就没有必要使用Mod计算了

和我的 r = Int(Rnd * (k - i)) + i 就是一样的效果了。


TA的精华主题

TA的得分主题

发表于 2015-3-16 11:33 | 显示全部楼层
香川群子 发表于 2015-3-15 20:27
1. 选择单列范围执行宏,即可得到单列的随机乱序结果。

2. 如果需要同时对多列,或多行内容进行各自分 ...

2. 如果需要同时对多列,或多行内容进行各自分开的随机乱序,那么只要代码加入按列或按行的循环操作即可。
大师能否做个实例,搞不定啊

点评

的确是。  发表于 2015-3-16 14:06
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-5-12 19:29 , Processed in 0.051452 second(s), 12 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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