Названный индекс для переменных оптимизации

Создайте названные индексы

Переменные оптимизации могут использовать имена в индексации элементов. Можно дать имена, когда вы создаете переменную или позже. Например, дайте имена при создании переменной.

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

  Array-wide properties:
          Name: 'x'
          Type: 'continuous'
    IndexNames: {{}  {1x3 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. Отобразите эту последнюю переменную для подтверждения.

showvar(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 = 1x3 cell array
    {'row1'}    {'importantRow'}    {'row3'}

x.IndexNames{2}
ans = 1x2 cell array
    {'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;
showconstr(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];
showconstr(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.
LP:                Optimal objective value is -1027.472366.                                         

Heuristics:        Found 1 solution using rounding.                                                 
                   Upper bound is -1027.233133.                                                     
                   Relative gap is 0.00%.                                                          

Cut Generation:    Applied 1 mir cut, and 2 strong CG cuts.                                         
                   Lower bound is -1027.233133.                                                     
                   Relative gap is 0.00%.                                                          


Optimal solution found.

Intlinprog stopped at the root node because the objective value is within a gap
tolerance of the optimal value, options.AbsoluteGapTolerance = 0 (the default
value). The intcon variables are integer within tolerance,
options.IntegerTolerance = 1e-05 (the default value).

Найдите оптимальный поток апельсинов и ягод в Нью-Йорк и Лос-Анджелес.

[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.0000
   70.0000         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.0000   28.0000  980.0000

Это отображение означает, что 70 ягод идут в NYC, 28 яблок идут в BOS, и 980 апельсинов идут в LAX.

Смотрите также

|

Похожие темы