如何在灵活的作业车间中编写操作的后续操作在同一台机器上完成的代码?
How to code in a flexible job shop that the successor of an operation is done on the same machine?
在模型中,我们必须为每个作业执行 3 个操作。我希望如果操作 1 在 OR
类型的机器中处理,操作 2 和操作 3 也必须在同一台 OR
类型的机器上执行,如果它们在类型的机器中执行OR
.
using CP;
int nbJobs = ...;
int nbMchs = ...;
int nbOR=...; //special machine type OR
int nbIR=...; //special machine type IR
int nbSR=...; //special machine type SR
range Jobs = 1..nbJobs;
range Mchs = 1..nbMchs;
range OR =1..nbOR;
range IR = nbOR+1..(nbOR+nbIR);
range SR=(nbOR+nbIR+1)..(nbOR+nbIR+nbSR);
tuple Operation {
int id; // Operation id
int jobId; // Job id
int pos; // Position in the Job
};
tuple Mode {
int opId; // Operation id
int mch; // Machine
int pt; // Processing time
};
{Operation} Ops=...;
{Mode} Modes=...;
execute {
cp.param.FailLimit = 10000;
}
// Position of last operation of job j
int jlast[j in Jobs] = max(o in Ops: o.jobId==j) o.pos;
dvar interval ops[Ops];
dvar interval modes[md in Modes] optional size md.pt;
dvar sequence mchs[m in Mchs] in
all(md in Modes: md.mch == m) modes[md];
minimize
max(j in Jobs, o in Ops: o.pos==jlast[j]) endOf(ops[o]);
subject to {
forall (j in Jobs, o1 in Ops, o2 in Ops:
o1.jobId==j && o2.jobId==j && o1.pos==2 && o2.pos==3)
endAtStart(ops[o1],ops[o2]);
forall (j in Jobs, o3 in Ops, o4 in Ops, o5 in Ops:
o3.jobId==j && o4.jobId==j && o5.jobId==j &&
o3.pos==1 && o4.pos==2 && o5.pos==3) {
(endOf(ops[o3]) != startOf(ops[o4])) =>
(endOf(ops[o3]) == startOf(ops[o5]));
(endOf(ops[o3]) != startOf(ops[o5])) =>
(endOf(ops[o3]) == startOf(ops[o4]));
}
// How to code the following in a correct way?
// From here...
forall (j in Jobs, k in OR, l in OR, m1 in Modes, m2 in Modes:
m1.opId == 1+(j-1)*3 && m2.opId == j*3) {
if (m1.mch == k && m2.mch == l){
m1.mch == m2.mch;
}
}
forall (j in Jobs, k in OR, l in OR, m1 in Modes, m2 in Modes:
m1.opId == 2+(j-1)*3 && m2.opId == j*3 &&
m1.mch == k && m2.mch == l) {
if (m1.mch == k && m2.mch == l) {
m1.mch == m2.mch;
}
}
forall (j in Jobs, k in OR, l in OR, m in OR, m1 in Modes,
m2 in Modes, m3 in Modes:
m1.opId == 1+(j-1)*3 && m2.opId == 2+(j-1)*3 &&
m3.opId == j*3 && m1.mch == k && m2.mch == l && m3.mch == m) {
if (m1.mch == k && m2.mch == l && m3.mch == m) {
m1.mch == m2.mch == m3.mch;
}
}
// ... to here
forall (o in Ops)
alternative(ops[o], all(md in Modes: md.opId==o.id) modes[md]);
forall (m in Mchs)
noOverlap(mchs[m]);
}
我认为您需要做的就是 post 存在区间变量之间的一些二元约束。类似于: presenceOf(mode1) => !presenceOf(mode2)
其中 mode1
是操作 1 在类型 OR
的机器上的分配, mode2
是操作 2 在类型 [=12] 的机器上的分配=] 与 mode1 不同。这就是您想要的:禁止在 OR
类型的机器上分配操作 2(与操作 3 相同),操作 1.
除外。
在模型中,我们必须为每个作业执行 3 个操作。我希望如果操作 1 在 OR
类型的机器中处理,操作 2 和操作 3 也必须在同一台 OR
类型的机器上执行,如果它们在类型的机器中执行OR
.
using CP;
int nbJobs = ...;
int nbMchs = ...;
int nbOR=...; //special machine type OR
int nbIR=...; //special machine type IR
int nbSR=...; //special machine type SR
range Jobs = 1..nbJobs;
range Mchs = 1..nbMchs;
range OR =1..nbOR;
range IR = nbOR+1..(nbOR+nbIR);
range SR=(nbOR+nbIR+1)..(nbOR+nbIR+nbSR);
tuple Operation {
int id; // Operation id
int jobId; // Job id
int pos; // Position in the Job
};
tuple Mode {
int opId; // Operation id
int mch; // Machine
int pt; // Processing time
};
{Operation} Ops=...;
{Mode} Modes=...;
execute {
cp.param.FailLimit = 10000;
}
// Position of last operation of job j
int jlast[j in Jobs] = max(o in Ops: o.jobId==j) o.pos;
dvar interval ops[Ops];
dvar interval modes[md in Modes] optional size md.pt;
dvar sequence mchs[m in Mchs] in
all(md in Modes: md.mch == m) modes[md];
minimize
max(j in Jobs, o in Ops: o.pos==jlast[j]) endOf(ops[o]);
subject to {
forall (j in Jobs, o1 in Ops, o2 in Ops:
o1.jobId==j && o2.jobId==j && o1.pos==2 && o2.pos==3)
endAtStart(ops[o1],ops[o2]);
forall (j in Jobs, o3 in Ops, o4 in Ops, o5 in Ops:
o3.jobId==j && o4.jobId==j && o5.jobId==j &&
o3.pos==1 && o4.pos==2 && o5.pos==3) {
(endOf(ops[o3]) != startOf(ops[o4])) =>
(endOf(ops[o3]) == startOf(ops[o5]));
(endOf(ops[o3]) != startOf(ops[o5])) =>
(endOf(ops[o3]) == startOf(ops[o4]));
}
// How to code the following in a correct way?
// From here...
forall (j in Jobs, k in OR, l in OR, m1 in Modes, m2 in Modes:
m1.opId == 1+(j-1)*3 && m2.opId == j*3) {
if (m1.mch == k && m2.mch == l){
m1.mch == m2.mch;
}
}
forall (j in Jobs, k in OR, l in OR, m1 in Modes, m2 in Modes:
m1.opId == 2+(j-1)*3 && m2.opId == j*3 &&
m1.mch == k && m2.mch == l) {
if (m1.mch == k && m2.mch == l) {
m1.mch == m2.mch;
}
}
forall (j in Jobs, k in OR, l in OR, m in OR, m1 in Modes,
m2 in Modes, m3 in Modes:
m1.opId == 1+(j-1)*3 && m2.opId == 2+(j-1)*3 &&
m3.opId == j*3 && m1.mch == k && m2.mch == l && m3.mch == m) {
if (m1.mch == k && m2.mch == l && m3.mch == m) {
m1.mch == m2.mch == m3.mch;
}
}
// ... to here
forall (o in Ops)
alternative(ops[o], all(md in Modes: md.opId==o.id) modes[md]);
forall (m in Mchs)
noOverlap(mchs[m]);
}
我认为您需要做的就是 post 存在区间变量之间的一些二元约束。类似于: presenceOf(mode1) => !presenceOf(mode2)
其中 mode1
是操作 1 在类型 OR
的机器上的分配, mode2
是操作 2 在类型 [=12] 的机器上的分配=] 与 mode1 不同。这就是您想要的:禁止在 OR
类型的机器上分配操作 2(与操作 3 相同),操作 1.