reset; option solver cplexamp; model MTC4_v3_1_proj_course.mod; # load the optimization model #data 20100504_MTC4_15j.dat; # load the model data data 20100504_MTC4_15j.dat problem MTC4_disc: x_nail, s_disc, h_disc, Finish_times_and_tardiness_disc, opconstraints_disc, #### z_nail_alloc, flexconstraints_disc, not_same_time_constraints_disc, interop_time_constraints_disc, end_for_j_prec_constraints, start_constraints1_disc, start_constraints2_disc, completion_time_constraints_disc, tardiness_constraints_disc #### allocconstraints ; option cplex_options 'mipdisplay=2' 'timing=1' 'mipinterval=2000' # 'mipgap=0.1' ; problem MTC4_feas: t, z, y, s, h, Process_times_and_tardiness_feas, opconstraints_feas, flexconstraints, both_y_not_1_constraints, at_least_one_y_constraints, earliest_start_constraints, same_job_constraints, interop_time_constraints, start_constraints1, start_constraints2, completion_time_constraints, tardiness_constraints, z2_fixed_constraints_feas, y_fixed_constraints_feas; option cplex_options 'mipdisplay=2' 'timing=1' 'mipinterval=2000' # 'absmipgap=0.0' # Jag la till mipgap = 0.0000005 2010-03-24 eftersom körningarna tagit för lång tid och jag inte lyckats få fram resultat. 'mipgap=0.0000005' ; option presolve_eps 1.0e-10; #-------------------------------------- HEURISTIC to determine better end of planning horizon, T----------------------------------# # These parameters are used for the heuristic: param x_nail_heur[j,k,u], s_time [k], s_max, s_min, chosen_k, proc_time_max, start_time[j] # parameters for the heuristic to find a good feasible solution, and a T_HORIZON param x_nail_heur {JOBS,K_mach_RESOURCES,0..T_HORIZON}; param s_time {K_mach_RESOURCES}; param s_max; param s_min; param chosen_k symbolic; param proc_time_max; param start_time {JOBS}; param t_disc_solution{JOBS}; # the starting times of the dicrete solution to the machining problem in hours # Initial values for {j in JOBS, k in K_mach_RESOURCES, u in 0..T_HORIZON} let x_nail_heur[j,k,u] := 0; # The time when resource k is available for the first time: for {k in K_mach_RESOURCES} let s_time[k] := a_disc[k]; let proc_time_max := 0; for {j in 1..maxjobs} { let s_min := T_HORIZON; # Below a resource k is chosen in order to schedule job j. for {k in K_mach_RESOURCES} { if ( lambda_mach[j,k]==1 ) then { if (s_min > s_time[k]) then { let s_min := s_time[k]; let chosen_k := k; if (r_disc[j] > s_min) then { let s_min := r_disc[j]; # s_min cannot be better than r_disc for this job so let's exit the loop break; } } } } let x_nail_heur[j,chosen_k,s_min] := 1; # display x_nail_heur[j,chosen_k,s_min],j,chosen_k,s_min; let start_time[j] := s_min; # x_nail get an initial solution let x_nail[j,chosen_k,s_min] := x_nail_heur[j,chosen_k,s_min]; let s_time[chosen_k] := s_min + proc_time_disc[j]; if (proc_time_max < proc_time_disc[j]) then let proc_time_max := proc_time_disc[j]; } # Below job q_follow is checked so that it is scheduled with a distance of at least v_jq_ext from j_prec which belongs to the set Q_PREC. If not, it is rescheduled. for {j_prec in Q_PREC} { if (start_time[j_prec] + v_disc_jq_ext[j_prec] > start_time[q_follow[j_prec]]) then { # q_follow needs to be rescheduled, first q_follow is "descheduled" for {k in K_mach_RESOURCES} { let x_nail_heur[q_follow[j_prec],k,start_time[q_follow[j_prec]]] := 0; let x_nail[q_follow[j_prec],k,start_time[q_follow[j_prec]]] := 0; } # Below q_follow is rescheduled let s_min := T_HORIZON; for {k in K_mach_RESOURCES} { if ( lambda_mach[q_follow[j_prec],k]==1 ) then { if (s_min > s_time[k]) then { let s_min := s_time[k]; let chosen_k := k; if (start_time[j_prec] + v_disc_jq_ext[j_prec] > s_min) then { let s_min := start_time[j_prec] + v_disc_jq_ext[j_prec]; # s_min cannot be better than this for this job so let's exit the loop break; } } } } let x_nail_heur[q_follow[j_prec],chosen_k,s_min] := 1; # print "Heuristic information: q rescheduled, because of the time v_jq_ext has to elapse after t_j, when (j,q) belongs to set Q"; # display x_nail_heur[q_follow[j_prec],chosen_k,s_min],q_follow[j_prec],chosen_k,s_min; let start_time[q_follow[j_prec]] := s_min; # x_nail get an initial solution let x_nail[q_follow[j_prec],chosen_k,s_min] := x_nail_heur[q_follow[j_prec],chosen_k,s_min]; let s_time[chosen_k] := s_min + proc_time_disc[q_follow[j_prec]]; if (proc_time_max < proc_time_disc[q_follow[j_prec]]) then let proc_time_max := proc_time_disc[q_follow[j_prec]]; } } let s_max :=0; for {k in K_mach_RESOURCES} if (s_max < s_time[k]) then let s_max := s_time[k]; # 2*proc_time_max is added to the max completion time of the jobs in the heuristic, so that there is room for at least 3 jobs to change scheduled resources in the optimization let T_HORIZON := s_max + 2*proc_time_max; option omit_zero_rows 0; print ""; print "----------Modell MTC4 - Discrete machining problem with nail variables--------------"; print ""; print "Length of discrete time interval: ", T_length_interval; print ""; print "Length of planning horizon (in number of discrete time intervals): ", T_HORIZON; print ""; print "Number of jobs: ", maxjobs; print ""; display a; display proc_time; #---------------------------------------------------------------------------------------------------------------------------------# solve MTC4_disc; # print "----------x_nail-----------"; #option omit_zero_rows 1; # display x_nail; print "----------y_disc_solution, which job is preceded by which job in a certain resource ----------"; # set all y to 0 at first let {j in JOBS,q in JOBS,k in K_RESOURCES} y_disc_solution[j,q,k] := 0; #so y_disc_solution is 0 for the non-machining resources for {j in JOBS,q in JOBS,k in K_mach_RESOURCES} if (0 < sum{u in T_ALL_INTERVALS} u*x_nail[j,k,u] < sum{u in T_ALL_INTERVALS} u*x_nail[q,k,u]) then let y_disc_solution[j,q,k] := 1; #y_disc_solution should be 1 when job j precedes job q in the same resource option omit_zero_rows 0, display_transpose -10; #display y_disc_solution; print "----------z_disc_solution, which job is scheduled to which resource -----------------"; let {j in JOBS, k in K_RESOURCES} z_disc_solution[j,k] := 0; #so z_disc_solution has a value for the non-machining resources let {j in JOBS, k in K_mach_RESOURCES} z_disc_solution[j,k] := sum{u in T_ALL_INTERVALS} x_nail[j,k,u]; option omit_zero_rows 0, display_transpose -10; display z_disc_solution; let {j in JOBS} t_disc_solution[j] := T_length_interval*(sum{k in K_mach_RESOURCES, u in T_ALL_INTERVALS} u*x_nail[j,k,u]); option omit_zero_rows 0, display_transpose 10; print "----------Starting time t_disc_j (hours from time t0)----------------------------------------"; display t_disc_solution; print "----------Completion time s_disc_j (# of intervals)------------------------------------------"; display s_disc; print "----------Tardiness h_disc_j (# of intervals)------------------------------------------------"; display h_disc; solve MTC4_feas; print ""; print "----------Modell MTC4_feas - The feasibility problem---------------------------"; print "----------z_ijk (which operation (i,j) is scheduled to which resource k)-------"; option omit_zero_rows 0, display_transpose -10; display z; option omit_zero_rows 0, display_transpose 10; print "----------Starting time t_ij (If (tr) jobs j in rows,(hours)-------------------"; display t; print "----------Completion time s_j (hours)------------------------------------------"; display s; print "----------Tardiness h_j (hours)------------------------------------------------"; display h; let proc_tardi_objective := sum{j in JOBS} (s[j]-t[1,j]+h[j]); print "---Sum of processing times and tardiness for the solution of the feasibility problem---"; display proc_tardi_objective; #option omit_zero_rows 1; #display x_nail; ####option omit_zero_rows 0; ####display z_nail_alloc;