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
Пример #4
0
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