具有非线性 objective(除法)的线性约束 MIP 的 CPLEX 与约束规划解决方案
CPLEX vs Constraint Programming Solution for a linearly constrained MIP with a nonlinear objective(division)
我正在尝试求解具有非线性 objective 的 MIP,例如 sum(a(i)*x(i))/sum(b(i)*x(i))
,其中 a(i) 和 b(i) 是参数。由于 CPLEX 无法提取此表达式,我尝试使用 CP。
但是,我有约束说明决策变量 x(i) 应该是 2.5 的乘数,因此是一个浮点数。由于 CP 无法处理浮点数,我将 x 设置为整数,并隐含为 25 的乘数。在所有其他约束和表达式中,我将 x 除以 10,因此计算保持不变。
首先,我求解了乘数为5的模型,得到了一个间隙非常小的解,很好。当我将乘数更改为 25 时,模型无法在 2 小时内终止(卡在 90% 的差距)。我相信这是由于缩放而发生的,但仍然无法弄清楚,因为我不熟悉 CP 算法。
我仍在努力使目标线性化,但是,对 CPLEX 和 CP 引擎解决方案的任何建议都将受到高度赞赏。
提前致谢。
您是否尝试过将等式变为不等式以提供一些灵活性?
比如
using CP;
int scale=1000;
dvar int scalex in 0..2000;
dexpr float x=scalex/scale;
subject to
{
x*x==2;
}
没有给出解决方案而
using CP;
float epsilon=0.001;
int scale=1000;
dvar int scalex in 0..2000;
dexpr float x=scalex/scale;
subject to
{
abs(x*x-2)<=epsilon;
}
给予
x=1.414
和
using CP;
{int} hm=asSet(1..4);
float epsilon=0.001;
dvar int scalex[1..card(hm)] in 0..20000;
int scale=10000;
dexpr float A[ i in 1..card(hm)]=scalex[i]/scale;
subject to
{
forall(i in 1..card(hm))abs(A[i]*A[i]-2)<=epsilon;
}
也很好用
谢谢@Alex Fleischer。我尝试了你的建议。我的决策变量的索引是一个元组,因此我编写了如下代码:
dvar int scalex[1..card(hm)] in 0..10000;
int scale=100;
dexpr float A[1..card(hm)]=[];
int max_range=card(hm);
execute{
for (var i=1;i<=max_range;i++){
A[i]==scalex[i]/scale;
}
}
我收到脚本运行时错误:无法转换为数字,“[a IloNumVar]”错误。我怎样才能解决这个问题?
谢谢。
我正在尝试求解具有非线性 objective 的 MIP,例如 sum(a(i)*x(i))/sum(b(i)*x(i))
,其中 a(i) 和 b(i) 是参数。由于 CPLEX 无法提取此表达式,我尝试使用 CP。
但是,我有约束说明决策变量 x(i) 应该是 2.5 的乘数,因此是一个浮点数。由于 CP 无法处理浮点数,我将 x 设置为整数,并隐含为 25 的乘数。在所有其他约束和表达式中,我将 x 除以 10,因此计算保持不变。
首先,我求解了乘数为5的模型,得到了一个间隙非常小的解,很好。当我将乘数更改为 25 时,模型无法在 2 小时内终止(卡在 90% 的差距)。我相信这是由于缩放而发生的,但仍然无法弄清楚,因为我不熟悉 CP 算法。
我仍在努力使目标线性化,但是,对 CPLEX 和 CP 引擎解决方案的任何建议都将受到高度赞赏。 提前致谢。
您是否尝试过将等式变为不等式以提供一些灵活性?
比如
using CP;
int scale=1000;
dvar int scalex in 0..2000;
dexpr float x=scalex/scale;
subject to
{
x*x==2;
}
没有给出解决方案而
using CP;
float epsilon=0.001;
int scale=1000;
dvar int scalex in 0..2000;
dexpr float x=scalex/scale;
subject to
{
abs(x*x-2)<=epsilon;
}
给予
x=1.414
和
using CP;
{int} hm=asSet(1..4);
float epsilon=0.001;
dvar int scalex[1..card(hm)] in 0..20000;
int scale=10000;
dexpr float A[ i in 1..card(hm)]=scalex[i]/scale;
subject to
{
forall(i in 1..card(hm))abs(A[i]*A[i]-2)<=epsilon;
}
也很好用
谢谢@Alex Fleischer。我尝试了你的建议。我的决策变量的索引是一个元组,因此我编写了如下代码:
dvar int scalex[1..card(hm)] in 0..10000;
int scale=100;
dexpr float A[1..card(hm)]=[];
int max_range=card(hm);
execute{
for (var i=1;i<=max_range;i++){
A[i]==scalex[i]/scale;
}
}
我收到脚本运行时错误:无法转换为数字,“[a IloNumVar]”错误。我怎样才能解决这个问题? 谢谢。