1,066
社区成员
发帖
与我相关
我的任务
分享
Option Explicit
Private Sub cmdStartCombine_Click()
TextI = ""
TextJ = ""
TextK = ""
TextResult = ""
Dim a As Long
a = TextA
Dim b As Long
b = TextB
Dim c As Long
c = TextC
Dim d As Long
d = TextD
Dim datStartTime As Date
datStartTime = Now
' 这三个是条件判断,根据三个公式变换而来,不符合任何一项都没有结果;
If d * a < 93 And d * b < 930 And d * c < 9000 Then
Dim i As Long
For i = 0 To 9999
' 计算剩余时间;
Dim datNowTime As Date
datNowTime = Now
Dim lngSecondUsed As Long
lngSecondUsed = DateDiff("s", datStartTime, datNowTime)
Dim lngSecondTotal As Long
lngSecondTotal = lngSecondUsed * 10001 \ (i + 1)
Dim lngSecondRemain As Long
lngSecondRemain = lngSecondTotal - lngSecondUsed
Dim intHours As Integer
intHours = lngSecondRemain \ 3600
Dim intMinutes As Integer
intMinutes = lngSecondRemain \ 60 Mod 60
Dim intSeconds As Integer
intSeconds = lngSecondRemain Mod 60
TextResult = i & " 剩余时间: " & intHours & ":" & intMinutes & ":" & intSeconds
Dim lngLastSecondUsed As Long
If lngSecondUsed > lngLastSecondUsed Then
lngLastSecondUsed = lngSecondUsed
' 判断是否界面已退出;
If Not Me.Visible Then
MsgBox "计算中断!"
Unload Me
Exit Sub
End If
DoEvents
End If
' 在i已确定,设k=0的情况下,用前两个公式计算j的范围;
Dim jmax As Long
jmax = (93 - d * a) * i / (d * b) ' 公式1忽略k,变形
Dim jmin As Long
jmin = d * a * i / (930 - d * b) ' 公式2忽略k,变形
Dim j As Long
For j = IIf(jmin < 0, 0, jmin) To IIf(jmax > 9999, 9999, jmax)
' 在i,j已经确定的情况下,用三个公式确定k值的范围;
Dim kmax1 As Long ' 公式1变形
kmax1 = (93 * i - d * a * i - d * b * j) / (d * c)
Dim kmax2 As Long ' 公式2变形
kmax2 = (930 * j - d * a * i - d * b * j) / (d * c)
Dim kmax As Long
kmax = IIf(kmax1 < kmax2, kmax1, kmax2)
Dim kmin As Long ' 公式3变形
kmin = (d * a * i + d * b * j) / (9000 - d * c)
Dim k As Long
For k = IIf(kmin < 0, 0, kmin) To IIf(kmax > 9999, 9999, kmax)
Dim temp As Long
temp = d * (a * i + b * j + c * k)
If 93 * i > temp And 930 * j > temp And 9000 * k > temp Then
TextI = i
TextJ = j
TextK = k
TextResult = "组合完成."
Exit Sub
End If
Next
Next
Next
End If
TextResult = "没有这种组合!"
End Sub
下载地址:
链接:https://pan.baidu.com/s/1I_t1f5vfY8xxOyHQhM7CQA
提取码:jfoo
运行示例:
Option Explicit
Private Sub cmdStartCombine_Click()
TextI = ""
TextJ = ""
TextK = ""
TextResult = ""
Dim a As Long
a = TextA
Dim b As Long
b = TextB
Dim c As Long
c = TextC
Dim d As Long
d = TextD
Dim datStartTime As Date
datStartTime = Now
' 这三个是条件判断,根据三个公式变换而来,不符合任何一项都没有结果;
If d * a < 93 And d * b < 930 And d * c < 9000 Then
Dim i As Long
For i = 0 To 10000
DoEvents
' 在i已确定,设k=0的情况下,用前两个公式计算j的范围;
Dim jmax As Long
jmax = (93 - d * a) * i / (d * b) ' 公式1忽略k,变形
Dim jmin As Long
jmin = d * a * i / (930 - d * b) ' 公式2忽略k,变形
Dim j As Long
For j = jmin To jmax
' 在i,j已经确定的情况下,用三个公式确定k值的范围;
Dim kmax1 As Long ' 公式1变形
kmax1 = (93 * i - d * a * i - d * b * j) / (d * c)
Dim kmax2 As Long ' 公式2变形
kmax2 = (930 * j - d * a * i - d * b * j) / (d * c)
Dim kmax As Long
kmax = IIf(kmax1 < kmax2, kmax1, kmax2)
Dim kmin As Long ' 公式3变形
kmin = (d * a * i + d * b * j) / (9000 - d * c)
Dim k As Long
For k = kmin To kmax
Dim temp As Long
temp = d * (a * i + b * j + c * k)
If 93 * i > temp And 930 * j > temp And 9000 * k > temp Then
TextI = i
TextJ = j
TextK = k
TextResult = "组合完成."
Exit Sub
End If
Next
Next
Dim datNowTime As Date
datNowTime = Now
Dim lngSecondUsed As Long
lngSecondUsed = DateDiff("s", datStartTime, datNowTime)
Dim lngSecondTotal As Long
lngSecondTotal = lngSecondUsed * 10001 \ (i + 1)
Dim lngSecondRemain As Long
lngSecondRemain = lngSecondTotal - lngSecondUsed
Dim intHours As Integer
intHours = lngSecondRemain \ 3600
Dim intMinutes As Integer
intMinutes = lngSecondRemain \ 60 Mod 60
Dim intSeconds As Integer
intSeconds = lngSecondRemain Mod 60
TextResult = i & " 剩余时间: " & intHours & ":" & intMinutes & ":" & intSeconds
If Not Me.Visible Then
MsgBox "计算中断!"
Unload Me
Exit Sub
End If
Next
End If
TextResult = "没有这种组合!"
End Sub
下载地址:
链接:https://pan.baidu.com/s/1vXHYNAF_b0ISqiAhJBTONQ
提取码:xq3a
运行示例:
Option Explicit
Private Sub cmdStartCombine_Click()
TextI = ""
TextJ = ""
TextK = ""
TextResult = ""
Dim a As Long
a = TextA
Dim b As Long
b = TextB
Dim c As Long
c = TextC
Dim d As Long
d = TextD
Dim i As Long
For i = 1 To 9999
DoEvents
Dim j As Long
For j = 1 To 9999
Dim k As Long
' 为什么k从1到1,因为画截面图可以看出,如果k>1成立的话,k=1也必定成立,因为f(k)=9000*k
' 这个平面已经基本上立起来了,与k轴连成的棱锥体已经覆盖了指定范围内所有的i,j整数点,
' 那么k就没有必要循环那么多次了;
For k = 1 To 1
Dim temp As Long
temp = d * (a * i + b * j + c * k)
If 93 * i > temp And 930 * j > temp And 9000 * k > temp Then
TextI = i
TextJ = j
TextK = k
TextResult = "组合完成."
Exit Sub
End If
Next
Next
Next
TextResult = "没有这种组合!"
End Sub
这样修改以后,速度快了很多;Option Explicit
Private Declare Function GetTickCount Lib "Kernel32" () As Long
Private Type ResultList
ci As Integer
cj As Integer
ck As Integer
cu As Long
End Type
Private Const MAXITEM As Long = 5000 ' 记录5000个以内的结果
' 最多允许 32768个 ,但不宜太多(List控件太卡,用ListView控件可以考虑更多记录)
Private arrList() As ResultList
Private mlPoint As Long
Private Sub cmdStartCombine_Click()
Dim a&, b&, c&, d As Long
Dim i&, j&, k&, m As Long
Dim fA&, fB&, fC As Long
Dim uA&, uB&, uC As Long
Dim wA&, wB&, wC As Long
mlPoint = 0&
Call List1.Clear
TextI.Text = ""
TextJ.Text = ""
TextK.Text = ""
' TextResult.Text = ""
TextResult.Text = "正在处理中………"
a = TextA.Text
b = TextB.Text
c = TextC.Text
d = TextD.Text
' 穷举i和j和k, 需要同时满足:
' 93 *i > d*(a*i+b*j+c*k)
' 和 930 *j > d*(a*i+b*j+c*k)
' 和 9000 *k > d*(a*i+b*j+c*k)
fA = d * a
fB = d * b
fC = d * c
' Dim ww As Long
' ww = GetTickCount()
If (93& > fA) Then
For i = 1& To 10000&
DoEvents
uA = 93& * i
wA = fA * i
For j = 1& To 10000&
uB = 930& * j
wB = fB * j
m = wA + wB
If (uA < m) Then Exit For
If (uB > m) Then
For k = 1& To 10000&
uC = 9000& * k
wC = m + fC * k
If (uA <= wC) Then Exit For
If (uB <= wC) Then Exit For
If (uC <= wC) Then Exit For
arrList(mlPoint).ci = i
arrList(mlPoint).cj = j
arrList(mlPoint).ck = k
arrList(mlPoint).cu = wC
mlPoint = 1& + mlPoint
If (MAXITEM = mlPoint) Then
' 强制退出全部循环
i = 999999
j = 999999
Exit For
End If
Next ' Next k
End If
Next ' Next j
Next ' Next i
End If
' 显示结果列表:
If (0& = mlPoint) Then
' TextResult.Text = "没有这种组合!耗时" & GetTickCount() - ww & "mm"
TextResult.Text = "没有这种组合!"
Else
TextResult.Text = "组合完成。结果数:" & mlPoint
DoEvents
For i = 0& To mlPoint - 1&
List1.AddItem Format$(arrList(i).ci, "@@@@") _
& Format$(arrList(i).cj, " @@@@") _
& Format$(arrList(i).ck, " @@@@")
Next
End If
End Sub
Private Sub Form_Load()
' 事先分配好数据记录空间
ReDim arrList(MAXITEM - 1&)
End Sub
Private Sub List1_Click()
Dim strTemp As String
Dim i&, k As Long
If (0& = mlPoint) Then Exit Sub
i = List1.ListIndex
k = arrList(i).ci
strTemp = "i = " & k & " , 93 * i = " & (93& * k) & vbLf
k = arrList(i).cj
strTemp = strTemp & "j = " & k & " , 930 * j = " & (930& * k) & vbLf
k = arrList(i).ck
strTemp = strTemp & "k = " & k & " , 9000 * k = " & (9000& * k) & vbLf
strTemp = strTemp & "d*(a*i +b*j +c*k) = " & arrList(i).cu
Call MsgBox(strTemp, 64&, "结果信息")
End Sub
Option Explicit
Private Sub cmdStartCombine_Click()
TextI = ""
TextJ = ""
TextK = ""
TextResult = ""
Dim a As Long
a = TextA
Dim b As Long
b = TextB
Dim c As Long
c = TextC
Dim d As Long
d = TextD
Dim datStartTime As Date
datStartTime = Now
Dim i As Long
For i = 0 To 10000
DoEvents
Dim j As Long
For j = 0 To 10000
Dim k As Long
For k = 0 To 10000
Dim temp As Long
temp = d * (a * i + b * j + c * k)
If 93 * i > temp And 930 * j > temp And 9000 * k > temp Then
TextI = i
TextJ = j
TextK = k
TextResult = "组合完成."
Exit Sub
End If
Next
Next
Dim datNowTime As Date
datNowTime = Now
Dim lngSecondUsed As Long
lngSecondUsed = DateDiff("s", datStartTime, datNowTime)
Dim lngSecondTotal As Long
lngSecondTotal = lngSecondUsed * 10001 \ (i + 1)
Dim lngSecondRemain As Long
lngSecondRemain = lngSecondTotal - lngSecondUsed
Dim intHours As Integer
intHours = lngSecondRemain \ 3600
Dim intMinutes As Integer
intMinutes = lngSecondRemain \ 60 Mod 60
Dim intSeconds As Integer
intSeconds = lngSecondRemain Mod 60
TextResult = "剩余时间: " & intHours & ":" & intMinutes & ":" & intSeconds
Next
TextResult = "没有这种组合!"
End Sub
下载地址:
链接:https://pan.baidu.com/s/1nJ2qPQpAQU2X6AA8WkTIWg
提取码:1p1t
运行示例:
经过对比,我发现如果程序中有大量循环,编译出来的程序运行速度是IDE环境中程序运行速度的将近9倍;
所以,编译出来的程序只需要运行1个多小时就能全部遍历完了;
Private Sub cmdStartCombine_Click()
TextI = ""
TextJ = ""
TextK = ""
TextResult = ""
Dim a As Long
a = Val(TextA)
Dim b As Long
b = Val(TextB)
Dim c As Long
c = Val(TextC)
Dim d As Long
d = Val(TextD)
Dim temp As Long
Dim i As Long
Dim j As Long
Dim k As Long
Dim tmp_adi As Long
Dim tmp_bdj As Long
For i = 1 To 10000
'在这一层循环里,j和k 都是1,对判定条件2和3影响很小,暂不理会后面再算
'所以93*i<adi的话后面别算了,退出循环。而且等式左右i可以约掉
If 93 <= a * d Then Exit For '
'前面的过滤门槛过了,就为下一层做准备
tmp_adi = a * d * i
For j = 1 To 10000
DoEvents
'这一层,i是定值,adi是定值,上一层里算好了,k是1对判定条件3影响很小,暂不考虑,所以只要判定前两个不满足就别再进第三层了
tmp_bdj = b * d * j
temp = tmp_adi + tmp_bdj
If 93 * i < temp Or 930 * j < temp Then Exit For
For k = 1 To 10000
'到了这层就三个判定逐个来了,但是 adi和bdj是定值在上一层已经算好了,这下再算一下cdk就可以了
temp = tmp_adi + tmp_bdj + c * d * k
'任何一个判定不满足就退出这层
If 93 * i <= temp Or 930 * j <= temp Or 9000 * k <= temp Then Exit For
'层层把关都过了,那么就是你想要的
TextI = i
TextJ = j
TextK = k
TextResult = "组合完成."
Exit Sub
Next
Next
Next
TextResult = "没有这种组合!"
End Sub