% main routine schedule(BestSchedule, BestFinTime):- tasks(TDs), constrain(TDs, Schedule, FinTime), init_bound, assign_pro(Schedule, FinTime), minimize(FinTime), update_bound(Schedule, FinTime), fail ; bestsofar(BestSchedule, BestFinTime). % take care of initial and final bounds init_bound :- retract( bestsofar(_, _) ), fail ; assert( bestsofar(no_schedule, 99999) ). update_bound(Schedule, FinTime):- retract( bestsofar(_, _) ), !, assert( bestsofar(Schedule, FinTime) ). % add basic constraints constrain([], [], FinTime). constrain([T/D | TDs], [T/Pro/Start/D | Rest], FinTime):- { Start >= 0, Start + D =< FinTime }, constrain(TDs, Rest, FinTime), prec_constr(T/Pro/Start/D, Rest). % add precedence constraints prec_constr(_, []). prec_constr(T/P/S/D, [T1/P1/S1/D1 | Rest]):- ( prec(T, T1), !, { S + D =< S1 } ; prec(T1, T), !, { S1 + D1 =< S } ; true ), prec_constr(T/P/S/D, Rest). % assign processors assign_pro([], _). assign_pro([T/P/S/D | Rest], FinTime):- assign_pro(Rest, FinTime), resource(T, Processors), member(P, Processors), resource_constr(T/P/S/D, Rest), bestsofar(_, BestTimeSoFar), { FinTime < BestTimeSoFar }. % add resource constaints resource_constr(_, []). resource_constr(T, [T1 | Rest]):- no_conflict(T, T1), resource_constr(T, Rest). % prevent processor conflicts no_conflict(T1/P1/S1/D1, T2/P2/S2/D2):- P1 \== P2, ! ; prec(T1, T2), ! ; prec(T2, T1), ! ; { S1 + D1 =< S2 ; S2 + D2 =< S1 }. % podaj problem (opisi taske in podaj precedence) tasks([t1/4, t2/8, t3/6, t4/20, t5/20, t6/11, t7/11, t8/9]). prec(t1, t4). prec(t1, t5). prec(t2, t4). prec(t2, t5). prec(t2, t6). prec(t3, t5). prec(t3, t6). prec(t3, t7). prec(t3, t8). prec(t4, t8). resource(_, [1,2,3]).