Пример #1
0
def run():

    #  Constants
    N_ITERS = 1  # Number of times to solve an instance with a given heuristic
    #  BASE_PATH_INSTANCES = "vrptw/instances/temp/"

    # Create array with heuristics
    heuristics_dict = {
        "interroute_relocate": interroute_relocate,
        "cross_exchange": cross_exchange,
        "geni_exchange": geni_exchange,
        "interroute_2opt": interroute_2opt,
        "interroute_exchange": interroute_exchange,
        "interroute_relocate2": interroute_relocate2,
        "interroute_relocate3": interroute_relocate3,
        "intraroute_2opt": intraroute_2opt,
        "intraroute_exchange": intraroute_exchange,
        "intraroute_oropt": intraroute_oropt,
        "intraroute_relocate": intraroute_relocate
    }

    filename = "G:/My Drive/Tec/Investigacion/Metodo/VRP/vrptw/instances/S25/S25_C101.txt"

    method = SimulatedAnnealing(max_temp=35,
                                min_temp=0.1,
                                eq_iter=50,
                                temp_change=0.95,
                                trace=True,
                                histograms=False)

    for heuristic_name, heuristic in heuristics_dict.items():
        method.add_heuristic(PerturbativeHeuristic(heuristic_name, heuristic))

    method.solve(filename)
    def solve_instance(total_cost, lock, n_iters, max_temp, min_temp, eq_iter,
                       temp_change, heuristics, file):
        """ Solves one instance

        :param total_cost: object of type multiprocessing.Manager.Value used as shared object among processes to keep track
               of the cumulative sum of the best cost for all solved instances. The actual value can be accessed via the
               value attribute, ie Value.value
        :param lock: object of type multiprocessing.Manager.Lock that is used for updating the total_cost variable. It has
               the characteristic that once a process has acquired the lock, subsequent attempts to acquire it from any
               process will block until it is released. It helps avoid race conditions.
        :param n_iters: Integer value representing the number of times that an instance is to be solved. This is used for
               when trying to get a more accurate and robust value of the best cost when solving a particular instance. This
               is because the average will be taken as the final value. So, if n_iters=10, then a particular instance will
               be solved 10 and the final best cost will be taken as the average of the 10 runs.
        :param max_temp: float value representing the initial temperature.
        :param min_temp: float value representing the final temperature to be reached, which is when the algorithm stops.
        :param eq_iter: integer value representing the iterations that the algorithm performs at each temperature step. That
               means that, everytime there is a change in temperature, the algorithm runs eq_iter times.
        :param temp_change: float value between 0 and 1 representing the proportion by which the temperature is decreased at
               each iteration. For example, is the current temperature is 100 and the temp_change is .95, then one change in
               temperature is defined as 100 * 0.95 = 95, and 95 will be the updated temperature.
        :param heuristics: heuristic dictionary where the key is the name of an heuristic and as value there is an array
               where the first element is a reference function to the heuristic and the second element is an integer with
               value 1 or 0.
        :param file: string with the address of the instance to be solved.
        :return: None
        """

        # n_iters corresponds to the number of times an instance is solved. This is used for when the best cost once to
        # be defined as the average best cost from n_iters iterations. It is used to get a more reliable result of the
        # best cost

        cumulative_best_cost = 0

        for iteration in range(0, n_iters):

            method = SimulatedAnnealing(max_temp,
                                        min_temp,
                                        eq_iter,
                                        temp_change,
                                        trace=False,
                                        histograms=False)

            # Adds all heuristics
            for heuristic_name, heuristic in heuristics.items():
                if heuristic[
                        1]:  # Adds the heuristic if and only if the boolean selection value heuristic0[1] is 1
                    # The actual heuristic function is in the first spot of the array, ie heuristics[0]
                    method.add_heuristic(
                        PerturbativeHeuristic(heuristic_name, heuristic[0]))

            method.solve(file)

            cumulative_best_cost += method.best_cost

        with lock:
            total_cost.value += cumulative_best_cost / n_iters
