예제 #1
0
class BestFirst:
    """Class representing Best First algorithm
    It returns a path depending on which country has the highest number of cases on the next day"""
    def __init__(self, starting_country, starting_date, alg_graph, goal_function):
        """Initializes BestFirst Algorithm object
        You specify the country and date you start with and a graph to work with"""
        self.path = Path(starting_country, starting_date)
        self.graph = alg_graph
        self.goal_function = goal_function


    def finding_path(self):
        """Main function to find a path according to BestFirst algorithm
            It returns a path object"""
        start_country, start_date = self.path.countries[0], self.path.start_date
        stats = self.graph.get_stats(start_country) # Here is a country which has latest data
        last_date = datetime.date(stats[0, 2], stats[0, 1], stats[0, 0])
        current_country_neighbors = self.graph.get_neighbours(start_country)
        current_country, current_date = start_country, start_date
        while current_date != last_date:
            current_country = self.choose_neighbor_with_max_cases(current_country_neighbors)
            current_country_neighbors = self.graph.get_neighbours(current_country)
            current_date += datetime.timedelta(days=1)
            self.path.add(current_country)
        self.path.eval(self.graph, self.goal_function)

    def choose_neighbor_with_max_cases(self, countries_list=None):
        """Function which chooses the best country to go to next
        It looks for the biggest number of cases from countries list"""
        countries_list = countries_list if countries_list else []
        try:
            if not countries_list:
                raise Exception
        except Exception as e:
            print("There are no neighbors to choose from: {0}".format(e))
        max_cases = -1
        country_with_max_cases = ''
        for country in countries_list:
            if self.path.get_profit(self.graph, country, self.goal_function) > max_cases:
                max_cases = self.path.get_profit(self.graph, country, self.goal_function)
                country_with_max_cases = country
        return country_with_max_cases

    def work(self):
        """Method which initializes every method essential to find a path"""
        self.finding_path()
예제 #2
0
class BruteAlgorithm:
    """Class representing Brute Algorithm
    It takes every possible path in the graph and finds the one,
    on which the doctor cures the highest number of people"""
    def __init__(self, starting_country, starting_date, alg_graph, goal_function):
        """Method which initializes BruteAlgorithm object
            It takes start country and date plus the graph on which it should work on"""
        self.path = Path(starting_country, starting_date)
        self.graph = alg_graph
        self.possible_paths = [tuple([starting_country])]
        stats = self.graph.get_stats(starting_country)  # Here is a country which has latest data
        self.last_date = datetime.date(stats[0, 2], stats[0, 1], stats[0, 0])
        self.days_difference = int((self.last_date - starting_date).days)
        self.goal_function = goal_function

    def generate_paths(self):
        """Method which generates all available paths"""
        for path_list in self.possible_paths:
            if int(self.days_difference) < len(path_list):
                break
            for neighbor in self.graph.get_neighbours(path_list[len(path_list)-1]):
                new_path = list(path_list)
                new_path.append(neighbor)
                self.possible_paths.append(tuple(new_path))

    def choose_best_path(self):
        """Method chooses the best possible path (which has the highest number of cured poeple)"""
        longest_paths = [path for path in self.possible_paths if len(path) == self.days_difference + 1]
        best_path = []
        if self.goal_function == 'recovered':
            best_score = -1
        elif self.goal_function == 'deaths':
            best_score = 1000000000
        for path in longest_paths:
            self.clear_path()
            self.add_whole_path(path)
            self.path.eval(self.graph, self.goal_function)
            if self.goal_function == 'recovered' and self.path.score > best_score:
                best_score = self.path.score
                best_path = path
            elif self.goal_function == 'deaths' and self.path.score < best_score:
                best_score = self.path.score
                best_path = path
        self.clear_path()
        self.add_whole_path(best_path)
        self.path.eval(self.graph, self.goal_function)

    def clear_path(self):
        """Method clears the variable self.path leaving only the starting country"""
        for i in range(len(self.path.countries)-1):
            self.path.countries.pop()
        self.path.score = 0

    def add_whole_path(self, path):
        """Method adds countries which are in the argument 'path'
        (execpt the first one which is already in the variable self.path"""
        for country_index in range(len(path)):
            if country_index == 0:
                continue
            self.path.add(path[country_index])

    def work(self):
        """Method which initializes every method essential to find a path"""
        self.generate_paths()
        self.choose_best_path()