0

嗨,我正在尝试制作一个具有目标函数的模型,以最大限度地降低模式 2 使用成本(使用外部资源的模式)。当我想限制总时间<=21时,我感到困惑,结果没有价值,但是当我设置时间<=50时,结果出来了,虽然我运行模型时的结果只花费了25时间。

tuple Task {
  key int id;
  {int} succs;
  int RelDate;
}
{Task} Tasks = ...;

tuple Mode {
  key int taskId;
  key int id;
  int pt;
  int costprod;
  int dmdIntRes [IntRes];
  int dmdExtRes [ExtRes]; 
  int ExtCost;
}
{Mode} Modes = ...;

dvar interval Taskss [t in Tasks] in t.RelDate..(maxint div 2)-1; 
dvar interval mode[m in Modes] optional  size m.pt;
dexpr int totaltime = sum(m in Modes) presenceOf(mode[m]) * ( m.pt); //boolean expression
//dexpr int totalExtCost = sum(m in Modes) presenceOf(mode[m])* (m.ExtCost * m.pt);


cumulFunction IntResUsage[r in IntRes] = 
  sum (m in Modes: m.dmdIntRes[r]>0) pulse(mode[m], m.dmdIntRes[r]);
  
cumulFunction ExtResUsage[r in ExtRes] = 
  sum (m in Modes: m.dmdExtRes[r]>0) pulse(mode[m], m.dmdExtRes[r]);
 
execute {
        cp.param.FailLimit = 10000;
}
 
minimize sum(m in Modes) (m.ExtCost * m.pt) * maxl (presenceOf(mode[m]));
//minimize max(t in Tasks) endOf(Taskss[t]);
  
subject to {
 //Alternative mode of resource productivity in Cost's unit
  forall (t in Tasks, m in Modes) {
 // if(m.costprod *m.pt == 0 && 0 <= 559717712) presenceOf(mode[first(Modes)]);
  
    alternative(Taskss[t], all(m in Modes: m.taskId==t.id) mode[m]);
}
forall (t in Tasks, m in Modes)
  (sum(t in Tasks)sum(m in Modes) m.costprod * m.pt <= 285740966 in 0..NbDays-14) != presenceOf(mode[first(Modes)]);
  
//External resource's budget limitation
forall ( t in Tasks, m in Modes )
  totaltime <= 50;
//forall ( m in Modes )
  //totalExtCost <= 30000000;
 //Resource Usage
  forall (r in IntRes)
    IntResUsage[r] <= CapIntRes[r];
  forall (r in ExtRes)
    ExtResUsage[r] <= CapExtRes[r];    
4

2 回答 2

0

您能否简化您的模型以说明您的问题?我在模型中看不到任何值 50 或 25。

还:

  • 我不明白你为什么在这里使用“最大值”:minimize sum(m in Modes) (m.ExtCost * m.pt) * maxl (presenceOf(mode[m]));

  • 我不明白你为什么为每个任务和每个模式发布这个约束(!)。它独立于任务和模式: forall ( t in Tasks, m in Modes ) { totaltime <= 100; }

顺便说一句,出于可读性的原因,您还可以将表达式:“presenceOf(mode[m]) * (m.pt)”改写为“sizeOf(mode[m])”。如果模型持续时间是一个常数,从性能的角度来看,两个公式应该或多或少相似,但如果持续时间是一个决策变量,那么具有“sizeOf(model[m])”的公式肯定会更好。

于 2021-04-19T08:53:40.633 回答
0

对于'min',你不应该使用min或max,因为你正在处理一个单例,你直接使用presenceOf。

所以我会简化公式如下:

dvar interval Tasks [t in Tasks] in t.RelDate..(maxint div 2)-1; 
dvar interval mode[m in Modes] optional  size m.pt;
dexpr int totaltime    = sum(m in Modes) sizeOf(mode[m]); 
dexpr int totalExtCost = sum(m in Modes) (m.ExtCost*sizeOf(mode[m]));

cumulFunction IntResUsage[r in IntRes] = 
  sum (m in Modes: m.dmdIntRes[r]>0) pulse(mode[m], m.dmdIntRes[r]);
  
cumulFunction ExtResUsage[r in ExtRes] = 
  sum (m in Modes: m.dmdExtRes[r]>0) pulse(mode[m], m.dmdExtRes[r]);
 
execute {
  cp.param.FailLimit = 10000;
}
 
minimize totalExtCost;
  
subject to {
 // Alternative mode of resource productivity in Cost's unit
  forall (t in Tasks)
    alternative(Tasks[t], all(m in Modes: m.taskId==t.id) mode[m]);
  
  // I have no hint what the constraints below are supposed to do !
  // forall (t in Tasks, m in Modes)
  //  (sum(t in Tasks) sum(m in Modes) m.costprod * m.pt <= 285740966 in 0..NbDays-14) != presenceOf(mode[first(Modes)]);
  
  // External resource's budget limitation
  totaltime <= 50;
  // totalExtCost <= 30000000;
  // Resource Usage
  forall (r in IntRes)
    IntResUsage[r] <= CapIntRes[r];
  forall (r in ExtRes)
    ExtResUsage[r] <= CapExtRes[r]; 
} 

然后我仍然不明白将“totalTime”限制为 50 的问题。它确实不会阻止计算“totalTime=25”的解决方案,因为 25<=50。

其实我不明白你的问题。您似乎说“totalTime <= 21”的问题是不可行的,并且当您发布约束“totalTime <= 50”时,它会找到“totalTime = 25”的解决方案。我看不出问题出在哪里......

于 2021-04-21T10:48:52.400 回答