Переменные оптимизации могут использовать имена для индексации элементов. Можно дать имена, когда вы создаете переменную или позже. Например, дайте имена при создании переменной.
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 showvar. 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);
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
.