def merge_archives(input_path, output_path, functions, instances, dimensions, crop_variables): """Merges all archives from the input_path (removes any dominated solutions) and stores the consolidated archives in the output_path. Returns problem names and their new best hypervolume values in the form of a dictionary. :param input_path: input path :param output_path: output path (created if not existing before) :param functions: functions to be included in the merging :param instances: instances to be included in the merging :param dimensions: dimensions to be included in the merging :param crop_variables: whether output archives should contain information on solution variables """ result = {} print('Reading archive information...') sys.stdout.flush() archive_info = ArchiveInfo(input_path, functions, instances, dimensions) print('Processing archives...') sys.stdout.flush() while True: # Get information about the next problem instance problem_instance_info = archive_info.get_next_problem_instance_info() if problem_instance_info is None: break old_level = log_level('warning') # Create an archive for this problem instance archive = Archive(problem_instance_info.suite_name, problem_instance_info.function, problem_instance_info.instance, problem_instance_info.dimension) # Read the solutions from the files and add them to the archive problem_instance_info.fill_archive(archive) # Write the non-dominated solutions into output folder problem_instance_info.write_archive_solutions(output_path, archive, crop_variables) result.update({str(problem_instance_info): archive.hypervolume}) print('{}: {:.15f}'.format(problem_instance_info, archive.hypervolume)) sys.stdout.flush() log_level(old_level) return result
def merge_archives(input_path, output_path, functions, instances, dimensions, crop_variables): """Merges all archives from the input_path (removes any dominated solutions) and stores the consolidated archives in the output_path. Returns problem names and their new best hypervolume values in the form of a dictionary. :param input_path: input path :param output_path: output path (created if not existing before) :param functions: functions to be included in the merging :param instances: instances to be included in the merging :param dimensions: dimensions to be included in the merging """ result = {} print('Reading archive information...') archive_info = ArchiveInfo(input_path, functions, instances, dimensions) print('Processing archives...') while True: # Get information about the next problem instance problem_instance_info = archive_info.get_next_problem_instance_info() if problem_instance_info is None: break old_level = log_level('warning') # Create an archive for this problem instance archive = Archive(problem_instance_info.suite_name, problem_instance_info.function, problem_instance_info.instance, problem_instance_info.dimension) # Read the solutions from the files and add them to the archive problem_instance_info.fill_archive(archive) # Write the non-dominated solutions into output folder problem_instance_info.write_archive_solutions(output_path, archive, crop_variables) result.update({str(problem_instance_info): archive.hypervolume}) print('{}: {:.15f}'.format(problem_instance_info, archive.hypervolume)) log_level(old_level) return result
def archive_thinning(input_path, output_path, thinning_precision, currently_nondominated, functions, instances, dimensions): """Performs thinning of all the archives in the input path and stores the thinned archives in the output path. Assumes one file contains one archive. For each archive, all input solutions are rounded according to the thinning precision (in the normalized objective space) and added to the thinned archive. If currently_nondominated is True, all solutions that are currently nondominated within the thinned archive are output. The two extreme solutions are not output. If currently_nondominated is False, only the solutions that are contained in the final archive are output. In this case, the two extreme solutions are also output. """ # Check whether input path exists input_files = get_file_name_list(input_path, ".adat") if len(input_files) == 0: raise PreprocessingException('Folder {} does not exist or is empty'.format(input_path)) old_level = log_level('warning') for input_file in input_files: try: (suite_name, function, instance, dimension) = parse_archive_file_name(input_file) if (function not in functions) or (dimension not in dimensions): continue if not instance: raise PreprocessingWarning('Thinning does not work on files with multiple archives, use archive_split') if instance not in instances: continue except PreprocessingWarning as warning: print('Skipping file {}\n{}'.format(input_file, warning)) continue print(input_file) output_file = input_file.replace(input_path, output_path) create_path(os.path.dirname(output_file)) f_out = open(output_file, 'w') thinned_archive = Archive(suite_name, function, instance, dimension) thinned_solutions = 0 all_solutions = 0 extreme1_text = thinned_archive.get_next_solution_text() extreme2_text = thinned_archive.get_next_solution_text() extreme1 = [float(x) for x in extreme1_text.split()[1:3]] extreme2 = [float(x) for x in extreme2_text.split()[1:3]] ideal = [min(x, y) for x, y in zip(extreme1, extreme2)] nadir = [max(x, y) for x, y in zip(extreme1, extreme2)] normalization = [x - y for x, y in zip(nadir, ideal)] with open(input_file, 'r') as f_in: for line in f_in: if line[0] == '%': f_out.write(line) elif len(line) == 0 or len(line.split()) < 3: continue elif line.split()[0] == '0': # The line contains an extreme solution, do nothing all_solutions += 1 continue else: # The line contains a 'regular' solution try: # Fill the archives with the rounded solutions values wrt the different precisions f_original = [float(x) for x in line.split()[1:3]] f_normalized = [(f_original[i] - ideal[i]) / normalization[i] for i in range(2)] f_normalized = [round(f_normalized[i] / thinning_precision) for i in range(2)] f_normalized = [ideal[i] + f_normalized[i] * thinning_precision for i in range(2)] updated = thinned_archive.add_solution(f_normalized[0], f_normalized[1], line) except IndexError: print('Problem in file {}, line {}, skipping line'.format(input_file, line)) continue finally: all_solutions += 1 if currently_nondominated and (updated == 1): thinned_solutions += 1 f_out.write(line) if not currently_nondominated and (thinned_archive.number_of_solutions == 2): # Output the two extreme solutions if they are the only two in the archive f_out.write(extreme1_text) f_out.write(extreme2_text) thinned_solutions = 2 while not currently_nondominated: text = thinned_archive.get_next_solution_text() if text is None: break thinned_solutions += 1 f_out.write(text) print('original: {} thinned: {} ({:.2f}%)'.format(all_solutions, thinned_solutions, 100 * thinned_solutions / all_solutions)) f_out.close() log_level(old_level)
def archive_thinning(input_path, output_path, thinning_precision, currently_nondominated, functions, instances, dimensions): """Performs thinning of all the archives in the input path and stores the thinned archives in the output path. Assumes one file contains one archive. For each archive, all input solutions are rounded according to the thinning precision (in the normalized objective space) and added to the thinned archive. If currently_nondominated is True, all solutions that are currently nondominated within the thinned archive are output. The two extreme solutions are not output. If currently_nondominated is False, only the solutions that are contained in the final archive are output. In this case, the two extreme solutions are also output. """ # Check whether input path exists input_files = get_file_name_list(input_path, ".adat") if len(input_files) == 0: raise PreprocessingException( 'Folder {} does not exist or is empty'.format(input_path)) old_level = log_level('warning') for input_file in input_files: try: (suite_name, function, instance, dimension) = parse_archive_file_name(input_file) if not instance: raise PreprocessingWarning( 'Thinning does not work on files with multiple archives, use archive_split' ) if (function not in functions) or (instance not in instances) or ( dimension not in dimensions): continue except PreprocessingWarning as warning: print('Skipping file {}\n{}'.format(input_file, warning)) continue print(input_file) output_file = input_file.replace(input_path, output_path) create_path(os.path.dirname(output_file)) f_out = open(output_file, 'w') thinned_archive = Archive(suite_name, function, instance, dimension) thinned_solutions = 0 all_solutions = 0 extreme1_text = thinned_archive.get_next_solution_text() extreme2_text = thinned_archive.get_next_solution_text() extreme1 = [float(x) for x in extreme1_text.split()[1:3]] extreme2 = [float(x) for x in extreme2_text.split()[1:3]] ideal = [min(x, y) for x, y in zip(extreme1, extreme2)] nadir = [max(x, y) for x, y in zip(extreme1, extreme2)] normalization = [x - y for x, y in zip(nadir, ideal)] with open(input_file, 'r') as f_in: for line in f_in: if line[0] == '%': f_out.write(line) elif len(line) == 0 or len(line.split()) < 3: continue elif line.split()[0] == '0': # The line contains an extreme solution, do nothing all_solutions += 1 continue else: # The line contains a 'regular' solution try: # Fill the archives with the rounded solutions values wrt the different precisions f_original = [float(x) for x in line.split()[1:3]] f_normalized = [ (f_original[i] - ideal[i]) / normalization[i] for i in range(2) ] f_normalized = [ round(f_normalized[i] / thinning_precision) for i in range(2) ] f_normalized = [ ideal[i] + f_normalized[i] * thinning_precision for i in range(2) ] updated = thinned_archive.add_solution( f_normalized[0], f_normalized[1], line) except IndexError: print('Problem in file {}, line {}, skipping line'. format(input_file, line)) continue finally: all_solutions += 1 if currently_nondominated and (updated == 1): thinned_solutions += 1 f_out.write(line) if not currently_nondominated and (thinned_archive.number_of_solutions == 2): # Output the two extreme solutions if they are the only two in the archive f_out.write(extreme1_text) f_out.write(extreme2_text) thinned_solutions = 2 while not currently_nondominated: text = thinned_archive.get_next_solution_text() if text is None: break thinned_solutions += 1 f_out.write(text) print('original: {} thinned: {} ({:.2f}%)'.format( all_solutions, thinned_solutions, 100 * thinned_solutions / all_solutions)) f_out.close() log_level(old_level)