0

简而言之,我们现在正在尝试将 IQP 更改为 ILP。旧的实现大约需要 2 天才能完成,现在使用线性工具——它应该会加快速度。基本上问题是最大化(大约 50 个二进制变量):

$$\sum_{g=1}^{5}sum_{p=1}^{10} ( S[p]x[g][p]-疲倦[g][p]-睡眠[g][p ])$$

更新

我认为 David 走在正确的轨道上,但是当我尝试使用奖励变量最大化表达式时,它们每次都为零,为什么?在一些代码下面,分数可能像S[1..10]=[1,2,3,4,5,6,7,8,9,10];.

int S[1..10] = ...; // Scores per player =s

dvar int x1[1..10] in 0..1;
dvar int x2[1..10] in 0..1;
dvar int x3[1..10] in 0..1;
dvar int x4[1..10] in 0..1;
dvar int x5[1..10] in 0..1;

dvar int b1[1..10] in 0..100;
dvar int b2[1..10] in 0..100;


//ERR: the values of b1 and b2 should be maximized...
// WHY not here so?

maximize 
sum(i in 1..10) 
(
S[i] *
    (
    (x1[i]+x2[i]+x3[i]+x4[i]+x5[i]) 
    - 1/10 * ( b1 +b2) 
    )
);

subject to 
{
    //We must play in 5 games.
    //It means that there are 5 players in each game.
    sum(i in 1..10) x1[i]==5;
    sum(i in 1..10) x2[i]==5;
    sum(i in 1..10) x3[i]==5;
    sum(i in 1..10) x4[i]==5;
    sum(i in 1..10) x5[i]==5;

    // IQP problem into ILP -problem

    forall (i in 1..10)
    {
        //ERROR HERE!
        //it returns zero for b1 and b2, they should be maximized... 
        //I am trying to use the tip by David here, see his answer.

        // EQ1: x2[i] * (x1[i]+x3[i])
        b1 <= 2*x2[i];
        b1 <= x1[i]+x3[i];

        // EQ2: x4[i] * (x3[i]+x5[i]+x1[i])
        b2 <= 3*x4[i];
        b2 <= x3[i]+x5[i]+x1[i];

    }

};
4

1 回答 1

1

像这样的表达

x1 * x2

如果 x1, x2 都是变量,则为二次型。您有一个 50 变量整数二次规划问题。此外,您的目标函数不是凹的,因此 CPLEX 将特别困难。
但是,由于您拥有所有 0-1 变量,您可以通过添加一个附加变量将其转换为线性问题,例如对具有正系数的表达式的奖励和对具有负系数的表达式的惩罚,将它们放在目标函数中而不是二次项并添加以下约束

bonus <= x1
bonus <= x2

或在负系数的情况下

penalty >= x1 + x2 - 1

由于您正在最大化,cplex 将在最佳解决方案中强制奖励惩罚正确值。惩罚和奖励变量应声明为非负数

dvar float+ penalty;
dvar float+ bonus;

对所有二次表达式执行此操作,您的问题将成为线性整数问题并更快地解决。

于 2011-11-08T16:44:31.983 回答