Пример #1
0
    def apply(self,
              graph: Graph,
              prod_input: List[str],
              orientation: int = 0,
              **kwargs) -> List[str]:

        self.__check_prod_input(graph, prod_input)

        overlapping_vertices = find_overlapping_vertices(graph)[0]
        layer = graph.nodes()[prod_input[0]]['layer']

        neighbours = set()
        for interior in prod_input:
            neighbours |= set(get_neighbors_at(graph, interior, layer))

        vertices_to_join = [
            neighbour for neighbour in neighbours if graph.nodes()[neighbour]
            ['position'] == graph.nodes()[overlapping_vertices[0]]['position']
        ]

        if len(vertices_to_join) == 2:
            join_overlapping_vertices(graph, vertices_to_join[0],
                                      vertices_to_join[1], layer)

        return prod_input
Пример #2
0
def __pull_overlapping_vertices_towards_neighbors(graph: Graph, factor: float):
    overlapping = find_overlapping_vertices(graph)

    to_pull_apart = set()
    for a, b in overlapping:
        to_pull_apart.add(a)
        to_pull_apart.add(b)

    for n in to_pull_apart:
        pull_vertex_towards_neighbors(graph, n, factor)
Пример #3
0
    def __check_prod_input(graph, prod_input):

        if len(set(prod_input)) != 4:
            raise ValueError('too few interiors')
        layer = graph.nodes()[prod_input[0]]['layer']
        if any(graph.nodes()[interior]['layer'] != layer
               for interior in prod_input[1:]):
            raise ValueError('interior vertices come from different layers')
        if any(graph.nodes()[interior]['label'] != 'I'
               for interior in prod_input):
            raise ValueError('interior vertices must have I label')

        all_neighbours = []

        for interior in prod_input:
            interior_neighbours = get_neighbors_at(graph, interior, layer)
            if len(interior_neighbours) != 3:
                raise ValueError('wrongly connected interior vertices')

            for neighbour in interior_neighbours:
                if graph.nodes()[neighbour]['label'] != 'E':
                    raise ValueError(
                        'interior vertices can be connect only with E vertices'
                    )

                all_neighbours.append(neighbour)

        if len(set(all_neighbours)) != 6:
            raise ValueError('incorrect number of E vertices')

        overlapping_vertices = find_overlapping_vertices(graph)

        if len(overlapping_vertices) != 2 or \
                any(overlapping_vertice1 not in set(all_neighbours)
                    or overlapping_vertice2 not in set(all_neighbours)
                    for overlapping_vertice1, overlapping_vertice2 in overlapping_vertices):
            raise ValueError('incorrect shape of graph')
