def test_construct_cities(self): cities = GeneticAlgorithm.construct_cities(self.cities, self.connections) assert cities == {'Miasto1': City('Miasto1', 1, 1, 5), 'Miasto2': City('Miasto2', 2, 2, 4), 'Miasto3': City('Miasto3', 2, 2, 6)} assert cities['Miasto1'].connected_cities == {'Miasto2': 2} assert cities['Miasto2'].connected_cities == {'Miasto1': 2} assert cities['Miasto3'].connected_cities == dict()
def check_solution(self): # metoda sprawdzająca czy rozwiązanie jest prawidłowe if self.salesman_max_time is None: # wyświetlenie komunikatu o błędzie jeśli czas pracy komiwojażera nie został wczytany self.info_message('Wczytaj najpierw czas pracy Komiwojażera') return if not self.solution: # wyświetlenie komunikatu o błędzie jeśli rozwiązanie nie zostało wczytane lub wyznaczone self.error_message('Brak wczytanego lub obliczonego rozwiązania') return if not self.cities or not self.connections: # do weryfikacji poprawności trasy potrzebujemy listy miast i połączeń między nimi self.info_message( 'Do weryfikacji poprawności trasy niezbędne są: lista miast oraz połączeń między nimi' ) return # przekształcamy trasę rozwiązania do postaci obiektu Route cities = GeneticAlgorithm.construct_cities( self.cities, self.connections) # najpierw tworzymy miasta solution_cities = [city[0] for city in self.solution ] # wybieramy tylko id miast trasy rozwiązania route = Route(solution_cities, cities) # tworzymy obiekt Route if route.is_valid(self.salesman_max_time): # jeżeli rozwiązanie jest poprawne to poinformowanie o tym użytkownika self.info_message('Trasa jest poprawna') elif route.invalid_cause == 'less than 2 cities': # poinformowanie użytkownika, że rozwiązanie jest błędne, bo ma mniej niż 2 miasta self.info_message('Trasa składa się z mniej niż dwóch miast') elif route.invalid_cause == 'cities not connected': # poinformowanie użytkownika, że rozwiązanie jest błędne, bo nie jest możliwe połączenie miast na trasie self.info_message( 'Na trasie sąsiadują ze sobą miasta, które nie są ze sobą połączone' ) elif route.invalid_cause == 'too long': # poinformowanie użytkownika, że rozwiązanie jest błędne, bo pokonanie trasy przekracza czas pracy # komiwojażera self.info_message( 'Długość trasy przekracza ograniczenie Komiwojażera') else: # poinformowanie, że trasa nie jest poprawna z innego powodu self.info_message('Trasa nie jest poprawna')
def save_solution(self, filename): # metoda zapisująca rozwiązanie do pliku filename jeśli rozwiązanie istnieje # w przeciwnym razie poinformowanie użytkownika, że rozwiązanie nie zostało wyznaczone lub wczytane if not self.solution: self.error_message('Brak rozwiązania, które można zapisać') return if not self.connections: self.error_message( 'W celu zapisania rozwiązania niezbędne są dane miast') return if not self.cities: self.error_message( 'W celu zapisania rozwiązania niezbędne są dane połączeń między miastami' ) return # przekształcenie do wymaganego formatu solution = [[str(element) for element in city] for city in self.solution] route_string = [','.join(city) for city in solution] route_string = [f'({city})' for city in route_string] route_string = ','.join(route_string) route_string = f'[{route_string}]' cities = GeneticAlgorithm.construct_cities(self.cities, self.connections) solution_cities = [city[0] for city in self.solution ] # wybieramy tylko id miast route = Route(solution_cities, cities) data = '\r\n'.join( [route_string, str(route.fitness), str(route.distance)]) # upewniamy się, że nazwa pliku, który zapisujemy ma rozszerzenie .txt i dodajemy jeśli nie ma if not filename.endswith('.txt'): filename += '.txt' IO.save_solution(data, filename)