Пример #3
0
    def solve_instance(self, n_iters, max_temp, min_temp, eq_iter, temp_change, heuristics, file, csv_file):
        """ Solves one instance

        :param n_iters: Integer value representing the number of times that an instance is to be solved. This is used for
               when trying to get a more accurate and robust value of the best cost when solving a particular instance. This
               is because the average will be taken as the final value. So, if n_iters=10, then a particular instance will
               be solved 10 and the final best cost will be taken as the average of the 10 runs.
        :param max_temp: float value representing the initial temperature.
        :param min_temp: float value representing the final temperature to be reached, which is when the algorithm stops.
        :param eq_iter: integer value representing the iterations that the algorithm performs at each temperature step. That
               means that, everytime there is a change in temperature, the algorithm runs eq_iter times.
        :param temp_change: float value between 0 and 1 representing the proportion by which the temperature is decreased at
               each iteration. For example, is the current temperature is 100 and the temp_change is .95, then one change in
               temperature is defined as 100 * 0.95 = 95, and 95 will be the updated temperature.
        :param heuristics: heuristic dictionary where the key is the name of an heuristic and as value there is an array
               where the first element is a reference function to the heuristic and the second element is an integer with
               value 1 or 0.
        :param file: string with the address of the instance to be solved.
        :return: None
        """

        # n_iters corresponds to the number of times an instance is solved. This is used for when the best cost once to
        # be defined as the average best cost from n_iters iterations. It is used to get a more reliable result of the
        # best cost

        for iteration in range(0, n_iters):

            method = SimulatedAnnealing(max_temp, min_temp, eq_iter, temp_change, trace=False, histograms=False)

            # Adds all heuristics
            for heuristic_name, heuristic in heuristics.items():
                if heuristic[1]:  # Adds the heuristic if and only if the boolean selection value heuristic0[1] is 1
                    # The actual heuristic function is in the first spot of the array, ie heuristics[0]
                    method.add_heuristic(PerturbativeHeuristic(heuristic_name, heuristic[0]))

            method.solve(file)

            # Compute features and save them as dictionary
            data_dict = self.compute_characterization_features(method)

            # Append data dictionary to output data
            self.output_data.append(data_dict)

        self.save_to_output(csv_file, headers=False)
            f = open(outputfile, 'a')
            f.write(sol_str + heur_str + "\n")
            f.close()
    print(">>> Finished <<<")


if __name__ == "__main__":
    instances_folder = input("Folder of problem instances? ")
    results_folder = input("Results folder? ")
    num_sols = int(input("Number of solutions? "))
    # algorithm configuration
    max_temp = 35.0  # initial temperature
    min_temp = 0.005  # final temperature
    eq_iter = 90  # iterations at same temperature
    temp_change = 0.995  # temperature reduction factor
    heuristics = [
        PerturbativeHeuristic('intraroute_or-opt', intraroute_oropt),
        PerturbativeHeuristic('intraroute_2-opt', intraroute_2opt),
        PerturbativeHeuristic('intraroute_relocate', intraroute_relocate),
        PerturbativeHeuristic('interroute_2-opt', interroute_2opt),
        PerturbativeHeuristic('interroute_relocate2', interroute_relocate2),
        PerturbativeHeuristic('interroute_exchange', interroute_exchange),
        PerturbativeHeuristic('cross-exchange', cross_exchange),
        PerturbativeHeuristic('GENI-exchange', geni_exchange)
    ]
    probabilities = [0.04, 0.11, 0.30, 0.06, 0.23, 0.20, 0.03, 0.03]
    # execute the algorithm
    solve_folder_problems(instances_folder, results_folder, num_sols, max_temp,
                          min_temp, eq_iter, temp_change, heuristics,
                          probabilities)
Пример #5
0
            input("Push <ENTER> to finish")
            plt.ioff()

    def present_statistics(self):
        """depicts statistics about heuristics"""
        for heuristic in self.heuristics:
            if self.trace: print(heuristic.statistics())
            if self.histograms: heuristic.plot_statistics(self.hist_step)

    def update_histograms(self):
        for heuristic in self.heuristics:
            heuristic.update_histograms()


if __name__ == "__main__":
    from vrptw.perturbative.heuristics.interroute_relocate import interroute_relocate

    filename = input("Nombre del archivo del problema? ")
    ##    cProfile.run('simulated_annealing(filename, max_temp, min_temp, eq_iter, \
    ##                               temp_change, True, False)')
    method = SimulatedAnnealing(max_temp=35.0,
                                min_temp=0.1,
                                eq_iter=50,
                                temp_change=0.95,
                                trace=True,
                                histograms=True)
    method.add_heuristic(
        PerturbativeHeuristic("interroute_relocate", interroute_relocate))
    method.solve(filename)
    print(method.best_cost)