Пример #4
0
    def __check_prod_input(graph, prod_input):

        if len(set(prod_input)) != 3:
            raise ValueError('too few interiors')
        layer = graph.nodes()[prod_input[0]]['layer']
        if any(graph.nodes()[interior]['layer'] != layer
               for interior in prod_input[1:]):
            raise ValueError('interior vertices come from different layers')
        if any(graph.nodes()[interior]['label'] != 'I'
               for interior in prod_input):
            raise ValueError('interior vertices must have I label')

        all_I_neighbours = []

        for interior in prod_input:
            interior_neighbours = get_neighbors_at(graph, interior, layer)
            if len(interior_neighbours) not in [2, 3]:
                raise ValueError('wrongly connected interior vertices')

            for neighbour in interior_neighbours:
                if graph.nodes()[neighbour]['label'] != 'E':
                    raise ValueError(
                        'interior vertices can be connect only with E vertices'
                    )

                all_I_neighbours.append(neighbour)

        E_vertices = get_vertices_from_layer(graph, layer, "E")
        E_vertices_position_prev_layer = []
        if any(E_vertice not in all_I_neighbours for E_vertice in E_vertices):
            raise ValueError('wrongly connected E vertices')
        for E_vertice in E_vertices:
            E_vertice_neighbours = get_neighbors_at(graph, E_vertice, layer)
            if len([
                    I_node for I_node in E_vertice_neighbours
                    if graph.nodes()[I_node]['label'] == "I"
            ]) not in [1, 2]:
                raise ValueError(
                    'each E vertice must be connected with I vertice')
            E_vertice_E_neighbours = [
                neighbour for neighbour in E_vertice_neighbours
                if graph.nodes()[neighbour]['label'] == "E"
            ]
            if len(E_vertice_E_neighbours) not in [1, 2, 3]:
                raise ValueError(
                    'each E vertice must be connected with at least one E vertice'
                )
            corresponding_vertice = get_node_at(
                graph, layer - 1,
                graph.nodes()[E_vertice]['position'])
            if corresponding_vertice is not None:
                E_vertices_position_prev_layer.append(corresponding_vertice)

        if len(E_vertices_position_prev_layer) != 4 and len(
                E_vertices_position_prev_layer) != 6:
            raise ValueError(
                'positions of corresponding vertices between layers are incorrect'
            )
        corresponding_positions = [
            graph.nodes()[E_vertice]['position']
            for E_vertice in E_vertices_position_prev_layer
        ]
        noncorresponding_E_vertices = [
            E_vertice for E_vertice in E_vertices if graph.nodes()[E_vertice]
            ['position'] not in corresponding_positions
        ]
        possible_positions = []
        for i in range(len(corresponding_positions) - 1):
            x1, y1 = corresponding_positions[i]
            for j in range(i + 1, len(corresponding_positions)):
                x2, y2 = corresponding_positions[j]
                possible_positions.append(((x1 + x2) / 2, (y1 + y2) / 2))
        for E_vertice in noncorresponding_E_vertices:
            x, y = graph.nodes()[E_vertice]['position']
            if (x, y) not in possible_positions:
                raise ValueError(
                    'position of noncorresponding vertice is incorrect')

        overlapping_vertices = find_overlapping_vertices(graph)

        if len(overlapping_vertices) != 4 or \
                any(overlapping_vertice1 not in set(all_I_neighbours)
                    or overlapping_vertice2 not in set(all_I_neighbours)
                    for overlapping_vertice1, overlapping_vertice2 in overlapping_vertices):
            raise ValueError('incorrect shape of graph')

        vertices_to_join = set()
        for overlapping_vertice1, overlapping_vertice2 in overlapping_vertices:
            vertices_to_join.add(overlapping_vertice1)
            vertices_to_join.add(overlapping_vertice2)

        if len(vertices_to_join) != 4:
            raise ValueError('too many overlapping vertices')

        vertices_to_join_group1 = [
            vertice for vertice in vertices_to_join
            if graph.nodes()[vertice]['position'] == graph.nodes()[list(
                vertices_to_join)[0]]['position']
        ]
        vertices_to_join_group2 = [
            vertice for vertice in vertices_to_join
            if vertice not in vertices_to_join_group1
        ]

        if len(vertices_to_join_group1) != 2 or len(
                vertices_to_join_group2) != 2:
            raise ValueError('too many overlapping vertices')

        vertice1_neighbours = get_neighbors_at(graph,
                                               vertices_to_join_group1[0],
                                               layer)
        vertice2_neighbours = get_neighbors_at(graph,
                                               vertices_to_join_group1[1],
                                               layer)
        vertice3_neighbours = get_neighbors_at(graph,
                                               vertices_to_join_group2[0],
                                               layer)
        vertice4_neighbours = get_neighbors_at(graph,
                                               vertices_to_join_group2[1],
                                               layer)

        I_neighbours_vertice1 = [
            neighbour for neighbour in vertice1_neighbours
            if graph.nodes()[neighbour]['label'] == "I"
        ]
        I_neighbours_vertice2 = [
            neighbour for neighbour in vertice2_neighbours
            if graph.nodes()[neighbour]['label'] == "I"
        ]
        I_neighbours_vertice3 = [
            neighbour for neighbour in vertice3_neighbours
            if graph.nodes()[neighbour]['label'] == "I"
        ]
        I_neighbours_vertice4 = [
            neighbour for neighbour in vertice4_neighbours
            if graph.nodes()[neighbour]['label'] == "I"
        ]

        if len(I_neighbours_vertice1) != 1 or len(I_neighbours_vertice2) != 1 or \
            len(I_neighbours_vertice3) != 1 or len(I_neighbours_vertice4) != 1:
            raise ValueError(
                'vertices to join wrongly connected with I vertices')

        common_I_neighbour_vertices_to_join = []
        if I_neighbours_vertice1 == I_neighbours_vertice3:
            common_I_neighbour_vertices_to_join.append(
                vertices_to_join_group1[0])
            common_I_neighbour_vertices_to_join.append(
                vertices_to_join_group2[0])
        elif I_neighbours_vertice1 == I_neighbours_vertice4:
            common_I_neighbour_vertices_to_join.append(
                vertices_to_join_group1[0])
            common_I_neighbour_vertices_to_join.append(
                vertices_to_join_group2[1])
        elif I_neighbours_vertice2 == I_neighbours_vertice3:
            common_I_neighbour_vertices_to_join.append(
                vertices_to_join_group1[1])
            common_I_neighbour_vertices_to_join.append(
                vertices_to_join_group2[0])
        elif I_neighbours_vertice2 == I_neighbours_vertice4:
            common_I_neighbour_vertices_to_join.append(
                vertices_to_join_group1[1])
            common_I_neighbour_vertices_to_join.append(
                vertices_to_join_group2[1])
        else:
            raise ValueError(
                'vertices to join wrongly connected with I vertices')

        noncommon_I_neighbour_vertices_to_join = [
            vertice for vertice in vertices_to_join
            if vertice not in common_I_neighbour_vertices_to_join
        ]
        if len(noncommon_I_neighbour_vertices_to_join) != 2:
            raise ValueError(
                'vertices to join wrongly connected with I vertices')
        if len(
                set(common_I_neighbour_vertices_to_join).intersection(
                    set(noncommon_I_neighbour_vertices_to_join))) != 0:
            raise ValueError('vertices to join wrongly connected')

        common_vertice1_neighbours = get_neighbors_at(
            graph, common_I_neighbour_vertices_to_join[0], layer)
        common_vertice2_neighbours = get_neighbors_at(
            graph, common_I_neighbour_vertices_to_join[1], layer)

        if common_I_neighbour_vertices_to_join[
                1] not in common_vertice1_neighbours:
            raise ValueError(
                'vertices to join with common I neighbour are not connected')
        if len(
                set(common_vertice1_neighbours).intersection(
                    set(common_vertice2_neighbours))) not in [1, 2]:
            raise ValueError(
                'vertices to join with common I neighbour are wrongly connected'
            )

        noncommon_vertice1_neighbours = get_neighbors_at(
            graph, noncommon_I_neighbour_vertices_to_join[0], layer)
        noncommon_vertice2_neighbours = get_neighbors_at(
            graph, noncommon_I_neighbour_vertices_to_join[1], layer)

        if noncommon_I_neighbour_vertices_to_join[
                1] in noncommon_vertice1_neighbours:
            raise ValueError(
                'vertices to join with non-common I neighbour are connected')
        if len(
                set(noncommon_vertice1_neighbours).intersection(
                    set(noncommon_vertice2_neighbours))) not in [1, 2]:
            raise ValueError(
                'vertices to join with common I neighbour are wrongly connected'
            )
