Переменные оптимизации могут использовать имена для индексирования элементов. Имена можно задать при создании переменной или после нее. Например, укажите имена при создании переменной.
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. Просмотрите последнюю переменную для подтверждения.
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 = 1x3 cell
{'row1'} {'importantRow'} {'row3'}
x.IndexNames{2}ans = 1x2 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.
LP: Optimal objective value is -1027.472366.
Heuristics: Found 1 solution using ZI round.
Upper 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.