def order_type(LM, LT, MCoeff, esp): """ input : List of machines, List of tasks, Array of coefficients, Double for the coefficient*LB wanted output : List of mahines order type depending on Mcoeff then allocate tasks with the LB criteria very good if not all types are compatible: because all coeffs on a machine will be 1 while they could be less if mixed """ LM = data_structure.create_LM(len(LM)) LB = borne_inf(LT, LM, MCoeff) #LT = sorted(LT, key = itemgetter('size'), reverse=True) # allocate task in the right order machine = 0 for Type in ordered_types: for task in LT: # append tasks of this one type if task['type'] == Type: LM[machine]['LTM'].append(task) if ((data_structure.cost_M_gen(LM[machine], MCoeff)) > esp * LB): LM[machine]['LTM'].remove(task) # trier les taches de la machine par ordre décroissant LM[machine]['LTM'] = sorted(LM[machine]['LTM'], key=itemgetter('size'), reverse=True) machine += 1 if (machine == len(LM)): #print ("pas de machine libre") return 0 LM[machine]['LTM'].append(task) # cas ou il reste des machines libres for machine in range(len(LM)): if not LM[machine]["LTM"]: # this machine is empty # try to fit tasks from the most charged machine(s) on the empty machine most_charged = data_structure.max_ind_cost_LM_gen(LM, MCoeff) #print(len(most_charged)) coutMax = data_structure.cost_M_gen(LM[most_charged[0]], MCoeff) for heavy_machine in most_charged: last_task = LM[heavy_machine]['LTM'][-1] # add last task to empty machine LM[machine]['LTM'].append(last_task) if data_structure.cost_M_gen(LM[machine], MCoeff) >= coutMax: LM[machine]['LTM'].remove(last_task) break # remove last task from heavy machine LM[heavy_machine]['LTM'].remove(last_task) return LM
def lpt_typed_difference(LM,LT,MCoeff, group=False, k = 0): """input : list of machines * list of tasks * Matrix Coefficient tasks output : a new list of machines after using algorithm This algorithm works like lpt in the first place but it is not looking for the machine with the minimal cost to add a task rather it looks for the machine that will be the least affected after adding a task this one looks the minimal differences between the old and the new one THIS ONE IS NOT BETTER THAN THE OLD ONE Although from time to times coupled with PTAS the cost_max is reduced, don't ask me why """ #a new list sorted in a decreasing tasks' size LT_sorted = sorted(LT,key=itemgetter('size'),reverse=True) LM_lpt_typed = copy.deepcopy(LM) #operating in all tasks for i in range(0,len(LT)): #if there's an index i in LM and the machine is empty, add the task in the machine if ((i<len(LM)) and len(LM_lpt_typed[i]['LTM'])==0): LM_lpt_typed[i]['LTM'].append(LT_sorted[i]) #we will put the task in the machine that will cost the least after adding it else: """will put the task in the machine where : new_cost_machine - old_cost_machine , is minimal looking machine by machine, faster but not the best """ #C_before is a list contains all machine's cost before adding the current task C_before=[] for k in range(len(LM_lpt_typed)): C_before.append(data_structure.cost_M_gen(LM_lpt_typed[k],MCoeff)) #C_after_diff is list that will contain the difference of a machine's cost after and before adding the task C_after_diff=[] #operating in all machines for j in range(len(LM_lpt_typed)): #operating in a copy so we don't affect what we want to return : LM_lpt_typed LM_lpt_typed_copy=copy.deepcopy(LM_lpt_typed) LM_lpt_typed_copy[j]['LTM'].append(LT_sorted[i]) C_after_diff.append(data_structure.cost_M_gen(LM_lpt_typed_copy[j],MCoeff)-C_before[j]) #adding the task in the machine that will cost the least afterwards LM_lpt_typed[C_after_diff.index(min(C_after_diff))]['LTM'].append(LT_sorted[i]) return LM_lpt_typed
def lpt_typed(LM, LT, MCoeff, group=False, k = 0): """input : list of machines * list of tasks * Matrix Coefficient tasks output : a new list of machines after using algorithm This algorithm works like lpt in the first place but it is not looking for the machine with the minimal cost to add a task rather it looks for the machine that will be the least affected after adding a task """ # a new list sorted in a decreasing tasks' size LT_sorted = sorted(LT, key=itemgetter('size'), reverse=True) LM_lpt_typed = copy.deepcopy(LM) # operating in all tasks for i in range(0, len(LT)): # if there's an index i in LM and the machine is empty, add the task in the machine if ((i < len(LM)) and len(LM_lpt_typed[i]['LTM']) == 0): LM_lpt_typed[i]['LTM'].append(LT_sorted[i]) # we will put the task in the machine that will cost the least after adding it else: # C_tmp is a list that will contain all machine's cost after adding the current task C_tmp = [] # C_old is a list containing all machine's cost before adding the current task C_old = [] for k in range(len(LM_lpt_typed)): LM_lpt_typed_copy = copy.deepcopy(LM_lpt_typed) C_old.append(data_structure.cost_M_gen(LM_lpt_typed_copy[k], MCoeff)) # operating in all machines for j in range(len(LM_lpt_typed)): # operating in a copy so we don't affect what we want to return : LM_lpt_typed LM_lpt_typed_copy = copy.deepcopy(LM_lpt_typed) # putting the task in the temporary LM LM_lpt_typed_copy[j]['LTM'].append(LT_sorted[i]) # calculating the final cost of LM after adding the task C_tmp.append(final_cost_inlist(C_old, data_structure.cost_M_gen(LM_lpt_typed_copy[j], MCoeff), j)) # adding the task in the machine that will cost the least afterwards LM_lpt_typed[C_tmp.index(min(C_tmp))]['LTM'].append(LT_sorted[i]) return LM_lpt_typed
def greedy_cluster_wo_lpt_typed(LM, LT, MCoeff, esp): """ input : List of machines, List of tasks, Array of coefficients, Double for the coefficient*LB wanted output : new List of mahines builds clusters of tasks depending on their types. Then allocates those tasks with the LB criteria """ LB = greedy_cluster_tools.borne_inf(LT, LM) LC = [] # create list of types All_types = [] for task in LT: if (task['type'] not in All_types): All_types.append(task['type']) # getting type clustered LC = greedy_cluster_tools.rec_clusterize(LC, All_types, MCoeff) #LC_rec_clusterize_improved(LC,All_types,MCoeff) # create clusters of tasks LT_clusterized based on clusters of types LC LT_clusterized = [[] for cluster in range(len(LC))] for cluster in range(len(LC)): for task in LT: if task['type'] in LC[cluster]: LT_clusterized[cluster].append(task) # allocate clusterized tasks LT_clusterized in machines LM so as not to surpass LB # here we'll operate first in the cluster : cluster, then in the tasks in that cluster : task, --> two loops # all of that operating in parallel with a machine : num_machine, it is not embodied by a loop num_machine = 0 machine_done = False LM_greedy = copy.deepcopy(LM) LT_clust_copy = copy.deepcopy(LT_clusterized) # operating in clusters containing tasks, looping in a copy to avoid weird bugs for cluster in LT_clust_copy: # if we are still operating in an existing machine if num_machine < len(LM_greedy): # if the cluster is not empty if len(cluster): #sort decreasingly by tasks' size the cluster cluster = sorted(cluster, key=itemgetter('size'), reverse=True) cluster_copy = copy.deepcopy(cluster) # operating task in that cluster, looping in a copy to avoid weird bugs, but operating directly in results : LM_greedy for task in cluster_copy: # if we are still operating in an existing machine if num_machine < len(LM_greedy): # add temporarily the task in the num_machine (LM_greedy[num_machine]['LTM']).append(task) cluster.remove(task) # if the num_machine have now a cost > esp*LB if (data_structure.cost_M_gen(LM_greedy[num_machine], MCoeff) > esp * LB): # we remove the added task and num_machine is done cluster.append(task) del LM_greedy[num_machine]['LTM'][-1] machine_done = True if machine_done: num_machine += 1 # add the task in the next existing machine if num_machine < len(LM_greedy): (LM_greedy[num_machine]['LTM']).append(task) cluster.remove(task) machine_done = False # case bad_esp : # no available machine to ensure < esp*LB , so we add the task in the first machine # note that this esp is not a good one, therefore we make sure that the cost will be high else: (LM_greedy[0]['LTM']).append(task) cluster.remove(task) machine_done = False # case bad_esp else: (LM_greedy[0]['LTM']).append(task) cluster.remove(task) # case bad_esp else: cluster_copy = copy.deepcopy(cluster) for task in cluster_copy: (LM_greedy[0]['LTM']).append(task) cluster.remove(task) return LM_greedy