最適化変数の名前付きインデックス
名前付きインデックスの作成
最適化変数はインデックス要素の名前を使用できます。変数には作成時または作成後に名前を付けることができます。たとえば、変数を作成する際に名前を付けます。
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'}
名前付きインデックスの使用
名前付きインデックス変数を使用すると、一部の問題を容易に作成およびデバッグできます。たとえば、vars
内の名前によってインデックス付けされている変数 x
について考えてみます。
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;
インデックス変数では、string (" "
) と文字ベクトル (' '
) を区別することなく使用できます。以下に例を示します。
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")
などの string で指定された変数と、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.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) 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
向けのオレンジは 0、70 のベリーが NYC
向け、980 のオレンジが LAX
向けで、LAX
向けのベリーは 0 であることを示しています。
次の最適なフローをリストします。
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
向けであることを示しています。