假设我有一个
Dict
,我在其中存储具有我想要进行的优化的配置。所以像下面这样:
portfolio = Model(Ipopt.Optimizer)
@variable(portfolio, x[1:5])
max_ = 10.0
min_ = [1,2,3,4,5]
constraints = Dict{String, String}()
constraints["max_constraint"] = "x .<= max_"
constraints["min_constraint"] = "x >= min_"
我想循环遍历约束中的所有内容,并将其作为约束放入模型中,其名称与字典中键的名称相同。所以基本上我想做:
for k in keys(constraints)
@constraint(portfolio, k, constraints[k])
end
这对任何一个约束都不起作用,但我可以复制粘贴
Dict
的内容以使其工作:
@constraint(portfolio, max_constraint, x .<= max_)
@constraint(portfolio, min_constraint, x >= min_)
那么如何直接使用
Dict
中的字符串添加约束呢?此外,有没有一种方法可以做到这一点,如果 max_
和 min_
超出范围(例如,在返回模型的函数调用中添加额外的约束)。
为了从描述约束的字符串得到表达式,需要有一个解析阶段。解析后,需要调用添加约束表达式的宏/函数。因此,以下内容在测试中对我有用:
for (name, con) in constraints
e = Meta.parse("@constraint(portfolio, $name, $con)")
@eval $e
end
无论如何,JuMP 允许以编程方式产生约束,这可能是值得探索的。
最后,如果描述约束的字符串来自外部文件或源,则使用
@eval
会带来风险(安全性等),您可能希望以某种方式控制解析和评估的字符串。