31 de agosto de 2012
24 de agosto de 2012
Encontro 10 - Permutation Flowshop Scheduling
Roteiro do Encontro
- Reorganizar o foco do grupo
- Escolher um problema da 6ª Maratona de Programação Paralela ( 2011 )
- Paralelizar
- Escolher um problema da 6ª Maratona de Programação Paralela ( 2011 )
- Paralelizar
Permutation Flowshop Scheduling
Permutation Flowshop Scheduling (PFS) have as goal the deployment of an optimal schedule for N jobs on M machines. It is a NP-hard problem: N! possibilities. Each ni job (1 ≤ i ≤ N) must be schedule, in any time, on a mj machine (1 ≤ j ≤ M). That is because a job has M operations and its jth operation must be processed in mj machine. So, one job can start on mj machine if its mj-1 operation is completed and mj machine is free. Each operation has its own time (tj). For PFS the operating sequence of the jobs are the same on every machine. That is the input job queue must be the same for all machines. Solving the PFS problem means determining the permutation which gives the smallest makespan value to schedule N jobs on M machine.
O algoritmo inicial utilizado para esse problema é o seguinte:
int main(int argc, char* argv[]) {
int i, j;
FILE *in, *out;
int makespan, min_makespan;
int seq[101];
int cont_n;
in = fopen("pfs.in", "r");
out = fopen("pfs.out", "w");
while (1) {
memset(tasks, 0, sizeof(tasks));
fscanf(in, "%d%d", &n, &m);
if (n == 0 || m == 0)
break;
for (i = 0; i < n; i++) {
for (j = 0; j < m; j++)
fscanf(in, "%d", &tasks[i].i[j]);
}
min_makespan = 0;
// generate first sequence
for (i = 0; i < n; i++)
seq[i] = i;
do {
for (i = 0; i < m; i++)
machines[i] = -1;
makespan = 0;
for (i = 0; i < n; i++) {
memset(tasks[i].exec, 0, sizeof(tasks[i].exec));
tasks[i].maq = 0;
}
cont_n = 0;
// simulate permutation flow job schedule
while (cont_n < n) {
// schedule each task on a machine
for (i = cont_n; i < n; i++) {
if (machines[tasks[seq[i]].maq] < 0) {
machines[tasks[seq[i]].maq] = seq[i];
}
}
//run task
for (i = 0; i < m; i++) {
if (machines[i] >= 0) {
tasks[machines[i]].exec[i]++;
if (tasks[machines[i]].exec[i]
>= tasks[machines[i]].i[i]) {
// free a machine
tasks[machines[i]].maq++;
if (tasks[machines[i]].maq >= m)
cont_n++;
machines[i] = -1;
}
}
}
makespan++;
}
// calculate makespan
if (!min_makespan || makespan < min_makespan)
min_makespan = makespan;
// generate another sequence
cont_n = 1;
while (cont_n) {
i = n - 1;
seq[i]++;
while (seq[i] >= n) {
for (j = i; j < n; j++)
seq[j] = 0;
if ((i - 1) >= 0)
seq[--i]++;
}
cont_n = 0;
for (i = 0; i < n && !cont_n; i++)
for (j = i + 1; j < n && !cont_n; j++)
if (seq[i] == seq[j])
cont_n = 1;
}
cont_n = 1;
for (i = 0; i < n - 1 && cont_n; i++)
if (seq[i] > seq[i + 1])
cont_n = 0;
if (cont_n)
break;
#ifdef DEBUG
for (i = 0; i < n; i++)
printf("%d ", seq[i]);
printf("\n");
fflush(stdout);
#endif
} while (1);
fprintf(out, "%d\n", min_makespan);
fflush(out);
}
fclose(in);
fclose(out);
return EXIT_SUCCESS;
}
Paralelização
Durante a reunião foram discutidas diferentes
abordagem para a solução desse problema. A dificuldade de encontrar uma maneira de definir as condições de parada fez com que sua solução fosse adiada para o próximo encontro.
Assinar:
Postagens (Atom)