【问题标题】:Finding Maximum taking too much time in ILP, why?在 ILP 中找到最大值花费了太多时间,为什么?
【发布时间】:2011-11-08 12:11:31
【问题描述】:

简而言之,我们现在正在尝试将 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];

    }

};

【问题讨论】:

  • 它很慢并不奇怪,因为这不是一个线性规划问题(而是一个 整数 线性规划问题)而且你有 50 个变量,而不是 20 个。什么是您要解决的问题吗?
  • 所以你需要将玩家分配到游戏中,对吧?你没有在 ILP 问题中限制游戏中的玩家数量,可以吗?

标签: integer mathematical-optimization linear-programming cplex integer-programming


【解决方案1】:

像这样的表达

x1 * x2

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

bonus <= x1
bonus <= x2

或在负系数的情况下

penalty >= x1 + x2 - 1

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

dvar float+ penalty;
dvar float+ bonus;

对所有二次表达式执行此操作,您的问题将变成线性整数问题并且求解速度更快。

【讨论】:

  • @hhh:那是因为这个答案有点错误。因为它在您的目标函数中具有负系数,所以它不是奖励,而是您寻求最小化惩罚。约束也发生了变化,我建议penalty &gt;= 0penalty &gt;= x1[y] + x3[y] - 2 + 2*x2[y]
  • @DavidNehme:......但不正确。需要根据处罚情况调整界限。想象一下当 x2 为 0(在这种情况下您需要消除其他约束)或 1(您想要相反的情况)时会发生什么。对于奖金情况,它是这样工作的,对于惩罚,它不是。
  • @jpalecek 再次感谢。现在这应该可以了。在惩罚情况下,如果 x1 或 x2 为 0,则惩罚可以为零,但如果两者都不为零,则惩罚必须至少为 1,并且目标应将其推至 1。在奖励情况下,奖励必须为 0除非 x1 和 x2 都是 1。如果它们都是 1,则目标应将其推至 1。
  • @hhh 变量的下限都应该是 0。所以隐含地应该有一个惩罚 >= 0。您可以通过将 dvar 声明为 float+ 来实现这一点。
  • 他的优化函数是一个线性函数,所以它总是凹的(和凸的)。
猜你喜欢
  • 2020-07-17
  • 2017-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-15
  • 2020-07-23
  • 2013-07-11
相关资源
最近更新 更多