How is a conditional summation possible in Cplex?

2020-05-07 05:03发布

I want to sum all used resources among times in my model (it's rcpsp model) how can I do it in CPLEX? at first I wrote this:

forall(k in K)
  forall(t in 1..f[nAct])
    sum(i in I:f[i]-d[i]<=t-1 && t<=f[i]) r[i,k] <= aR[k]; 

(note: K is a range for resources, nAct is number of activities, f[i] is an array dvar and indicates finishing time of activity i, d[i] is duration of i,r[i,k] is required resource of k for activity i and aR[k] is available resources of k.)

The problem is that the cplex doesn't accept decision variable in sum's condition. I changed it to:

forall(k in K)
  forall(t in 1..f[nAct])
    sum(i in I) (f[i]-d[i]<=t-1 && t<=f[i])*r[i,k] <= aR[k]; 

But it didn't work. it made True constraints in Problem Browser after run(I don't know why) and it made this constraint ineffective.

Any Idea how to fix it?

2条回答
乱世女痞
2楼-- · 2020-05-07 05:29

You can use dexpr for manipulating decision variables. Here is an example from the same resource IBM Knowledge Center.

Without dexpr

dvar int x in 0..20;
dvar int y in 0..20;
dvar int d;
dvar int s;
maximize (d);
subject to {
  d==x-y;
  s==x+y;
  s<=15;
  s<=x-2*y;
  d>=2;
  d<=y+8;
  1<=d;
}

With dexpr

dvar int x in 0..20;
dvar int y in 0..20;
dexpr int d=x-y;
dexpr int s=x+y;
maximize (d);
subject to {
  s<=15;
  s<=x-2*y;
  d>=2;
  d<=y+8;
  1<=d;
}
查看更多
太酷不给撩
3楼-- · 2020-05-07 05:37

There are several ways to put your problem into an integer programming framework. There are books written on this subject. I think this is the simplest formulation.

I assume that in your problem, r[i,k] and d[i] are known and that the time horizon is broken into discrete time periods.

  • on[i,t] indicator that activity i is active at time t
  • start[i,t] indicator that activity i starts at the start of period t
  • end[i,t] indicator that activity i finishes at the end of period t

So in[i,t] replaces the condition f[i]-d[i]<=t-1 && t<=f[i])*r[i,k] Your constraint becomes

forall(k in K)
   forall(t in 1..f[nAct])
      sum(i in I : r[i,k] = 1) on[i,t] <= aR[k]; 

You also need to add constraints to enforce the definition of on, start and off.

   forall(t in 2..f[nAct])
      forall(i in I)
         on[i,t-1] - on[i,t] = end[i,t-1] - start[i,t];

   forall(i in I)
      on[i,0] = start[i,0];

   forall(i in I)
      sum(t in 1..f[nAct]) start[i,t] = 1;
   forall(i in I)
      sum(t in 1..f[nAct]) end[i,t] = 1;
   forall(i in I)
      sum(t in 1..f[nAct]) on[i,t] = d[i];
查看更多
登录 后发表回答