示例#1
0
class DVA(Algorithm):

    # noinspection PyMissingConstructor
    def __init__(self, dist_multiplier=1.0):
        if dist_multiplier < 1.0:
            raise Exception('dist_multiplier cannot be lower than 1.0')

        self.graph = Graph()
        self.dist_multiplier = dist_multiplier

    def add_point(self, point: Point):
        # This list contains tuples of points and distances to them : (distance, point)
        list_distances = self.graph.get_distance_to(point)

        # If graph is empty we don't need to do any specific operations but adding point
        if len(list_distances) == 0:
            self.graph.add_point(point, set())
            return

        # Get nearest point
        num_nearest_distance = list_distances[0][0]

        # Get list of new neighbors of point
        filter_tuples = filter(
            lambda x: x[0] <= num_nearest_distance * self.dist_multiplier,
            list_distances)
        list_neighbors = list(filter_tuples)
        map_neighbors = map(lambda x: x[1], list_neighbors)
        set_neighbors = set(map_neighbors)

        # Add point and its neighbors to graph
        self.graph.add_point(point, set_neighbors)

    def delete_point(self, point: Point):
        # Get list of points which connections is needed to correct
        list_neighbors = self.graph.get_neighbours_list(point)

        if len(list_neighbors) == 0:
            self.graph.remove_point(point)
            return

        map_neighbors = map(lambda x: x[1], list_neighbors)
        list_points_to_correct = list(map_neighbors)

        # Remove point
        self.graph.remove_point(point)

        # Correct graph structure
        self.__correct_graph_structure(list_points_to_correct)

    def find_nearest_to(self, point: Point):
        set_a = set(self.graph.get_points())

        point_current = set_a.pop()
        num_current_distance = point.distance_to(point_current)

        list_neighbors = self.graph.get_neighbours_list(point_current)
        while len(list_neighbors) != 0:
            # Get shortest distance among neighbors
            list_distances = list(
                map(lambda x: x[1].distance_to(point), list_neighbors))
            num_new_distance = min(list_distances)

            if num_current_distance < num_new_distance:
                return point_current

            # Update current distance
            num_current_distance = num_new_distance

            # Update point_current
            index_of_new_distance = list_distances.index(num_new_distance)
            point_current = list_neighbors[index_of_new_distance][1]

            # Update set_a
            for neighbor in list_neighbors:
                set_a.discard(neighbor)

            # Update list_neighbors
            filter_only_a_marked_points = filter(
                lambda x: x[1] in set_a,
                self.graph.get_neighbours_list(point_current))
            list_neighbors = list(filter_only_a_marked_points)

        return point_current

    def __correct_graph_structure(self, list_pointsToCorrect: list):
        """
        This method corrects connections of each point in list_pointsToCorrect
        NEED TO MODIFY. DANGER OF LOSS OF CONNECTIONS BETWEEN PARTS OF GRAPH
        :return: none
        """
        for point in list_pointsToCorrect:
            # Get neighbors of point
            list_tuples_current_neighbors = self.graph.get_neighbours_list(
                point)

            # Get distance to nearest neighbor
            if len(list_tuples_current_neighbors
                   ) == 0 or list_tuples_current_neighbors is None:
                self.add_point(point)