Пример #6
0
            v -= probability
            if v <= 0.0:
                return self.heuristics[h]
        return self.heuristics[-1]


if __name__ == "__main__":
    filename = input("Nombre del archivo del problema? ")
    method = ProbabilisticSAHH(max_temp=10.0,
                               min_temp=0.5,
                               eq_iter=30,
                               temp_change=0.95,
                               trace=True,
                               histograms=False)
    method.add_heuristic(
        PerturbativeHeuristic('intraroute_or-opt', intraroute_oropt), 0.00)
    method.add_heuristic(
        PerturbativeHeuristic('intraroute_2-opt', intraroute_2opt), 0.00)
    method.add_heuristic(
        PerturbativeHeuristic('intraroute_exchange', intraroute_exchange),
        0.00)
    method.add_heuristic(
        PerturbativeHeuristic('intraroute_relocate', intraroute_relocate),
        0.00)
    method.add_heuristic(
        PerturbativeHeuristic('interroute_2-opt', interroute_2opt), 0.43)
    method.add_heuristic(
        PerturbativeHeuristic('interroute_relocate2', interroute_relocate2),
        0.26)
    method.add_heuristic(
        PerturbativeHeuristic('interroute_exchange', interroute_exchange),
        sys.stdout.flush()

        num_iteration = 0
        # Solve current instance n times with the same heuristic
        for iteration in range(0, N_ITERS):

            num_iteration = num_iteration + 1

            method = SimulatedAnnealing(max_temp=35,
                                        min_temp=0.1,
                                        eq_iter=50,
                                        temp_change=0.95,
                                        trace=False,
                                        histograms=False)
            method.add_heuristic(
                PerturbativeHeuristic(heuristic_name, heuristic))
            method.solve(filename)

            # Get customers as data frame
            df_customers = pd.DataFrame(
                list(map(vars, method.problem.customers)))

            # Process stats into dictionary
            data_dict = ast.literal_eval(method.heuristics[0].statistics())
            data_dict['best_cost'] = method.best_cost

            # Change key names
            data_dict['heuristic'] = data_dict.pop('name')
            data_dict['niter'] = data_dict.pop('used')

            # Add data about problem to dict
def main():
    # input_path = "/vrptw/instances/all_instances/"
    input_path = "/vrptw/instances/initial_instances/"
    # input_path = "/vrptw/instances/temp/"

    # This string represents the folder where the instances to be solved are located. The folder containing these
    # instances has to have the raw text file for each instance. They should not be grouped within more sub-folders.
    base_path_instances = "".join([get_project_path(), input_path])

    # Creates array with the filenames of the instances to be solved
    file_names = [
        ''.join([base_path_instances, file])
        for file in os.listdir(base_path_instances)
    ]

    # Create array with heuristics
    heuristics_dict = {
        "interroute_relocate": interroute_relocate,
        "cross_exchange": cross_exchange,
        "geni_exchange": geni_exchange,
        "interroute_2opt": interroute_2opt,
        "interroute_exchange": interroute_exchange,
        "interroute_relocate2": interroute_relocate2,
        "interroute_relocate3": interroute_relocate3,
        "intraroute_2opt": intraroute_2opt,
        "intraroute_exchange": intraroute_exchange,
        "intraroute_oropt": intraroute_oropt,
        "intraroute_relocate": intraroute_relocate
    }

    # Create pandas df to save results
    column_names = [
        'used', 'feasible', 'improved', 'improved_value', 'best', 'best_value',
        'best_cost', 'problem', 'heuristic', 'avg_overlap', 'total_overlap',
        'std_overlap', 'skewness_overlap', 'kurtosis_overlap'
    ]

    df_results = pd.DataFrame(columns=column_names)

    N_ITERS = 10

    instance_counter = 0

    # Compute values for each instance
    for instance in file_names:
        instance_counter += 1
        heuristic_counter = 1
        for heuristic_name, heuristic in heuristics_dict.items():
            print('****** INSTANCE: {}/{} ****** HEURISTIC: {}/{}\n'.format(
                instance_counter, len(file_names), heuristic_counter,
                len(heuristics_dict)),
                  flush=True)
            heuristic_counter += 1
            iteration_counter = 1
            # Solve current instance n times with the same heuristic
            for iteration in range(0, N_ITERS):
                print('ITERATION: {}/{}\n'.format(iteration_counter, N_ITERS),
                      flush=True)
                iteration_counter += 1

                method = SimulatedAnnealing(max_temp=35,
                                            min_temp=0.1,
                                            eq_iter=50,
                                            temp_change=0.95,
                                            trace=False,
                                            histograms=False)

                method.add_heuristic(
                    PerturbativeHeuristic(heuristic_name, heuristic))

                method.solve(instance)

                # Get customers as data frame
                df_customers = pd.DataFrame(
                    list(map(vars, method.problem.customers)))

                # Process stats into dictionary
                data_dict = ast.literal_eval(method.heuristics[0].statistics())
                data_dict['best_cost'] = method.best_cost

                # Add data about problem to dict
                data_dict['problem'] = 'S' + str(method.problem.ncustomers -
                                                 1) + "_" + str(
                                                     method.problem.name)

                # Change key names
                data_dict['heuristic'] = data_dict.pop('name')

                # Add data about problem to dict
                data_dict['problem'] = 'S' + str(method.problem.ncustomers -
                                                 1) + "_" + str(
                                                     method.problem.name)
                data_dict['nvehicles'] = method.problem.nvehicles
                data_dict['vehicle_capacity'] = method.problem.capacity
                data_dict['ncustomers'] = method.problem.ncustomers - 1
                data_dict['avg_demand'] = round(
                    df_customers['demand'][1:].mean(), 4)
                data_dict['total_demand'] = df_customers['demand'][1:].sum()
                data_dict['x_depot'] = df_customers[df_customers['customer'] ==
                                                    0]['xcoord'].values[0]
                data_dict['y_depot'] = df_customers[df_customers['customer'] ==
                                                    0]['ycoord'].values[0]
                data_dict['std_demand'] = round(
                    df_customers['demand'][1:].std(), 2)
                data_dict['skewness_demand'] = round(
                    df_customers['demand'][1:].skew(), 4)
                data_dict['kurtosis_demand'] = round(
                    df_customers['demand'][1:].kurtosis(), 4)
                data_dict['std_prop_demand_capacity'] = \
                    round(np.std(df_customers['demand'][1:] / method.problem.capacity), 2)
                data_dict['prop_demand_capacity'] = df_customers['demand'][1:].sum() / \
                                                    (method.problem.capacity * method.problem.nvehicles)
                data_dict['prop_largest_custmr_demand_capacity'] = \
                    df_customers['demand'].max() / method.problem.capacity
                data_dict['avg_ncustmr_vehicle'] = (method.problem.ncustomers - 1) / \
                                                   method.problem.nvehicles
                data_dict['min_nvehicles'] = round(df_customers['demand'][1:].sum() / \
                                                   method.problem.capacity, 4)
                data_dict['avg_service_time'] = round(
                    df_customers['service_duration'][1:].mean(), 4)
                data_dict['sum_ready_time'] = df_customers['ready_time'][
                    1:].sum()
                data_dict['avg_tw'] = np.sum(df_customers['due_date'][1:] - \
                                             df_customers['ready_time'][1:]) / \
                                      (method.problem.ncustomers - 1)
                data_dict['std_tw'] = np.std(df_customers['due_date'][1:] - \
                                             df_customers['ready_time'][1:]) / \
                                      (method.problem.ncustomers - 1)
                data_dict['skewness_tw'] = round(pd.DataFrame(df_customers['due_date'][1:] \
                                                              - df_customers['ready_time'][1:])
                                                 .skew().values[0], 4)
                data_dict['kurtosis_tw'] = round(pd.DataFrame(df_customers['due_date'][1:] \
                                                              - df_customers['ready_time'][1:])
                                                 .kurtosis().values[0], 4)

                # TW overlap features
                data_dict['avg_overlap'], data_dict['total_overlap'], \
                data_dict['std_overlap'], data_dict['skewness_overlap'], \
                data_dict['kurtosis_overlap'] = compute_overlap(df_customers)

                # Append data tu results dataframe
                df_results = df_results.append(data_dict, ignore_index=True)

    df_results.to_csv("statistics_and_tw_overlap_features.csv", index=False)