当前位置: 首页 > 知识库问答 >
问题:

Choco求解器中的建模约束

骆文华
2023-03-14

我正在和choco solver一起解决一些任务调度问题。

我有几个工作和可能的时间段(可以执行一个工作)。有一些限制,比如:

  • 每个插槽只能有一个作业(C.1)
  • 作业需要一定的时间t,并且插槽有一个可用的持续时间d。作业必须符合可用的持续时间:t

所以,基本上用一些基本/伪类表示:

class Job {
    int id;
    int time;
}

class Slot {
    int id;
    int duration;
}

目前,我可以为每个作业分配一个插槽,假设作业id和插槽是连续编号的

int jobCount = 5;  // 5 jobs with ids from 0 to 4
int slotCount= 20; // 20 jobs with ids from 0 to 19
Model model = new Model("Example");
IntVar[] jobs = model.intVarArray("Job", jobCount, 0, slotCount, false);
// all jobs must have different slots (C.1)
model.allDifferent(jobs).post();

// solving - details omitted, because I think it is not relevant...
Solution solution = model.getSolver().findSolution();
// assign the jobs to the slots like (pseudo-code): 
// foreach i in jobs.length do 
//     job = getJobForId(i);
//     getSlotForId(jobs[i]).setJob(job);

这是工作的预期。但现在我想对其他约束条件进行建模。但我正在研究如何将工作/时段与时间/持续时间结合起来,因为时间和持续时间是一个因变量。

在第一步中,我为时间和持续时间建模了两个附加变量:

int[] slotDurations = {10, 20, 10, 40, ..., 20} // 20 durations (d)
IntVar[] durations = model.intVarArray("Time", slotCount, slotDurations);

int[] jobTimes = {5, 16, 30, 2, 17} // 5 times (t)
IntVar[] times = model.intVarArray("Time", jobCount , jobTimes);

现在,我需要表达一个约束,即时间应该适合于持续时间(C.2)。

是否可以定义这样的约束(不工作/有效的伪代码):

for(int i=0;i<jobCount;i++){
    times[i].le(durations[jobs[i]]).post();
}

还是模型完全错了?!

也许有人有解决办法或想法?!


共有1个答案

洪成济
2023-03-14

如果您说每个插槽只能有一个作业,那么选择slot作为IntVarArray是很自然的,如下所示:

 IntVar[] slots = model.intVarArray("Slot", slotCount, 0, jobCount, false);
 int[] jobTimes = {0, 5, 16, 30, 2, 17};  //6(!) items; see explanation below.
 int[] slotDurations = {10, 20, 10, 40, ..., 20}; //20 items

这里,slot指向jobTime中的项目。如果你的职位比工作多,那么要注意allDifferent约束:你最终将没有解决方案。在这种情况下,请使用修改后的约束,例如AllDifferentitexcept0,以便解算器可以选择有效项。然后,jobTimes[0]必须是一个满足所有时隙的条目(例如,0)。

那么你就很接近了,你所需要做的就是引入一个中间的IntVar变量,比如说shaoTime,它以给出的顺序表示时间,就像这样:

IntVar[] shadowTime = model.intVarArray("shadowTime", slotDurations.length, 0, jobTimes.length, false); //has the jobTimes in the order indicated by slots.
for(int i=0;i<slotCount;i++){
    model.element(shadowTime[i], jobTimes, slots[i]).post();
    //this is similar to what you wanted to achieve with 'durations[jobs[i]]' in your code
}

然后可以在同一循环中添加约束C.2:

//within in the above loop:
{    
    ...
    model.arithm(shadowTime[i], "<", slotDurations[i]).post();
}

然后可以枚举手册中描述的所有解决方案(而(solver.solver(){...})。

 类似资料:
  • 我正在使用choco solver库生成一组谜题。我需要运行解算器,检查有多少个解,如果有多个解,添加一个额外的约束。重复这一步会给我一组约束(线索),它们有一个独特的解决方案。 然而,一旦我运行model.get求解器(findAllSolutions()),任何额外的检查都会返回零解。 我猜我需要以某种方式重置模型求解器,但找不到实现这一点的方法——如果必须的话,我宁愿不生成新模型并重新创建现

  • 我在建模一个问题并用Java中的Choco solver解决它时遇到了问题,我一开始对约束编程不太熟悉,但我的任务是为会议制作一个座位应用程序,其中: 每张桌子必须至少有6个人,而且总是有足够的桌子 人们应该与邻居坐在一起,以最大限度地实现共同利益 在之前的几天里,我们希望尽量减少人们和他们之前坐过的人一起坐在桌子上 人们要么属于A类,要么属于B类,我们希望在每张桌子上尽量减少A类的出现 到目前为

  • 我正在使用choco解算器4.0.5(最新的,直到现在)和网络上的几个例子,除了不考虑我的需要,使用旧版本。 我绝对是choco解算器的乞丐,经过在网络上非常努力的搜索,我来这里寻求帮助。 我有以下变量域: 一年中的日子: 1(代表1-jan),35(代表4-feb),58, 56, 125, 142, 168, 225, 360, 364......人的身份:789111, 789555, 78

  • Choco 将MVC带到了客户端!一个Choco应用仅有一个HTML页面组成,所有的交互有JS来完成。你的UI仅使用HTML 和CSS。

  • 我有一个问题要解决,如图所示。我已经尝试了下面给出的代码 但它给了我这个错误 runfile('C:/Users/aliya/.spyder-py3/temp.py',wdir='C:/Users/aliya/.spyder-py3')回溯(最后一次最近调用): 文件“”,第1行,在runfile('C:/Users/aliya/.spyder-py3/temp.py',wdir='C:/User

  • Choco-solver 是一个用于约束满足问题(Constraint Satisfaction Problems)和约束规划(Constraint Programming)的 Java 库。 它建立在一个可回溯结构的,基于事件的传播机制上。   Choco-solver 随附: 各种类型的变量(整数、布尔值、集合、图和实数) 各种最新的约束条件(所有不同、计数、n 值等) 各种搜索策略,从基本的