Main Content

optimeq

创建空优化等式数组

自 R2019b 起

说明

使用 optimeq 初始化一组等式表达式。

提示

有关完整的工作流,请参阅基于问题的优化工作流基于问题的方程求解工作流

示例

eq = optimeq(N) 创建一个 N×1 空优化等式数组。使用 eq 初始化一个用于创建等式的循环。将得到的等式用作优化问题中的约束或方程问题中的方程。

示例

eq = optimeq(cstr) 创建一个按 cstr 进行索引的空优化等式数组,该数组是字符向量元胞数组或字符串向量。

如果 cstr 是 1×ncstr,其中 ncstrcstr 的元素数,则 eq 也是 1×ncstr。否则,eq 是 ncstr×1。

对于 cstrN 参量的任意组合,eq = optimeq(cstr1,N2,...,cstrk)eq = optimeq({cstr1,cstr2,...,cstrk})eq = optimeq([N1,N2,...,Nk]) 会创建一个 ncstrN2×...×ncstrk 空优化等式数组,其中 ncstrcstr 中的元素数。

示例

全部折叠

为库存模型创建等式约束。每个周期开始时的货物库存等于上一周期结束时的库存。在每个周期中,库存按 buy 增加,按 sell 减少。变量 stock 表示周期结束时的库存。

N = 12;
stock = optimvar('stock',N,1,'Type','integer','LowerBound',0);
buy = optimvar('buy',N,1,'Type','integer','LowerBound',0);
sell = optimvar('sell',N,1,'Type','integer','LowerBound',0);
initialstock = 100;

stockbalance = optimeq(N,1);

for t = 1:N
    if t == 1
        enterstock = initialstock;
    else
        enterstock = stock(t-1);
    end
    stockbalance(t) = stock(t) == enterstock + buy(t) - sell(t);
end

show(stockbalance)
(1, 1)

  -buy(1) + sell(1) + stock(1) == 100

(2, 1)

  -buy(2) + sell(2) - stock(1) + stock(2) == 0

(3, 1)

  -buy(3) + sell(3) - stock(2) + stock(3) == 0

(4, 1)

  -buy(4) + sell(4) - stock(3) + stock(4) == 0

(5, 1)

  -buy(5) + sell(5) - stock(4) + stock(5) == 0

(6, 1)

  -buy(6) + sell(6) - stock(5) + stock(6) == 0

(7, 1)

  -buy(7) + sell(7) - stock(6) + stock(7) == 0

(8, 1)

  -buy(8) + sell(8) - stock(7) + stock(8) == 0

(9, 1)

  -buy(9) + sell(9) - stock(8) + stock(9) == 0

(10, 1)

  -buy(10) + sell(10) - stock(9) + stock(10) == 0

(11, 1)

  -buy(11) + sell(11) - stock(10) + stock(11) == 0

(12, 1)

  -buy(12) + sell(12) - stock(11) + stock(12) == 0

在优化问题中包含约束。

prob = optimproblem;
prob.Constraints.stockbalance = stockbalance;

您也可以不使用循环,而是通过对变量使用矩阵运算来创建相同的约束。

stockbalance2 = optimeq(12, 1);
t = 2:12;
stockbalance2(t) = stock(t) == stock(t-1) + buy(t) - sell(t);
stockbalance2(1) = stock(1) == initialstock + buy(1) - sell(1);

显示新约束。请注意,它们与 stockbalance 中的约束相同。

show(stockbalance2)
(1, 1)

  -buy(1) + sell(1) + stock(1) == 100

(2, 1)

  -buy(2) + sell(2) - stock(1) + stock(2) == 0

(3, 1)

  -buy(3) + sell(3) - stock(2) + stock(3) == 0

(4, 1)

  -buy(4) + sell(4) - stock(3) + stock(4) == 0

(5, 1)

  -buy(5) + sell(5) - stock(4) + stock(5) == 0

(6, 1)

  -buy(6) + sell(6) - stock(5) + stock(6) == 0

(7, 1)

  -buy(7) + sell(7) - stock(6) + stock(7) == 0

(8, 1)

  -buy(8) + sell(8) - stock(7) + stock(8) == 0

(9, 1)

  -buy(9) + sell(9) - stock(8) + stock(9) == 0

(10, 1)

  -buy(10) + sell(10) - stock(9) + stock(10) == 0

(11, 1)

  -buy(11) + sell(11) - stock(10) + stock(11) == 0

(12, 1)

  -buy(12) + sell(12) - stock(11) + stock(12) == 0

使用循环方式创建约束可能比使用矩阵运算创建约束更耗时。

为涉及机场间货物传输的问题创建索引等式。首先,创建表示机场的索引。

airports = ["LAX" "JFK" "ORD"];