示例#2
0
class NRA(Algorithm):

    # noinspection PyMissingConstructor
    def __init__(self):
        self.graph = Graph()
        self.cache = None
        pass

    """
        Вычисляем расстояние от добавляемой точки до всех имеющихся точек.
        Добавляем ближайшую в список соседей
    """

    def add_point(self, point: Point):
        if len(self.graph) == 0:
            self.cache = point
            self.graph.add_point(point)
            return
        elif len(self.graph) == 1:
            fp = self.graph.get_points()[0]
            self.graph.add_point(point, fp)
            self.graph.set_neighbours(fp, point)
            return
        distances = self.graph.get_distance_to(point)
        neighbours = set()

        for index in range(len(distances)):
            add_flag = True
            verifiable_cluster = distances[index][1]
            dist = distances[index][0]
            for neighbour in neighbours:
                dist_to_ngh = neighbour.distance_to(verifiable_cluster)
                if dist >= dist_to_ngh:
                    add_flag = False
                    break

            if add_flag:
                neighbours.add(verifiable_cluster)

        if len(neighbours) == 0:
            neighbours.add(distances[0][1])
            neighbours = self.__check_crossing(point, neighbours)
            self.graph.add_point(point, neighbours)
        else:
            neighbours = self.__check_crossing(point, neighbours)
            self.graph.add_point(point, neighbours)

        pass

    def __check_crossing(self, new_point, neighbours_of_new):
        for neighbour in copy(neighbours_of_new):
            neighbours_of_current = self.graph.get_neighbours(neighbour)
            for ngh_o_c in neighbours_of_current:
                if new_point.distance_to(neighbour) < ngh_o_c.distance_to(neighbour) and \
                        new_point.distance_to(ngh_o_c) < ngh_o_c.distance_to(neighbour):
                    neighbours_of_new.add(ngh_o_c)
                    self.graph.delete_neighbours(neighbour, ngh_o_c)
                    self.graph.delete_neighbours(ngh_o_c, neighbour)
        return neighbours_of_new

    def __check_relationship(self, point_set: set):
        for point in point_set:
            test_set = set()
            new_check_set = set()
            neighbours = self.graph.get_distance_to(point)
            test_set.add(neighbours[1][1])
            for index in range(2, len(neighbours)):
                add_flag = True
                for test_point in test_set:
                    if neighbours[index][0] > test_point.distance_to(
                            neighbours[index][1]):
                        add_flag = False
                        new_check_set.add(neighbours[index][1])
                        break
                if add_flag:
                    test_set.add(neighbours[index][1])

            if len(new_check_set) != 0:
                self.graph.set_neighbours(point, test_set)

    def delete_point(self, point: Point):
        if len(self.graph) < 2:
            self.graph.remove_point(point)
        else:
            if point == self.cache:
                self.cache = self.graph.get_points()[0]
            neighbours = self.graph.get_neighbours_list(point)
            self.graph.remove_point(point)
            self.__check_relationship(neighbours)
        pass

    def find_nearest_to(self, point: Point):
        current = self.cache
        temp = None
        minimal = point.distance_to(current)
        cluster_set = {x for x in self.graph.get_points()}
        cluster_set.discard(current)
        while True:
            the_smallest = float('inf')
            neighbours = self.graph.get_neighbours(current)
            cluster_set.difference_update(neighbours)
            for neighbour in neighbours:
                dist = neighbour.distance_to(point)
                if dist < the_smallest:
                    the_smallest = dist
                    temp = neighbour
            # noinspection PyChainedComparisons
            if the_smallest < minimal and len(
                    cluster_set) != 0 and minimal != 0:
                minimal = the_smallest
                current = temp
            else:
                break
        self.cache = current
        return current
        pass
class NRA(Algorithm):

    # noinspection PyMissingConstructor
    def __init__(self):
        self.graph = Graph()
        self.cache = None
        pass

    """
        Вычисляем расстояние от добавляемой точки до всех имеющихся точек.
        Добавляем ближайшую в список соседей
    """

    def add_point(self, point: Point):
        if len(self.graph) == 0:
            self.cache = point
            self.graph.add_point(point)
            return
        elif len(self.graph) == 1:
            fp = self.graph.get_points()[0]
            self.graph.add_point(point, fp)
            self.graph.set_neighbours(fp, point)
            return
        distances = self.graph.get_distance_to(point)
        neighbours = set()

        for index in range(len(distances)):
            add_flag = True
            verifiable_cluster = distances[index][1]
            dist = distances[index][0]
            for neighbour in neighbours:
                dist_to_ngh = neighbour.distance_to(verifiable_cluster)
                if dist >= dist_to_ngh:
                    add_flag = False
                    break

            if add_flag:
                neighbours.add(verifiable_cluster)

        if len(neighbours) == 0:
            neighbours.add(distances[0][1])
            self.graph.add_point(point, neighbours)
        else:
            self.graph.add_point(point, neighbours)
        pass

    def delete_point(self, point: Point):
        if len(self.graph) < 3:
            isolated_points = self.graph.remove_point(point)
            for p in isolated_points:
                self.graph.remove_point(p)
                self.add_point(p)
        elif self.graph.is_in_graph(point):
            neighbours = self.graph.get_neighbours(point)
            self.graph.remove_point(point)
            for neighbour in neighbours:
                isolated_points = self.graph.remove_point(neighbour)
                for p in isolated_points:
                    self.graph.remove_point(p)
                    self.add_point(p)
                self.add_point(neighbour)
        pass

    def find_nearest_to(self, point: Point):
        current = self.cache
        temp = None
        minimal = point.distance_to(current)
        cluster_set = {x for x in self.graph.get_points()}
        cluster_set.discard(current)
        while True:
            the_smallest = float('inf')
            neighbours = self.graph.get_neighbours(current)
            cluster_set.difference_update(neighbours)
            for neighbour in neighbours:
                dist = neighbour.distance_to(point)
                if dist < the_smallest:
                    the_smallest = dist
                    temp = neighbour
            # noinspection PyChainedComparisons
            if the_smallest < minimal and len(
                    cluster_set) != 0 and minimal != 0:
                minimal = the_smallest
                current = temp
            else:
                break
        self.cache = current
        return current
        pass