Пример #5
0
    def apply(self,
              graph: Graph,
              prod_input: List[str],
              orientation: int = 0,
              **kwargs) -> List[str]:
        self.__check_prod_input(graph, prod_input)

        layer = graph.nodes()[prod_input[0]]['layer']
        overlapping_vertices = find_overlapping_vertices(graph)
        vertices_to_join = set()
        for overlapping_vertice1, overlapping_vertice2 in overlapping_vertices:
            vertices_to_join.add(overlapping_vertice1)
            vertices_to_join.add(overlapping_vertice2)

        vertices_to_join_group1 = [
            vertice for vertice in vertices_to_join
            if graph.nodes()[vertice]['position'] == graph.nodes()[list(
                vertices_to_join)[0]]['position']
        ]
        vertices_to_join_group2 = [
            vertice for vertice in vertices_to_join
            if vertice not in vertices_to_join_group1
        ]

        vertice1_group1_neighbours = get_neighbors_at(
            graph, vertices_to_join_group1[0], layer)
        vertice2_group1_neighbours = get_neighbors_at(
            graph, vertices_to_join_group1[1], layer)
        vertice1_group2_neighbours = get_neighbors_at(
            graph, vertices_to_join_group2[0], layer)
        vertice2_group2_neighbours = get_neighbors_at(
            graph, vertices_to_join_group2[1], layer)

        vertice1_group1_I_neighbours = [
            neighbour for neighbour in vertice1_group1_neighbours
            if graph.nodes()[neighbour]['label'] == "I"
        ]
        vertice2_group1_I_neighbours = [
            neighbour for neighbour in vertice2_group1_neighbours
            if graph.nodes()[neighbour]['label'] == "I"
        ]
        vertice1_group2_I_neighbours = [
            neighbour for neighbour in vertice1_group2_neighbours
            if graph.nodes()[neighbour]['label'] == "I"
        ]
        vertice2_group2_I_neighbours = [
            neighbour for neighbour in vertice2_group2_neighbours
            if graph.nodes()[neighbour]['label'] == "I"
        ]

        common_I_neighbour_vertices_to_join = []
        if vertice1_group1_I_neighbours == vertice1_group2_I_neighbours:
            common_I_neighbour_vertices_to_join.append(
                vertices_to_join_group1[0])
            common_I_neighbour_vertices_to_join.append(
                vertices_to_join_group2[0])
        elif vertice1_group1_I_neighbours == vertice2_group2_I_neighbours:
            common_I_neighbour_vertices_to_join.append(
                vertices_to_join_group1[0])
            common_I_neighbour_vertices_to_join.append(
                vertices_to_join_group2[1])
        elif vertice2_group1_I_neighbours == vertice1_group2_I_neighbours:
            common_I_neighbour_vertices_to_join.append(
                vertices_to_join_group1[1])
            common_I_neighbour_vertices_to_join.append(
                vertices_to_join_group2[0])
        elif vertice2_group1_I_neighbours == vertice2_group2_I_neighbours:
            common_I_neighbour_vertices_to_join.append(
                vertices_to_join_group1[1])
            common_I_neighbour_vertices_to_join.append(
                vertices_to_join_group2[1])

        if graph.has_edge(common_I_neighbour_vertices_to_join[0],
                          common_I_neighbour_vertices_to_join[1]):
            graph.remove_edge(common_I_neighbour_vertices_to_join[0],
                              common_I_neighbour_vertices_to_join[1])

        join_overlapping_vertices(graph, vertices_to_join_group1[0],
                                  vertices_to_join_group1[1], layer)
        join_overlapping_vertices(graph, vertices_to_join_group2[0],
                                  vertices_to_join_group2[1], layer)

        return prod_input
