# Solve
求解优化问题或方程问题
函数库: TyOptimization
# 语法
sol, = Solve(prob)
sol, = Solve(prob,x0)
sol, = Solve(___;Key=Value)
sol,fval = Solve(___)
sol,fval,exitflag,output,lambda = Solve(___)
# 说明
使用 Solve 来求优化问题或方程问题的解。
提示
有关完整的工作流,请参见基于问题的优化工作流或基于问题的方程求解工作流。
sol ,= Solve(prob) 求解优化问题或方程问题 prob。示例
sol ,= Solve(prob,x0) 从点 x0 开始求解 prob。示例
sol ,= Solve(___;Key=Value) 支持上述语法中的输入参量,且可使用一个或多个键-值对组参量修正求解过程。示例
sol,fval = Solve(___) 还使用上述语法中的任何输入参量返回在解处的目标函数值。
sol,fval,exitflag,output,lanbda = Solve(___) 还返回一个说明退出条件的退出标志和一个 output 结构体(其中包含关于求解过程的其他信息);对于非整数优化问题,还返回一个拉格朗日乘数结构体。示例
# 示例
求解线性规划问题
求解由优化问题定义的线性规划问题。
using TyOptimization
x = optimvar("x")
y = optimvar("y")
prob = optimproblem()
prob.Objective = -x - y/3
cons1 = x + y <= 2
cons2 = x + y/4 <= 1
cons3 = x - y <= 2
cons4 = x/4 + y >= -1
cons5 = x + y >= 1
cons6 = -x + y <= 2
prob.Constraints=(;cons1,cons2,cons3,cons4,cons5,cons6)
sol, = Solve(prob)
Solving problem using linprog.
Optimal found.
sol =
(x = 0.6666666666666666, y = 1.3333333333333335)
使用基于问题的方法求解非线性规划问题
在
using TyOptimization
x = optimvar("x")
y = optimvar("y")
以 peaks 作为目标函数,创建一个优化问题。
peaks = 3 * (1 - x)^2 * exp(-(x^2) - (y + 1)^2) - 10 * (x / 5 - x^3 - y^5) * exp(-x^2 - y^2) - 1 / 3 * exp(-(x + 1)^2 - y^2)
prob = optimproblem()
prob.Objective = peaks
将约束作为不等式包含在优化变量中。
prob.Constraints = x^2 + y^2 <= 4
将 x 的初始点设置为 1,将 y 设置为 –1,并求解问题。
x0 = (x=1,y=-1)
sol, = Solve(prob,x0)
Solving problem using fmincon.
No active inequalities.
sol =
(x = 0.22827984581856223, y = -1.6255501988809062)
不受支持的函数使用宏 @fcn2expr 生成,如果目标函数或非线性约束函数不完全由初等函数组成,则必须使用 @fcn2expr 将这些函数转换为优化表达式。
按如下所示转换当前示例:
_peaks(x,y) = 3 * (1 - x)^2 * exp(-(x^2) - (y + 1)^2) - 10 * (x / 5 - x^3 - y^5) * exp(-x^2 - y^2) - 1 / 3 * exp(-(x + 1)^2 - y^2)
convpeaks = @fcn2expr _peaks(x,y) x y
prob.Objective = convpeaks
sol2, = Solve(prob,x0)
Solving problem using fmincon.
No active inequalities.
sol2 =
(x = 0.22827984581856223, y = -1.6255501988809062)
从初始点开始求解混合整数线性规划
比较在具有和没有初始可行点的情况下求解整数规划问题的步数。该问题有八个整数变量和四个线性等式约束,所有变量都限制为正值。
using TyOptimization
using TyMath
prob = optimproblem()
x = optimvar("x",8,Lowerbnd=0,Type="integer")
创建四个线性等式约束,并将它们加入问题中。
Aeq = [22 13 26 33 21 3 14 26
39 16 22 28 26 30 23 24
18 14 29 27 30 38 26 26
41 26 28 36 18 38 16 26]
beq = [7872;10466;11322;12058]
cons = Aeq*x == beq
prob.Constraints = cons
创建目标函数,并将其加入问题中。
f = [2;10;13;17;7;5;7;3]
prob.Objective = dot(f,x)
在不使用初始点的情况下求解问题,并检查显示以查看分支定界节点的数量。
x1,fval1,exitflag1,output1 = Solve(prob)
Solving problem using intlinprog.
Running HiGHS 1.6.0: Copyright (c) 2023 HiGHS under MIT licence terms
Presolving model
4 rows, 8 cols, 32 nonzeros
4 rows, 8 cols, 27 nonzeros
Objective function is integral with scale 1
Solving MIP model with:
4 rows
8 cols (0 binary, 8 integer, 0 implied int., 0 continuous)
27 nonzeros
Nodes | B&B Tree | Objective Bounds | Dynamic Constraints | Work
Proc. InQueue | Leaves Expl. | BestBound BestSol
Gap | Cuts InLp Confl. | LpIters Time
0 0 0 0.00% 0 inf
inf 0 0 0
0 0.0s
0 0 0 0.00% 1554.047531 inf
inf 0 0 3
4 0.0s
T 2107 390 806 39.42% 1620.173547 3136 48.34% 53 3 1672 2675 0.2s
T 5576 965 2202 50.21% 1648.195463 2849 42.15% 20 6 2894 5248 0.4s
T 14545 1248 5980 74.53% 1714.198807 2154 20.42% 22 6 4473 11856 0.8s
T 25217 216 10957 97.06% 1801.469877 1854
2.83% 14 9 2006 19853 1.5s
Solving report
Status Optimal
Primal bound 1854
Dual bound 1854
Gap 0% (tolerance: 0.01%)
Solution status feasible
1854 (objective)
0 (bound viol.)
1.42108547152e-13 (int. viol.)
0 (row viol.)
Timing 1.51 (total)
0.00 (presolve)
0.00 (postsolve)
Nodes 25564
LP iterations 20115 (total)
177 (strong br.)
89 (separation)
2062 (heuristics)
使用初始可行点求得解。
x0 = (;x = [8, 62, 23, 103, 53, 84, 46, 34])
x2,fval2,exitflag2,output2 = Solve(prob)
x2 =
(x = [24.0, 15.0, 19.000000000000004, 10.999999999999904, 2.9999999999999662, 99.0, 4.0, 226.00000000000014],)
fval2 =
1853.9999999999986
使用非默认选项求解整数规划问题
求解问题
满足约束:
而不显示迭代输出。
using TyOptimization
x = optimvar("x",2,Lowerbnd=0)
x3 = optimvar("x3",Type="integer",Lowerbnd=0,Upperbnd=1)
prob = optimproblem()
prob.Objective = -3*x[1] - 2*x[2] - x3
cons1 = x[1] + x[2] + x3 <= 7
cons2 = 4*x[1] + 2*x[2] + x3 == 12
prob.Constraints = (;cons1,cons2)
opts = optimoptions(:intlinprog,Display="off",Algorithm="highs")
sol, = Solve(prob,options=opts)
sol =
(x = [0.0, 6.0], x3 = 0.0)
检查解。
sol.x
ans =
2-element Vector{Float64}:
0.0
6.0
sol.x3
ans =
0.0
使用 intlinprog 求解线性规划
强制 Solve 使用 intlinprog 作为线性规划问题的求解器。
using TyOptimization
x = optimvar("x")
y = optimvar("y")
prob = optimproblem()
prob.Objective = -x - y/3
cons1 = x + y <= 2
cons2 = x + y/4 <= 1
cons3 = x - y <= 2
cons4 = x/4 + y >= -1
cons5 = x + y >= 1
cons6 = -x + y <= 2
prob.Constraints=(;cons1,cons2,cons3,cons4,cons5,cons6)
sol, = Solve(prob,Solver = "intlinprog")
sol =
(x = 0.6666666666666666, y = 1.3333333333333335)
返回所有输出
求解使用非默认选项求解整数规划问题中所述的混合整数线性规划问题,并检查所有输出数据。
using TyOptimization
x = optimvar("x",2,Lowerbnd=0)
x3 = optimvar("x3",Type="integer",Lowerbnd=0,Upperbnd=1)
prob = optimproblem()
prob.Objective = -3*x[1] - 2*x[2] - x3
cons1 = x[1] + x[2] + x3 <= 7
cons2 = 4*x[1] + 2*x[2] + x3 == 12
prob.Constraints=(;cons1,cons2)
sol,fval,exitflag,output = Solve(prob)
sol =
(x = [0.0, 6.0], x3 = 0.0)
fval =
-12.0
exitflag =
1
output =
(iterations = 0, algorithm = "highs", message = "Optimal found.")
用索引变量查看解
使用指定的索引变量创建和求解优化问题。问题描述:将水果运往多个机场,使利润加权运量最大化,同时确保加权运量满足约束。
using TyOptimization
using TyMath
rng = MT19937ar(5489)
p = optimproblem(; ObjectiveSense="maximize")
flow = optimvar(
"flow",
("apples", "oranges", "bananas", "berries"),
("NYC", "BOS", "LAX");
Lowerbnd=0,
Type="integer",
)
pk = rand(rng, 4, 3)
pk1 = rand(rng, 4)
pk2 = rand(rng, 4)
pk3 = rand(rng, 4)
p.Objective = @fcn2expr sum(pk.* flow) flow
NYC = dot(pk1, flow[:, "NYC"]) <= 10
BOS = dot(pk2, flow[:, "BOS"]) <= 12
LAX = dot(pk3, flow[:, "LAX"]) <= 35
p.Constraints = (; NYC, BOS, LAX)
sol, fval = Solve(p)
Solving problem using intlinprog.
Running HiGHS 1.6.0: Copyright (c) 2023 HiGHS under MIT licence terms
Presolving model
3 rows, 12 cols, 12 nonzeros
3 rows, 12 cols, 12 nonzeros
Solving MIP model with:
3 rows
12 cols (0 binary, 12 integer, 0 implied int., 0 continuous)
12 nonzeros
Nodes | B&B Tree | Objective Bounds | Dynamic Constraints | Work
Proc. InQueue | Leaves Expl. | BestBound BestSol Gap | Cuts InLp Confl. | LpIters Time
0 0 0 0.00% -1160.150059 inf inf 0 0 0 0 0.0s
S 0 0 0 0.00% -1160.150059 -1027.233133 12.94% 0 0 0 0 0.0s
Solving report
Status Optimal
Primal bound -1027.23313332
Dual bound -1027.23313332
Gap 0% (tolerance: 0.01%)
Solution status feasible
-1027.23313332 (objective)
0 (bound viol.)
0 (int. viol.)
0 (row viol.)
Timing 0.01 (total)
0.00 (presolve)
0.00 (postsolve)
Nodes 1
LP iterations 3 (total)
0 (strong br.)
0 (separation)
0 (heuristics)
((flow = [0.0 28.0 0.0; 0.0 0.0 980.0; 0.0 0.0 0.0; 70.0 0.0 0.0],), 1027.2331333193338, 1, (iterations = 3, algorithm = "highs", message = "Optimal found."), (ineqlin = [-0.0, -0.0, -0.0], eqlin = Float64[], lower = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], upper = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]))
找出运送至纽约和洛杉矶的橙子和浆果的最佳运量。
idxFruit, idxAirports = findindex(flow, ("oranges", "berries"), ("NYC", "LAX"))
idxFruit =
2-element Vector{Int64}:
2
4
idxAirports =
2-element Vector{Int64}:
1
3
orangeBerries = sol.flow[idxFruit, idxAirports]
orangeBerries =
2×2 Matrix{Float64}:
0.0 980.0
70.0 0.0
此结果表示不向 NYC 运送橙子,只将 70 份浆果运至 NYC,同时将 980 份橙子运至 LAX,而不向 LAX 运送浆果。
idx = findindex(flow, ("berries", "apples", "oranges"), ("NYC", "BOS", "LAX"); islinear=Val(true))
idx =
3-element Vector{Int64}:
4
5
10
optimalFlow = sol.flow[idx]
optimalFlow =
3-element Vector{Float64}:
70.0
28.0
980.0
基于问题求解非线性系统
要使用基于问题的方法求解非线性方程组
请首先将 x 定义为一个二元素优化变量。
using TyOptimization
x = optimvar("x",2)
创建第一个方程作为优化等式表达式。
eq1 = exp(-exp(-(x[1] + x[2]))) == x[2]*(1 + x[1]^2)
同样,创建第二个方程作为优化等式表达式。
eq2 = x[1]*cos(x[2]) + x[2]*sin(x[1]) == 1/2
创建一个方程问题,并将这些方程放入该问题中。
prob = eqnproblem()
prob.Equations = (;eq1, eq2)
检查此问题。
show(prob)
Solve for:
x
eq1:
exp(-(exp(-(x[1]+x[2])))) == x[2]*(1+x[1]^2)
eq2:
x[1]*(cos(x[2]))+x[2]*(sin(x[1])) == 0.5
从
x0 = (;x = [0,0])
sol,fval,exitflag = Solve(prob,x0)
Solving problem using fsolve.
sol = (x = [0.3532465619167724, 0.6060820265081073],)
fval =
2-element Vector{Float64}:
-2.406924060061044e-7
-3.8257579881850745e-8
exitflag =
1
查看解点。
sol.x
ans =
2-element Vector{Float64}:
0.3532465619167724
0.6060820265081073
# 输入参数
prob — 优化问题或方程问题OptimizationProblem 结构体 | EquationProblem 结构体
优化问题或方程问题,指定为 OptimizationProblem 结构体或 EquationProblem 结构体。使用 optimproblem 创建优化问题;使用 eqnproblem 创建方程问题。
警告
基于问题的方法不支持目标函数、非线性等式或非线性不等式中使用复数值。如果某函数计算具有复数值,即使是作为中间值,最终结果也可能不正确。
示例: prob = optimproblem(); prob.Objective = obj; prob.Constraints = cons1;
示例: prob = eqnproblem(); prob.Equations = eqs;
x0 — 初始点具名元组
初始点,指定为具名元组,其字段名称等于 prob 中的变量名称。
示例: 如果 prob 具有名为 x 和 y 的变量:x0 =(x = [3,2,17], y = [pi/3,2*pi/3])。
# 键-值参数
将可选的参数对组指定为 Key1=Value1,...,KeyN=ValueN,其中 Key 是参数名称,Value 是对应的值。名称-值参数必须出现在其他参数之后,但参数对组的顺序无关紧要。
options — 优化选项由 optimoptions 创建的结构体 | options 结构体
优化选项,指定为一个由 optimoptions 创建的结构体,或一个由 optimset 等创建的 options 结构体。
在内部,Solve 函数调用相关求解器。确保 options 与求解器兼容。
Solver — 优化求解器"intlinprog" | "linprog" | "lsqlin" | "lsqnonlin" | "lsqnonnegm" | "quadprog" | "fminbnd" | "fminunc" | "fmincon" | "fminsearch" | "fzero" | "fsolve" | "coneprog"
优化求解器,指定为一个列出的求解器的名称。
提示
对于最大化问题(prob.ObjectiveSense 为 "max" 或 "maximize"),不要指定最小二乘求解器(名称以 lsq 开头的求解器)。如果指定,则 Solve 会引发错误,因为这些求解器无法最大化。
# 输出参数
sol — 解具名元组
解,以具名元组形式返回。对于单目标问题,返回的具名元组的字段是问题中优化变量的名称。请参阅 optimvar。
fval — 解处的目标函数值实数 | 实数向量 | 实矩阵
在解处的目标函数值。
exitflag — 求解器停止的原因整数
求解器停止的原因,以整数形式返回。
output — 有关优化过程的信息结构体
有关优化过程的信息,以结构体形式返回。输出结构体包含相关基础求解器输出字段中的字段,具体取决于调用了哪个求解器 Solve。
lambda — 解处的拉格朗日乘数结构体
解处的拉格朗日乘数,以结构体形式返回。
# 另请参阅
evaluate | OptimizationProblem | EquationProblem | optimoptions | prob2struct | @fcn2expr | optimvalues | solvers