创建表示要从一个机场运送到另一个机场的货物的索引。

goods = ["Electronics" "Foodstuffs" "Clothing" "Raw Materials"];

创建一个数组,表示每单位货物的重量。

weights = [1 20 5 100];

创建一个变量数组,表示从一个机场运送到另一个机场的货物数量。quantities(airport1,airport2,goods) 表示从 airport1 运往 airport2goods 的数量。

quantities = optimvar('quantities',airports,airports,goods,'LowerBound',0);

创建一个等式约束,即从每个机场运出的货物总重等于运输到该机场的货物总重。

eq = optimeq(airports);
outweight = optimexpr(size(eq));
inweight = optimexpr(size(eq));
for i = 1:length(airports)
    temp = optimexpr;
    temp2 = optimexpr;
    for j = 1:length(airports)
        for k = 1:length(goods)
            temp = temp + quantities(i,j,k)*weights(k);
            temp2 = temp2 + quantities(j,i,k)*weights(k);
        end
    end
    outweight(i) = temp;
    inweight(i) = temp2;
    eq(i) = outweight(i) == inweight(i);
end

检查等式。

show(eq)
(1, 'LAX')

  -quantities('JFK', 'LAX', 'Electronics') - quantities('ORD', 'LAX', 'Electronics') + quantities('LAX', 'JFK', 'Electronics') + quantities('LAX', 'ORD', 'Electronics') - 20*quantities('JFK', 'LAX', 'Foodstuffs') - 20*quantities('ORD', 'LAX', 'Foodstuffs') + 20*quantities('LAX', 'JFK', 'Foodstuffs') + 20*quantities('LAX', 'ORD', 'Foodstuffs') - 5*quantities('JFK', 'LAX', 'Clothing') - 5*quantities('ORD', 'LAX', 'Clothing') + 5*quantities('LAX', 'JFK', 'Clothing') + 5*quantities('LAX', 'ORD', 'Clothing') - 100*quantities('JFK', 'LAX', 'Raw Materials') - 100*quantities('ORD', 'LAX', 'Raw Materials') + 100*quantities('LAX', 'JFK', 'Raw Materials') + 100*quantities('LAX', 'ORD', 'Raw Materials') == 0

(1, 'JFK')

  quantities('JFK', 'LAX', 'Electronics') - quantities('LAX', 'JFK', 'Electronics') - quantities('ORD', 'JFK', 'Electronics') + quantities('JFK', 'ORD', 'Electronics') + 20*quantities('JFK', 'LAX', 'Foodstuffs') - 20*quantities('LAX', 'JFK', 'Foodstuffs') - 20*quantities('ORD', 'JFK', 'Foodstuffs') + 20*quantities('JFK', 'ORD', 'Foodstuffs') + 5*quantities('JFK', 'LAX', 'Clothing') - 5*quantities('LAX', 'JFK', 'Clothing') - 5*quantities('ORD', 'JFK', 'Clothing') + 5*quantities('JFK', 'ORD', 'Clothing') + 100*quantities('JFK', 'LAX', 'Raw Materials') - 100*quantities('LAX', 'JFK', 'Raw Materials') - 100*quantities('ORD', 'JFK', 'Raw Materials') + 100*quantities('JFK', 'ORD', 'Raw Materials') == 0

(1, 'ORD')

  quantities('ORD', 'LAX', 'Electronics') + quantities('ORD', 'JFK', 'Electronics') - quantities('LAX', 'ORD', 'Electronics') - quantities('JFK', 'ORD', 'Electronics') + 20*quantities('ORD', 'LAX', 'Foodstuffs') + 20*quantities('ORD', 'JFK', 'Foodstuffs') - 20*quantities('LAX', 'ORD', 'Foodstuffs') - 20*quantities('JFK', 'ORD', 'Foodstuffs') + 5*quantities('ORD', 'LAX', 'Clothing') + 5*quantities('ORD', 'JFK', 'Clothing') - 5*quantities('LAX', 'ORD', 'Clothing') - 5*quantities('JFK', 'ORD', 'Clothing') + 100*quantities('ORD', 'LAX', 'Raw Materials') + 100*quantities('ORD', 'JFK', 'Raw Materials') - 100*quantities('LAX', 'ORD', 'Raw Materials') - 100*quantities('JFK', 'ORD', 'Raw Materials') == 0

为了避免嵌套的 for 循环,请使用标准 MATLAB® 运算符来表示等式。通过对到达机场的索引求和,创建离开数量数组。压缩结果以删除单一维度。

departing = squeeze(sum(quantities,2));

计算离开数量的重量。

departweights = departing * weights';

同样,计算到达数量的重量。

arriving = squeeze(sum(quantities,1));
arriveweights = arriving*weights';

创建约束,使离开的重量等于到达的重量。