Пример #6
0
    def __check_prod_input(graph, prod_input):

        if len(set(prod_input)) != 4:
            raise ValueError('too few interiors')
        layer = graph.nodes()[prod_input[0]]['layer']
        if any(graph.nodes()[interior]['layer'] != layer
               for interior in prod_input[1:]):
            raise ValueError('interior vertices come from different layers')
        if any(graph.nodes()[interior]['label'] != 'I'
               for interior in prod_input):
            raise ValueError('interior vertices must have I label')

        all_I_neighbours = []

        for interior in prod_input:
            interior_neighbours = get_neighbors_at(graph, interior, layer)
            if len(interior_neighbours) not in [2, 3]:
                raise ValueError('wrongly connected interior vertices')

            for neighbour in interior_neighbours:
                if graph.nodes()[neighbour]['label'] != 'E':
                    raise ValueError(
                        'interior vertices can be connect only with E vertices'
                    )

                all_I_neighbours.append(neighbour)

        E_vertices = get_vertices_from_layer(graph, layer, 'E')
        E_vertices_position_prev_layer = []
        if any(E_vertice not in all_I_neighbours for E_vertice in E_vertices):
            raise ValueError('wrongly connected E vertices')
        for E_vertice in E_vertices:
            E_vertice_neighbours = get_neighbors_at(graph, E_vertice, layer)
            if len([
                    I_node for I_node in E_vertice_neighbours
                    if graph.nodes()[I_node]['label'] == "I"
            ]) != 2:
                raise ValueError(
                    'each E vertice must be connected with two I vertices')
            E_vertice_E_neighbours = [
                neighbour for neighbour in E_vertice_neighbours
                if graph.nodes()[neighbour]['label'] == "E"
            ]
            if len(E_vertice_E_neighbours) not in [1, 2, 3, 4]:
                print(len(E_vertice_E_neighbours))
                raise ValueError(
                    'each E vertice must be connected with at least one E vertice'
                )
            corresponding_vertice = get_node_at(
                graph, layer - 1,
                graph.nodes()[E_vertice]['position'])
            if corresponding_vertice is not None:
                E_vertices_position_prev_layer.append(corresponding_vertice)

        if len(E_vertices_position_prev_layer) != 2 and len(
                E_vertices_position_prev_layer) != 4:
            raise ValueError(
                'positions of corresponding vertices between layers are incorrect'
            )
        corresponding_positions = [
            graph.nodes()[E_vertice]['position']
            for E_vertice in E_vertices_position_prev_layer
        ]
        noncorresponding_E_vertices = [
            E_vertice for E_vertice in E_vertices if graph.nodes()[E_vertice]
            ['position'] not in corresponding_positions
        ]
        possible_positions = []
        for i in range(len(corresponding_positions) - 1):
            x1, y1 = corresponding_positions[i]
            for j in range(i + 1, len(corresponding_positions)):
                x2, y2 = corresponding_positions[j]
                possible_positions.append(((x1 + x2) / 2, (y1 + y2) / 2))
        for E_vertice in noncorresponding_E_vertices:
            x, y = graph.nodes()[E_vertice]['position']
            if (x, y) not in possible_positions:
                raise ValueError(
                    'positions of noncorresponding vertices are incorrect')

        overlapping_vertices = find_overlapping_vertices(graph)

        if len(overlapping_vertices) != 2 or \
                any(overlapping_vertice1 not in set(all_I_neighbours)
                    or overlapping_vertice2 not in set(all_I_neighbours)
                    for overlapping_vertice1, overlapping_vertice2 in overlapping_vertices):
            raise ValueError('incorrect shape of graph')

        vertices_to_join = [
            neighbour for neighbour in set(all_I_neighbours)
            if graph.nodes()[neighbour]['position'] == graph.nodes()[
                overlapping_vertices[0][0]]['position']
        ]

        if len(vertices_to_join) != 2:
            raise ValueError('too many overlapping vertices')

        vertice1_neighbours = get_neighbors_at(graph, vertices_to_join[0],
                                               layer)
        vertice2_neighbours = get_neighbors_at(graph, vertices_to_join[1],
                                               layer)

        common_neighbours = set(vertice1_neighbours).intersection(
            set(vertice2_neighbours))

        if len(common_neighbours) != 2:
            raise ValueError('vertices to join wrongly connected')

        I_neighbours_vertice1 = [
            neighbour for neighbour in vertice1_neighbours
            if graph.nodes()[neighbour]['label'] == "I"
        ]
        I_neighbours_vertice2 = [
            neighbour for neighbour in vertice2_neighbours
            if graph.nodes()[neighbour]['label'] == "I"
        ]

        if len(I_neighbours_vertice1) != 2 or len(I_neighbours_vertice2) != 2:
            raise ValueError(
                'vertices to join wrongly connected with I vertices')

        if len(set(I_neighbours_vertice1).intersection(
                I_neighbours_vertice2)) != 0:
            raise ValueError('vertices to join have common I neighbour')
Пример #7
0
def __pull__overlapping_vertices_apart(graph: Graph, factor: float):
    overlapping = find_overlapping_vertices(graph)

    for a, b in overlapping:
        pull_vertices_apart(graph, a, b, factor)