主要内容

本页采用了机器翻译。点击此处可查看最新英文版本。

优化变量的命名索引

创建命名索引

优化变量可以使用名称来索引元素。您可以在创建变量时或之后指定名称。例如,在创建变量时给出名称。

x = optimvar('x',["United","Lufthansa","Virgin Air"])
x = 
  1×3 OptimizationVariable array with properties:

  Array-wide properties:
          Name: 'x'
          Type: 'continuous'
    IndexNames: {{}  {1×3 cell}}

  Elementwise properties:
    LowerBound: [-Inf -Inf -Inf]
    UpperBound: [Inf Inf Inf]

  See variables with show.
  See bounds with showbounds.

optimvar 会自动将您指定的名称按照变量的顺序映射到索引号。例如,"United" 对应索引 1,"Lufthansa" 对应索引 2,"Virgin Air" 对应索引 3。显示最后一个变量以供确认。

show(x(3))
    [ x('Virgin Air') ]

索引名称使您能够通过索引名称来寻址 x 的元素。例如:

route = 2*x("United") + 3*x("Virgin Air")
route = 
  Linear OptimizationExpression

    2*x('United') + 3*x('Virgin Air')

创建变量后,您可以创建或更改索引名称。但是,构造之后就无法更改优化变量的大小。因此,您只能通过设置与原始变量索引大小相同的新名称来更改索引名称。例如:

x = optimvar('x',3,2);
x.IndexNames = { {'row1','row2','row3'}, {'col1','col2'} };

您可以为每个维度单独设置索引名称:

x.IndexNames{1} = {'row1', 'row2', 'row3'};
x.IndexNames{2} = {'col1', 'col2'};

您还可以为特定元素设置索引名称:

x.IndexNames{1}{2} = 'importantRow';

检查变量的索引名称。

x.IndexNames{1}
ans = 1×3 cell
    {'row1'}    {'importantRow'}    {'row3'}

x.IndexNames{2}
ans = 1×2 cell
    {'col1'}    {'col2'}

使用命名索引

您可以使用命名索引变量轻松创建和调试一些问题。例如,考虑由 x 中的名称索引的变量 vars

vars = {'P1','P2','I1','I2','C','LE1','LE2','HE1','HE2',...
    'HPS','MPS','LPS','BF1','BF2','EP','PP'};
x = optimvar('x',vars,'LowerBound',0);

使用命名索引为 x 创建边界、目标函数和线性约束。

x('P1').LowerBound = 2500;
x('I2').UpperBound = 244000;
linprob = optimproblem;
linprob.Objective = 0.002614*x('HPS') + 0.0239*x('PP') + 0.009825*x('EP');
linprob.Constraints.cons1 = x('I1') - x('HE1') <= 132000;

您可以在索引变量中随意使用字符串(" ")或字符向量(' ')。例如:

x("P2").LowerBound = 3000;
x('MPS').LowerBound = 271536;
showbounds(x)
      2500 <= x('P1')
      3000 <= x('P2')
         0 <= x('I1')
         0 <= x('I2')  <= 244000
         0 <= x('C')
         0 <= x('LE1')
         0 <= x('LE2')
         0 <= x('HE1')
         0 <= x('HE2')
         0 <= x('HPS')
    271536 <= x('MPS')
         0 <= x('LPS')
         0 <= x('BF1')
         0 <= x('BF2')
         0 <= x('EP')
         0 <= x('PP')
    

使用字符串指定的变量(例如 x("P2"))与使用字符向量指定的变量(例如 x('MPS'))之间没有区别。

由于命名索引变量具有数值等效项,因此即使您有命名索引变量,也可以使用普通求和和冒号运算符。例如,您可以有以下形式的约束:

constr = sum(x) <= 100;
show(constr)
  x('P1') + x('P2') + x('I1') + x('I2') + x('C') + x('LE1') + x('LE2') + x('HE1') + x('HE2') + x('HPS') + x('MPS') + x('LPS') + x('BF1') + x('BF2') + x('EP') + x('PP') <= 100
y = optimvar('y',{'red','green','blue'},{'plastic','wood','metal'},...
    'Type','integer','LowerBound',0);
constr2 = y("red",:) == [5,7,3];
show(constr2)
(1, 1)

  y('red', 'plastic') == 5

(1, 2)

  y('red', 'wood') == 7

(1, 3)

  y('red', 'metal') == 3

用索引变量查看解

使用指定的索引变量创建和求解优化问题。问题描述:将水果运往多个机场,使利润加权运量最大化,同时确保加权运量满足约束。

rng(0) % For reproducibility
p = optimproblem('ObjectiveSense', 'maximize');
flow = optimvar('flow', ...
    {'apples', 'oranges', 'bananas', 'berries'}, {'NYC', 'BOS', 'LAX'}, ...
    'LowerBound',0,'Type','integer');
p.Objective = sum(sum(rand(4,3).*flow));
p.Constraints.NYC = rand(1,4)*flow(:,'NYC') <= 10;
p.Constraints.BOS = rand(1,4)*flow(:,'BOS') <= 12;
p.Constraints.LAX = rand(1,4)*flow(:,'LAX') <= 35;
sol = solve(p);
Solving problem using intlinprog.
Running HiGHS 1.7.1: Copyright (c) 2024 HiGHS under MIT licence terms
Coefficient ranges:
  Matrix [4e-02, 1e+00]
  Cost   [1e-01, 1e+00]
  Bound  [0e+00, 0e+00]
  RHS    [1e+01, 4e+01]
Presolving model
3 rows, 12 cols, 12 nonzeros  0s
3 rows, 12 cols, 12 nonzeros  0s

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.00 (total)
                    0.00 (presolve)
                    0.00 (postsolve)
  Nodes             1
  LP iterations     3 (total)
                    0 (strong br.)
                    0 (separation)
                    0 (heuristics)

Optimal solution found.

Intlinprog stopped at the root node because the objective value is within a gap tolerance of the optimal value, options.AbsoluteGapTolerance = 1e-06. The intcon variables are integer within tolerance, options.ConstraintTolerance = 1e-06.

找出运送至纽约和洛杉矶的橙子和浆果的最佳运量。

[idxFruit,idxAirports] = findindex(flow, {'oranges','berries'}, {'NYC', 'LAX'})
idxFruit = 1×2

     2     4

idxAirports = 1×2

     1     3

orangeBerries = sol.flow(idxFruit, idxAirports)
orangeBerries = 2×2

     0   980
    70     0

此结果表示不向 NYC 运送橙子,只将 70 份浆果运至 NYC,同时将 980 份橙子运至 LAX,而不向 LAX 运送浆果。

列出以下最佳运量:

Fruit Airports

----- --------

Berries NYC

Apples BOS

Oranges LAX

idx = findindex(flow, {'berries', 'apples', 'oranges'}, {'NYC', 'BOS', 'LAX'})
idx = 1×3

     4     5    10

optimalFlow = sol.flow(idx)
optimalFlow = 1×3

    70    28   980

此结果表示将 70 份浆果运送至 NYC,将 28 份苹果运送至 BOS,将 980 份橙子运送至 LAX

另请参阅

|

主题