## Named Index for Optimization Variables

### Create Named Indices

Optimization variables can use names for indexing elements. You can give the names when you create a variable or afterward. For example, give the names while creating the variable.

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`

automatically maps the names you specify to index numbers in the order of your variables. For example, `"United"`

corresponds to index 1, `"Lufthansa"`

corresponds to index 2, and `"Virgin Air"`

corresponds to index 3. Display this last variable for confirmation.

show(x(3))

[ x('Virgin Air') ]

Index names enable you to address elements of `x`

by the index names. For example:

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

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

You can create or change the index names after you create a variable. However, you cannot change the size of an optimization variable after construction. So you can change index names only by setting new names that index the same size as the original variable. For example:

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

You can set the index names for each dimension individually:

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

You can also set an index name for a particular element:

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

Examine the index names for the variable.

x.IndexNames{1}

`ans = `*1x3 cell*
{'row1'} {'importantRow'} {'row3'}

x.IndexNames{2}

`ans = `*1x2 cell*
{'col1'} {'col2'}

### Use Named Indices

You can create and debug some problems easily by using named index variables. For example, consider the variable `x`

that is indexed by the names in `vars`

:

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

Create bounds, an objective function, and linear constraints for `x`

by using the named indices.

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;

You can use strings (`" "`

) or character vectors (`' '`

) in index variables indiscriminately. For example:

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')

There is no distinction between variables you specified with a string, such as `x("P2")`

, and variables you specified with a character vector, such as `x('MPS')`

.

Because named index variables have numeric equivalents, you can use ordinary summation and colon operators even when you have named index variables. For example, you can have constraints of these forms:

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

### View Solution with Index Variables

Create and solve an optimization problem using named index variables. The problem is to maximize the profit-weighted flow of fruit to various airports, subject to constraints on the weighted flows.

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. 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 intcon variables are integer within tolerance, options.IntegerTolerance = 1e-05.

Find the optimal flow of oranges and berries to New York and Los Angeles.

[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

This display means that no oranges are going to `NYC`

, 70 berries are going to `NYC`

, 980 oranges are going to `LAX`

, and no berries are going to `LAX`

.

List the optimal flow of the following:

`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

This display means that 70 berries are going to `NYC`

, 28 apples are going to `BOS`

, and 980 oranges are going to `LAX`

.