<p>错误是因为您试图指定非代数约束。从概念上讲,以下将定义逻辑析取:</p>
<pre><code>expr == model.aff[f1,f2] | expr == 0
</code></pre>
<p>对于具体的语法问题:</p>
<ul>
<li><code>|</code>是二进制或。它比关系运算符绑定得更紧,因此不会执行您想要的操作。在</li>
<li><code>||</code>不是有效的Python语法</li>
<li>从概念上讲,您需要的是<em>逻辑或</em>,这在Python中是用<code>or</code>实现的。这将是一个很好的语法支持-但是,它目前不支持Pyomo。在</li>
</ul>
<p>您有两个选项来指定这样的约束:要么(1)使用<code>pyomo.gdp</code>扩展将其指定为析取,然后利用<code>pyomo.gdp</code>中的转换将析取程序松弛回MIP,或者(2)使用例如Big-M松弛显式地松弛析取。要执行前者,需要定义两个析取,然后定义析取:</p>
^{pr2}$
<p>然后需要调用转换将析取转换回代数约束。注意:转换要么需要Pyomo变量都有上下限,要么需要通过模型上的<code>BigM</code>后缀指定有效的“Big-M”值。您可以:</p>
<ul>
<li>在Pyomo命令行上指定转换(例如,<code> transform=gdp.bigm</code>或{<cd8>})</li>
<li><p>在<code>BuildAction</code>中指定转换</p>
<pre><code>def xfrm(m):
TransformationFactory('gdp.bigm').apply_to(m)
model.xfrm = BuildAction(rule=xfrm)
</code></pre></li>
<li><p>作为自定义驱动程序脚本的一部分显式调用转换。</p></li>
</ul>
<p>替代<code>pyomo.gdp</code>的方法是自己显式地实现放松。您需要添加一个二进制变量(我们称之为<code>y</code>),它指示析取的哪一边必须为真,然后使用该二进制变量显式地放宽两个析取。从概念上讲你会转向</p>
<pre><code>expr == model.aff[f1,f2] | expr == 0
</code></pre>
<p>进入</p>
<pre><code>expr - model.aff[f1.f2] <= M1 * y
model.aff[f1.f2] - expr <= M2 * y
expr <= M3 * (1-y)
expr >- M4 * (1-y)
</code></pre>
<p>请注意,根据<code>expr</code>和<code>aff</code>的界限,其中一些约束可能是多余的。另外,四个“大M”(大常量)可能不一定要不同,尽管如果您能确定每个M的最小有效值,那么问题将得到更好的解决</p>