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
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)
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)
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)