eq2 = departweights == arriveweights;

通过设置 IndexNames 属性,为等式包含适当的索引名称。

eq2.IndexNames = {airports,{}};

显示新等式。请注意,它们与前面的等式相匹配,但是是经过转置的向量。

show(eq2)
('LAX', 1)

  -quantities('JFK', 'LAX', 'Electronics') - quantities('ORD', 'LAX', 'Electronics') + quantities('LAX', 'JFK', 'Electronics') + quantities('LAX', 'ORD', 'Electronics') - 20*quantities('JFK', 'LAX', 'Foodstuffs') - 20*quantities('ORD', 'LAX', 'Foodstuffs') + 20*quantities('LAX', 'JFK', 'Foodstuffs') + 20*quantities('LAX', 'ORD', 'Foodstuffs') - 5*quantities('JFK', 'LAX', 'Clothing') - 5*quantities('ORD', 'LAX', 'Clothing') + 5*quantities('LAX', 'JFK', 'Clothing') + 5*quantities('LAX', 'ORD', 'Clothing') - 100*quantities('JFK', 'LAX', 'Raw Materials') - 100*quantities('ORD', 'LAX', 'Raw Materials') + 100*quantities('LAX', 'JFK', 'Raw Materials') + 100*quantities('LAX', 'ORD', 'Raw Materials') == 0

('JFK', 1)

  quantities('JFK', 'LAX', 'Electronics') - quantities('LAX', 'JFK', 'Electronics') - quantities('ORD', 'JFK', 'Electronics') + quantities('JFK', 'ORD', 'Electronics') + 20*quantities('JFK', 'LAX', 'Foodstuffs') - 20*quantities('LAX', 'JFK', 'Foodstuffs') - 20*quantities('ORD', 'JFK', 'Foodstuffs') + 20*quantities('JFK', 'ORD', 'Foodstuffs') + 5*quantities('JFK', 'LAX', 'Clothing') - 5*quantities('LAX', 'JFK', 'Clothing') - 5*quantities('ORD', 'JFK', 'Clothing') + 5*quantities('JFK', 'ORD', 'Clothing') + 100*quantities('JFK', 'LAX', 'Raw Materials') - 100*quantities('LAX', 'JFK', 'Raw Materials') - 100*quantities('ORD', 'JFK', 'Raw Materials') + 100*quantities('JFK', 'ORD', 'Raw Materials') == 0

('ORD', 1)

  quantities('ORD', 'LAX', 'Electronics') + quantities('ORD', 'JFK', 'Electronics') - quantities('LAX', 'ORD', 'Electronics') - quantities('JFK', 'ORD', 'Electronics') + 20*quantities('ORD', 'LAX', 'Foodstuffs') + 20*quantities('ORD', 'JFK', 'Foodstuffs') - 20*quantities('LAX', 'ORD', 'Foodstuffs') - 20*quantities('JFK', 'ORD', 'Foodstuffs') + 5*quantities('ORD', 'LAX', 'Clothing') + 5*quantities('ORD', 'JFK', 'Clothing') - 5*quantities('LAX', 'ORD', 'Clothing') - 5*quantities('JFK', 'ORD', 'Clothing') + 100*quantities('ORD', 'LAX', 'Raw Materials') + 100*quantities('ORD', 'JFK', 'Raw Materials') - 100*quantities('LAX', 'ORD', 'Raw Materials') - 100*quantities('JFK', 'ORD', 'Raw Materials') == 0

使用循环方式创建约束可能比使用矩阵运算创建约束更耗时。

输入参数

全部折叠

约束维度的大小,指定为正整数。

  • constr = optimeq(N) 的大小为 N×1。

  • constr = optimeq(N1,N2) 的大小为 N1×N2

  • constr = optimeq(N1,N2,...,Nk) 的大小为 N1×N2×...×Nk

示例: 5

数据类型: double

用于索引的名称,指定为字符向量元胞数组或字符串向量。

注意

cstr 不能为诸如 "Tp" 之类的字符串标量,而必须为诸如 ["Tp" "ul"] 之类的向量。要指定单个名称,请使用 {'Tp'} 或等效的 cellstr("Tp")

示例: {'red','orange','green','blue'}

示例: ["red";"orange";"green";"blue"]

数据类型: string | cell

输出参量

全部折叠

等式,以空 OptimizationEquality 数组形式返回。使用 eq 初始化一个用于创建等式的循环。

例如:

x = optimvar('x',8);
eq = optimeq(4);
for k = 1:4
    eq(k) = 5*k*(x(2*k) - x(2*k-1)) == 10 - 2*k;
end

提示

  • 您可以使用 optimconstr 而不是 optimeq 为优化问题创建等式约束或为方程问题创建方程。

版本历史记录

在 R2019b 中推出