如何在GAMS(MIP)中正确使用round函数处理正变量arr?
在GAMS MIP模型中实现变量的四舍五入(保留两位小数)
GAMS的round()函数仅支持参数(Parameter),无法直接作用于决策变量(如你的arr(i,j)),因为MIP求解时变量值未知,这类非线性非凸函数无法直接纳入约束。要实现变量的四舍五入逻辑,需要通过线性化+整数辅助变量来转化约束,具体步骤如下:
1. 声明变量
首先补充声明辅助整数变量,用于承载arr(i,j)*100四舍五入后的整数值:
Positive Variable arr(i,j); // 你的原始正变量 Variable w(i,j); // 四舍五入后的结果变量 Integer Variable k(i,j); // 辅助整数变量:对应arr*100四舍五入后的整数
2. 设置辅助变量的上下界
为了提升求解效率,需要给k(i,j)设置合理的上下界(基于arr(i,j)的已知范围):
// 假设你已知arr的下界lb_arr和上界ub_arr(需替换为你的实际参数或数值) k.lo(i,j) = floor(lb_arr(i,j)*100); k.up(i,j) = ceil(ub_arr(i,j)*100);
如果arr的范围不确定,可以根据模型场景设置一个足够覆盖可能取值的范围(比如k.lo(i,j)=0,k.up(i,j)=10000,具体看你的业务需求)。
3. 编写线性化约束
通过两个约束实现四舍五入逻辑,再关联w(i,j)和k(i,j):
// 约束1:arr*100 - 0.5 ≤ k ≤ arr*100 + 0.5 eq_round_low(i,j).. arr(i,j)*100 - 0.5 =l= k(i,j); eq_round_high(i,j).. k(i,j) =l= arr(i,j)*100 + 0.5; // 约束2:w是k除以100的结果(保留两位小数) eq_w_def(i,j).. w(i,j) =e= k(i,j)/100;
逻辑说明
因为k(i,j)是整数,上述约束会强制k取arr(i,j)*100四舍五入后的整数:
- 当
arr(i,j)*100的小数部分≥0.5时,k会取到大于等于arr*100的最小整数(即ceil值) - 当小数部分<0.5时,
k会取到小于等于arr*100的最大整数(即floor值)
最终w(i,j)就是arr(i,j)四舍五入保留两位小数的结果,完全替代你原来的eq1约束。
内容的提问来源于stack exchange,提问作者Kosovi
相关产品推荐
相关产品推荐

