【发布时间】:2020-09-20 07:07:38
【问题描述】:
如何在工作表的新行中输出每次迭代的结果集?即遍历 (i,j,k,l,m) 的所有可能组合
avg protein1 = (0,j,k,l,m)
avg protein2 = (1,j,k,l,m)
avg protein3 = (2,j,k,l,m) ...
.. .
avg protein (n-2) = (i,j,k,l,0)
avg protein (n-1) = (i,j,k,l,1)
avg protein (n) = (i,j,k,l,2)
这是修改后的背包优化问题的代码(代码有效)。它最大化 5 个不同 bin 的 avg 蛋白质值,每个 bin 受到边距约束。
Option Explicit
Sub ProteinCalc()
Dim limit As Double, tol As Double, Protein As Double, Margin As Double, averageprotein As Double, maximumMargin As Double
Dim i, j, k, l, m As Integer
Dim Proteini, Proteinj, Proteink, Proteinl, Proteinm As Double
Dim Margini, Marginj, Margink, Marginl, Marginm As Double
Worksheets("simplecalc").Range("B19:H23").ClearContents
Worksheets("simplecalc").Range("B4:F4").ClearContents
limit = Range("D6").Value 'declare max protein target on blend
tol = Range("G6").Value 'declare tolarance on protein blend to get close to max protien target
maximumMargin = Range("G8").Value 'declare minimum margin $/MT want to make
Proteini = Range("B2").Value
Proteinj = Range("C2").Value
Proteink = Range("D2").Value
Proteinl = Range("E2").Value
Proteinm = Range("F2").Value
Margini = Range("B3").Value
Marginj = Range("C3").Value
Margink = Range("D3").Value
Marginl = Range("E3").Value
Marginm = Range("F3").Value
For i = 0 To 2 'loop up to 2 to signify a possible double spot for train at station i
For j = 0 To 2
For k = 0 To 2
For l = 0 To 2
For m = 0 To 2
Protein = (Proteini * i + Proteinj * j + Proteink * k + Proteinl * l + Proteinm * m) / 5 'linear avg of 5 stations
Margin = (Margini * i + Marginj * j + Margink * k + Marginl * l + Marginm * m) / 5 ' linear avg of margin from 5 stations
If Margin > maximumMargin And Protein <= limit Then
Range("B4").Value = i
Range("C4").Value = j
Range("D4").Value = k
Range("E4").Value = l
Range("F4").Value = m
averageprotein = Protein
maximumMargin = Margin
Debug.Print i
End If
If m >= 0 And m <= 2 Then
Worksheets("simplecalc").Range("B23").Value = averageprotein
Worksheets("simplecalc").Range("C23").Value = Proteini
Worksheets("simplecalc").Range("D23").Value = Proteinj
Worksheets("simplecalc").Range("E23").Value = Proteink
Worksheets("simplecalc").Range("F23").Value = Proteinl
Worksheets("simplecalc").Range("G23").Value = Proteinm
Worksheets("simplecalc").Range("H23").Value = m
Worksheets("simplecalc").Range("i23").Value = l
Worksheets("simplecalc").Range("j23").Value = k
Worksheets("simplecalc").Range("k23").Value = j
Worksheets("simplecalc").Range("l23").Value = i
End If
Next m
If l >= 0 And l <= 2 Then
Worksheets("simplecalc").Range("B22").Value = averageprotein
Worksheets("simplecalc").Range("C22").Value = Proteini
Worksheets("simplecalc").Range("D22").Value = Proteinj
Worksheets("simplecalc").Range("E22").Value = Proteink
Worksheets("simplecalc").Range("F22").Value = Proteinl
Worksheets("simplecalc").Range("G22").Value = Proteinm
Worksheets("simplecalc").Range("H22").Value = l
End If
Next l
If k >= 0 And k <= 2 Then
Worksheets("simplecalc").Range("B21").Value = averageprotein
Worksheets("simplecalc").Range("C21").Value = Proteini
Worksheets("simplecalc").Range("D21").Value = Proteinj
Worksheets("simplecalc").Range("E21").Value = Proteink
Worksheets("simplecalc").Range("F21").Value = Proteinl
Worksheets("simplecalc").Range("G21").Value = Proteinm
Worksheets("simplecalc").Range("H21").Value = k
End If
Next k
If j >= 0 And j <= 2 Then
Worksheets("simplecalc").Range("B20").Value = averageprotein
Worksheets("simplecalc").Range("C20").Value = Proteini
Worksheets("simplecalc").Range("D20").Value = Proteinj
Worksheets("simplecalc").Range("E20").Value = Proteink
Worksheets("simplecalc").Range("F20").Value = Proteinl
Worksheets("simplecalc").Range("G20").Value = Proteinm
Worksheets("simplecalc").Range("H20").Value = j
End If
Next j
If i >= 0 And i <= 2 Then
Worksheets("simplecalc").Range("B19").Value = averageprotein
Worksheets("simplecalc").Range("C19").Value = Proteini
Worksheets("simplecalc").Range("D19").Value = Proteinj
Worksheets("simplecalc").Range("E19").Value = Proteink
Worksheets("simplecalc").Range("F19").Value = Proteinl
Worksheets("simplecalc").Range("G19").Value = Proteinm
Worksheets("simplecalc").Range("H19").Value = i
End If
Next i
Range("B6").Value = averageprotein
Range("B8").Value = maximumMargin
End Sub
【问题讨论】:
-
由于VBA代码很慢,我会使用SQL(有没有不能用SQL轻松解决的问题;),好吧有一些;()照常创建一个cartesian product并删除查询条件中不需要的欺骗。这应该比大多数减少循环数的优化要快得多。结果可以分配给带有
CopyFromRecordset的工作表 -
我不确定我是否明白你在问什么,但你可以用 81 * i + 27 * j + 9 * k + 3 * l + m + 1 计算线
-
@Zer0Kelvin 想要为循环中的每次迭代输出“平均蛋白质 = 蛋白质”值。整数 i,j,k,l,m 公式循环通过您可以将它们视为该公式中的权重。这有意义吗?
-
@ComputerVersteher 希望我知道 SQL...一般编程新手(如您所想)
-
将一些示例数据添加为格式为table 的文本和预期的输出。如果新手使用数据 sql 是一个完美的开始,因为与“普通”编程相比,基础知识要简单得多。如果您从 Ms Acccess 开始,则不需要编程,并且您稍后会受益,因为大多数 Excel 用户不使用它(因为他们不知道),但它使许多问题易于解决,并且如果您知道如何避免许多问题使用数据。只需搜索一些“ms 访问查询教程”(没有来自、报告或代码)。
标签: excel vba loops optimization