The only difference between the classical HFS and the classical Flow-shop scheduling problem is that there are several parallel machines (say C[s]) for each stage s instead of a single one. So with CP Optimizer, you only need to use a cumul function instead of a no-overlap constraints. In OPL, it looks like:
using CP;
int N = ...; // Number of jobs
int M = ...; // Number of operations per jobs
int D[i in 1..N][s in 1..M] = ...; // Processing time of operation s of job i
int C[s in 1..M] = ...; // Number of machines for stage s (in 1..M)
dvar interval op[i in 1..N][s in 1..M] size D[i][s];
minimize max(i in 1..N) endOf(op[i][M]);
subject to {
forall(i in 1..N, s in 2..M) {
endBeforeStart(op[i][s-1], op[i][s]);
}
forall(s in 1..M) {
sum(i in 1..N) pulse(op[i][s],1) <= C[s];
}
}
------------------------------
Philippe Laborie
------------------------------