/*------------------------------------------------------------------------------- TIA F|perm|max(Ci) Ütemezési fedadat szimulációja. Egyutas előzésnélküli többoperációs termelésütemezési feladat. A Simulation_FS adott műveleti idők és adott indítási sorrend esetében kiszámítja az operációk indítási és befejezési időpontjait. F2|perm|max(Ci) Ütemezési fedadat megoldása Johnson-algoritmussal. Az algoritmus optimális megoldást eredményez. void Johnson_alg(T_JOB* job, int N, int M, int* sch, int x, int y); F3|perm|max(Ci) feladatra a Johnson-algoritmus kiterjeszthető! Bizonyos feltételek teljesülése esetén a megoldás optimális, egyébként az optimalitás nem garantálható! int Johnson_alg_3gepre(T_JOB* job, int N, int M, int* sch, int x); Továbbfejlesztett modell: F|permut|max(Ci) Utemezesi fedadat: Többgépes egyutas előzés nélküli termelésiütemezési feladat. Az ütemezés célja a legkésőbbi befejezési időpont minimalizálása, ezáltal a teljes rendeléscsoport átfutási idejének minimalizálása. CDS-algoritmus: A Campbell-Dudek-Smith algoritmus a többgépes feladatot kétgépes problémákra vezeti vissza. Az algoritmus az eredeti M gépes feladatból M-1 darab mesterséges kétgépes problémát generál úgy, hogy az egymást követő gépek lesznek a kétgépes feladat gépei. A kétgépes feladatok egyenként megoldhatók a Johnson-algoritmussal. Kiválasztva közülük a teljes feladatra vonatkozó átfutási idő szempontjából a legjobbat, az lesz az M-gépes probléma megoldása. A megoldás nem optimális mert a feladat NP-hard, de jó közelítő ütemtervet eredményez. Dannenbring-algoritmus: Az eredeti M-gépes problémából egy mesterséges kétgépes problémát generál úgy, hogy a műveleti idők súlyozott lineáris kombinációjával állítja elő a virtuális kétgépes probléma időadatait. A kétgépes feladat megoldható a Johnson-algoritmussal és ez adja az eredeti probléma megoldását. . DTFSZTIR Továbbfejlesztett modell: F|perm|max(Ci) Utemezesi fedadat megoldasa véletlenszerűen kereső algoritmus alkalmazásával. Lokális kereső algoritmus demo (kész). Továbbfejlesztés: F|perm|max(Ci) szakaszosan rendelkezésre álló erőforrások figyelembevételével. Továbbfejlesztett modell: Szakaszosan rendelkezésre álló gépek terhelésére szolgáló algortimus. A Load_STET_to_Cal függvény a cut paraméter értékétől függően a megadott terhelést [st, et] but==0 érték esetén: az adott gépre megszakitás nelkul helyezi el (a legkorábbi rendelkezésre állási intervallumra, amelyen egészben elfér). cut==1 érték esetén: megszakitásokkal akár több darabban helyezi el az adott gép rendelkezésre állási időintervallumaira. A függvény a szimulációban kerül meghívásra. Továbbfejlesztett modell: Több célfüggvény egyidejű figyelembevétele. A megoldások egymáshoz vizsonyított relatív minőségének számszerűsítésére alapozott matematikai modell. double F( OBJF* sx, OBJF* sy); Ennek felhasználásával az egycélú kereső algoritmusok többcélúvá alakíthatók. Egyszerű példa: int Search( T_JOB* job, int N, int M, int* sch, int STEP, int LOOP, T_RES* res, int cut); A célfüggvények kiszámítása: void Evaluation_MO(T_JOB* job, int N, int M, OBJF* obj); -------------------------------------------------------------------------------*/ #include #include #include #include #define K 3 //celfuggvenyek szama typedef double OBJF[K]; //celfv-k akt. erteket tarolo tipus double W[K]; //celfv-k prioritasa typedef struct{ int id; long *ProcT, /*vektorban tarolhato az operaciok ideje*/ *StartT, *EndT; long T, /* tardiness, csuszas */ d; /* due date, hatariido */ }T_JOB; typedef struct{ long Cmax; /*Cmax Completion Time*/ }T_OBJF; typedef struct{ long ST; //Start Time long ET; //End Time }T_TW; //Time Window typedef struct{ int id; int NCal; //Number of Calendar elements T_TW* Cal; //Calendar }T_RES; //Resource: gep, ember stb. //void Simulation_FS(T_JOB* job, int N, int M, int* sch, long t); void Simulation_FS(T_JOB* job, int N, int M, int* sch, long t, T_RES* res, int cut); //void Evaluation(T_JOB* job, int N, int M, T_OBJF* obj); void Evaluation_MO(T_JOB* job, int N, int M, OBJF* obj); void print_Machine_Gantt_FS(T_JOB* job, int N, int M, int* sch); void print_Job_Gantt_FS(T_JOB* job, int N, int M, int* sch); void print_OBJF(OBJF* obj); void Johnson_alg(T_JOB* job, int N, int M, int* sch, int x, int y); int Johnson_alg_3gepre(T_JOB* job, int N, int M, int* sch, int x); void Dannenbring_alg(T_JOB* job, int N, int M, int* sch); void copy_sch(int* s1, int* s2, int N); void copy_OBJF(OBJF* o1, OBJF* o2); //DTFSZTIR //int Search( T_JOB* job, int N, int M, int* sch, int STEP, int LOOP); int Search( T_JOB* job, int N, int M, int* sch, int STEP, int LOOP, T_RES* res, int cut); void Neighbour(int* s0, int* s, int N); //res void print_Cal( T_RES* res, int M); int Load_STET_to_Cal( long* ST, long* ET, long last, T_RES* res, int m, int cut ); int Load_STET_to_Cal_do_Cut( long* ST, long* ET, long last, T_RES* res, int m ); double F( OBJF* sx, OBJF* sy); int main(int argc, char* argv[]) { int par; //kiterjeszthetoseg feltetelenek vizsgalata T_JOB* job; //munkak adatai int M; //gepek szama int m; //gepek indexe int c; //intervallumok futoindexe int* sch; //BUG javitasa //T_OBJF obj; //korabbi: struktura tipus OBJF obj; //uj: vektor tipus T_RES* res; //eroforrasok adatai int N; //munkak szama int i; //munkak indexe int cut; //munka megszakithato? int k; //celfuggveny indexe printf("\n Flow Shop utemezesi feladat megoldasa tobbcelu kereso algoritmussal"); for( k=0; kCmax = job[0].EndT[M-1]; for (i=1; i obj->Cmax ) obj->Cmax = job[i].EndT[M-1]; } */ void Evaluation_MO(T_JOB* job, int N, int M, OBJF* obj) { //k = 0 eseten Cmax //k = 1 eseten Csum //k = 2 eseten Tmax int i; (*obj)[0] = job[0].EndT[M-1]; (*obj)[1] = job[0].EndT[M-1]; (*obj)[2] = max(0, job[0].EndT[M-1] - job[0].d); for (i=1; i min( job[r[j]].ProcT[x], job[r[j]].ProcT[y] ) ) { temp = r[i]; r[i] = r[j]; r[j] = temp; } f = 0; /* first */ l = N-1; /* last */ for(i=0; i job[i].ProcT[x]) min_0 = job[i].ProcT[x]; if ( max_1 > job[i].ProcT[x+1]) max_1 = job[i].ProcT[x+1]; if ( min_2 > job[i].ProcT[x+2]) min_2 = job[i].ProcT[x+2]; } } if ( min_0 >= max_1 || min_2 >= max_1 ) return 1; else return 0; } void copy_sch(int* s1, int* s2, int N) { int i; for (i=0; i", res[m].id, res[m].NCal); for( c=0; c= res[m].NCal ) break; continue; } } c++; } *ST = newST; *ET = newET; return found; //megtalalt intervallum azonositoja } int Load_STET_to_Cal_do_Cut( long* ST, long* ET, long last, T_RES* res, int m ) { long newST; //elhelyezett munka kezdete long newET; //elhelyezett munka vege long size; //munka meg be nem utemezett merete int c; //intervallumok futoindexe int found; //talalat long fps; //first part start, munka elso darabjanak kezdete size = *ET - *ST; newST = max( *ST, last); newET = newST + size; c = 0; found = -1; fps = -1; //jelzes while( c < res[m].NCal ) { if ( newST < res[m].Cal[c].ET ) { newST = max( newST, res[m].Cal[c].ST ); //elejere igazit newET = newST + size; if ( fps == -1 ) fps = newST; if ( newET <= res[m].Cal[c].ET ) //benne van a vege is { //siker found = c; break; } else { c++; if ( c >= res[m].NCal ) break; //csokkentjuk a munka meg be nem utamezett hosszat size -= res[m].Cal[c-1].ET - newST; continue; } } c++; } if ( fps == -1 ) //ha a bejovo ST ertek tullepi az utolso intervallumot is *ST = newST; //a bejovo ST erteken nem valtoztat else *ST = fps; //elso darab kezdete *ET = newET; //utolso darab vege return found; //megtalalt intervallum azonositoja } double F( OBJF* sx, OBJF* sy) { //sx, sy megoldasok relativ tobbcelu osszehasonlitasa int k; //celfv indexe double F = 0; double D; double a, b; for( k=0; k