可变行长求解器优化

可以说我有四列(U,W,X,Y)。 (i)= X(i),Y(i)= 0,因为Y = XY和U(i)是可变的。 您可以更改“U”列中的值,并将W = X,并且所有值都必须为正值W,X,Y,U。 这是我的代码,它不工作。

lRo = Sheets(“Rohr-Bogen”)。Cells(Rows.Count,2).End(xlUp).Row

SolverReset solverprecision = 0.0001 SolverOk SetCell:="$Y$12:$Y$" & lRo, MaxMinVal:=3, ValueOf:="0", ByChange:="$U12$:$U$" & lRo SolverAdd cellRef:="$W$12:$W$" & lRo, relation:=2, formulaText:="$X$12:$X$" & lRo SolverAdd cellRef:="$X$12:$X$" & lRo, relation:=3, formulaText:=0 SolverOptions AssumeNonNeg:=True SolverSolve UserFinish:=True SolverFinish KeepFinal:=1 If Range("W10").Value > 0.0001 Then Call solve End If 

谢谢

您可以使用SolverAdd函数。 这个函数的forms是

 SolverAdd(CellRef, Relation, FormulaText) 

哪里

  • CellRef是公式单元格的范围(在您的情况下是Y单元格)。
  • Relation可以是对应于<=>==integerbinaryalldifferent
  • FormulaText一个具有CellRef所需(目标)值的CellRef

根据你的代码,这里是一个演示。 这是未经testing的,因为不清楚电子表格上的哪些单元格是公式,哪些是值,但是应该让您开始:

 'First I define an enumeration to make clear what 1, 2, 3 etc mean: 'For details check http://msdn.microsoft.com/en-us/library/office/ff838657(v=office.15).aspx Enum tRelationship Const tRelationship_leq = 1 ' Stands for <= Const tRelationship_eq = 2 ' Stands for = Const tRelationship_geq = 3 ' ... Const tRelationship_int = 4 Const tRelationship_bin = 5 Const tRelationship_alldiff = 6 End Enum Sub solve() lRo = Sheets(1).Cells(Rows.Count, 2).End(xlUp).Row SolverReset ' Change K7 with the range that solves all variables SolverOk SetCell:="$W$10", MaxMinVal:=3, ValueOf:="0", ByChange:="$K$7" 'solves first W10 = 0 SolverOptions AssumeNonNeg:=True SolverSolve UserFinish:=True SolverFinish KeepFinal:=1 ' Here I assume that last row is row 16. You can change that dynamically as you do ' in your code. No loop is necessary. I assume that Y12 = X12 - W12, Y13 = ..., etc. SolverAdd cellRef:=Range("Y12:Y16"), relation:=tRelationship_eq, formulaText:=0 SolverOptions AssumeNonNeg:=True SolverSolve UserFinish:=True SolverFinish KeepFinal:=1 End Sub 

事实上,你只是求解一个模型,将W10设置为零,这提供了一个保证,如果存在一个可行的解决scheme(用X = W ),它将被find。

我希望这有帮助!

UPDATE

解算器如何工作的快速总结:

  • 更改给定单元格的范围(称为决策variables单元 – 在SolverOK-->ByChange指定SolverOK-->ByChange ),以便

  • 一个给定的单元格( 只有一个单元格 ,称为目标单元格目标函数单元格 ,在SolverOK-->SetCell指定),其值取决于决策variables单元,被最小化或最大化或达到给定值( SolverOK-->MaxMinValValueOf如果MaxMinVal=3

  • 依赖于决策variables单元的一系列其他单元满足一定的约束(如上所述的SolverAdd部分)。

在您发布的代码的更新版本中:

  • SolverOK-->SetCell被赋予一系列的单元格,这将失败(请参阅SetCell的文档 )。
  • SolverAdd部分过于复杂(并且不正确)。 假设X(i)Y(i)具有涉及U单元的公式 ,那么如果Y(i) = X(i) - W(i)我们只需要这条线:

SolverAdd cellRef:="$Y$12:$Y$" & lRo, relation:=2, formulaText:=0

由于Y(i) = X(i) - W(i)Y单元设置为零确保X(i)=W(i) Y(i) = X(i) - W(i)

  • 你的代码的最后一部分有点混乱。 你检查W10的值,但是W10在模型中是不存在的。 W10是否与U(i)细胞相连? 如果你希望你的W10等于零,你可以把它放在目标函数中,并且再次使用MaxMinVal := 3ValueOf := 0 ,假设它连接到U单元。

总之,求解器只改变Decisionvariables单元( U(i) )。 我们需要最小化/最大化/等于值的单元格,以及应该是>=<==的数值的单元格都应链接到U(i)单元格。

我希望这更清楚?