Excel精英培训网

 找回密码
 注册
数据透视表40+个常用小技巧,让你一次学会!

[已解决]代码提速

[复制链接]
发表于 2017-3-28 20:45 | 显示全部楼层
你指的1000是棱长吗?10秒确定?你是什么配置的电脑?
我现在的代码已经比楼上快了,最后发现思路甚至结构都基本一致,
但是我在Lmax上下了点功夫,棱长100时在我的破电脑上跑0.078秒,生成结果249组,
有效结果(不重复)131组。楼上高手的代码在同样的条件下跑0.20秒,生成结果739组,
有效结果(不重复)同样也是131组。
  1. Sub test()
  2. Dim s&, L&, Lmax&, L1&, L2&, arr(1 To 65536, 1 To 5), n&, m
  3. t = Timer
  4. s = [f4]
  5. L = [e4]
  6. [H2].CurrentRegion.ClearContents
  7. If L Mod 2 = 0 Then Lmax = s / 8 Else Lmax = s / 4
  8. s = s / 2
  9. For L1 = 1 To L
  10.   For L2 = L To Lmax
  11.     m = (s - L1 * L2) / (L1 + L2)
  12.     If m < 1 Then Exit For
  13.     If m = Int(m) Then
  14.       n = n + 1
  15.       arr(n, 1) = L1
  16.       arr(n, 2) = L2
  17.       arr(n, 3) = m
  18.       arr(n, 4) = L1 * L2 * m
  19.       arr(n, 5) = s * 2
  20.     End If
  21.   Next L2
  22. Next L1
  23. [H2].Resize(n, 5) = arr
  24. MsgBox Timer - t
  25. End Sub
复制代码

评分

参与人数 1 +6 收起 理由
乐乐2006201506 + 6 我和小伙伴都惊呆了

查看全部评分

excel精英培训的微信平台,每天都会发送excel学习教程和资料。扫一扫明天就可以收到新教程
回复

使用道具 举报

发表于 2017-3-28 20:47 | 显示全部楼层
既然有重复结果,说明还有提升空间,这个题很有意思,我会继续研究下去。
回复

使用道具 举报

发表于 2017-3-28 20:52 | 显示全部楼层
好吧,仔细看了下代码,与高手的代码接近99%的相似度,可以认为我抄袭吧,懒得解释
回复

使用道具 举报

 楼主| 发表于 2017-3-28 21:19 | 显示全部楼层
本帖最后由 乐乐2006201506 于 2017-3-28 22:16 编辑

没有这个意思,为您的执着精神点赞,如有更好的方法,希望分享,另外,只要在别人代码基础上改进也是一种能力啊! 20170328214725.png

电脑在76%情况下的速度,我试试您的代码,等会儿告诉您速度。


20170328215156.png

这个是您的最新代码的速度。提速近3倍。和您测试(0.078,0.2)的差不多。

您这个棱长2000时,内存占用78%时,16秒多。期待您更好的代码。

16楼代码和本楼代码速度基本一样。您说的提速25%,估计是和您没有重复代码比较的结果吧!
回复

使用道具 举报

发表于 2017-3-28 21:46 | 显示全部楼层
已经可以生成不重复结果,但是时间反而变长了,我还要再优化。
回复

使用道具 举报

发表于 2017-3-28 21:59 | 显示全部楼层
现在又提速25%左右,可以生成不重复结果。
但是总感觉不精妙,还要再研究。
  1. Sub test()
  2. Dim s&, L&, Lmax&, L1&, L2&, arr(1 To 65536, 1 To 5), n&, m
  3. s = [f4]
  4. L = [e4]
  5. [H2].CurrentRegion.ClearContents
  6. If L Mod 2 = 0 Then Lmax = s / 8 Else Lmax = s / 4
  7. s = s / 2
  8. For L1 = 1 To L
  9.   For L2 = L To Lmax
  10.     m = (s - L1 * L2) / (L1 + L2)
  11.     If m < 1 Then Exit For
  12.     If m = Int(m) Then
  13.       If m >= L1 And m <= L2 Then
  14.         n = n + 1
  15.         arr(n, 1) = L1
  16.         arr(n, 2) = L2
  17.         arr(n, 3) = m
  18.         arr(n, 4) = L1 * L2 * m
  19.         arr(n, 5) = s * 2
  20.       End If
  21.     End If
  22.   Next L2
  23. Next L1
  24. [H2].Resize(n, 5) = arr
  25. End Sub
