2026a

# 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)
使用基于问题的方法求解非线性规划问题

区域内,求 peaks 函数的最小值。为此,我们需要创建优化变量 x 和 y。

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
使用非默认选项求解整数规划问题

求解问题

满足约束:

为 二元变量(0 或 1)

而不显示迭代输出。

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

点开始求解问题。对于基于问题的方法,将初始点指定为具名元组,并将变量名称作为元组的字段。对于此问题,只有一个变量,即 x。

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