复制代码

评分

参与人数 1 +6 收起 理由
乐乐2006201506 + 6 很给力

查看全部评分

回复

使用道具 举报

发表于 2017-3-29 10:31 | 显示全部楼层
你再试试,L2动态化了,取消Lmax,结果无重复。
Sub test()
Dim s&, L&, L1&, L2&, arr(1 To 65536, 1 To 5), n&, m, a&
t = Timer
s = [f4]
L = [e4]
[H2].CurrentRegion.ClearContents
s = s / 2
For L1 = 1 To L
  a = (s - L1) / (L1 + 1)
  For L2 = L To a
    m = (s - L1 * L2) / (L1 + L2)
    If m = Int(m) Then
      If m >= L1 And m <= L2 Then
        n = n + 1
        arr(n, 1) = L1
        arr(n, 2) = L2
        arr(n, 3) = m
        arr(n, 4) = L1 * L2 * m
        arr(n, 5) = s * 2
      End If
    End If
  Next L2
Next L1
[H2].Resize(n, 5) = arr
MsgBox Timer - t
End Sub

评分

参与人数 1 +6 收起 理由
乐乐2006201506 + 6 赞一个

查看全部评分

回复

使用道具 举报

 楼主| 发表于 2017-3-29 12:50 | 显示全部楼层
本帖最后由 乐乐2006201506 于 2017-3-29 12:52 编辑
大灰狼1976 发表于 2017-3-29 10:31
你再试试,L2动态化了,取消Lmax,结果无重复。
Sub test()
Dim s&, L&, L1&, L2&, arr(1 To 65536, 1 To ...

您最新代码,棱长1000时,最快2.72秒。
非常感谢!
敬业精神,钻研精神,都是我学习的楷模。
回复

使用道具 举报

发表于 2017-3-29 13:43 | 显示全部楼层
原来代码小改一下,棱长1000,运行0.5秒,还加上了排序。
  1. Sub grf()
  2.     t1 = Timer
  3.     Dim s, i, j, k, v, ar(1 To 65536, 1 To 5), n&
  4.     Application.DisplayAlerts = False
  5.     s = Range("f4").Value
  6.     If s Mod 2 = 1 Then MsgBox "无整数解": Exit Sub
  7.     s = s / 2         'i * j + i * k + j * k=s/2 必须为整数
  8.     '不失一般性,令k>=j>=i (k,j,i分别为长,宽,高)
  9.     For i = 1 To s / 2 - 1        '当j=1,k=1时,i有最大值s/2
  10.         For j = i To s / 2         '当i=1,k=1时,j有最大值s/2
  11.             k = (s - i * j) / (i + j)    '根据 i * j + i * k + j * k=s ,求出k
  12.             If k < j Then Exit For  '如果k出现负值,退出循环
  13.             If k = Int(k) Then '如果k为正整数
  14.                 n = n + 1
  15.                 ar(n, 1) = k
  16.                 ar(n, 2) = j
  17.                 ar(n, 3) = i
  18.                 ar(n, 4) = i * j * k
  19.                 ar(n, 5) = s * 2
  20.             End If
  21.         Next j
  22.     Next i
  23.     [H:L].ClearContents
  24.     [H1].Resize(1, 5) = Array("长", "宽", "高", "体积", "表面积")
  25.     [H2].Resize(n, 5) = ar
  26.     [H2].Resize(n, 5).Sort key1:=[H2], key2:=[i2], key3:=[j2]    '排序
  27.     Application.DisplayAlerts = True
  28.     MsgBox "运行时间" & Timer - t1 & "秒,不重复解共" & n & "组"
  29. End Sub
复制代码

评分

参与人数 1 +6 收起 理由
乐乐2006201506 + 6 很给力

查看全部评分

回复

使用道具 举报

发表于 2017-3-29 13:45 | 显示全部楼层
基本只改动了第10句和第12句。
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-4 15:50 , Processed in 0.303103 second(s), 14 queries , Gzip On, Yac On.

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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