Esempio n. 1
0
    def deleteVertex(self, vertex: CanvasVertex) -> None:
        HyperEdge.deleteVertex(self, vertex)
        for vertex in self.vertices:
            if type(vertex) is Vertex:
                return
        if self.getDegree() > 2:
            self.grahamConvex()

        self.draw()
        self.update()
Esempio n. 2
0
 def _copy_constructor(self, other: HyperGraph):
     self.vertices = {Vertex(other=v) for v in other.getVertices()}
     self.edges = [
         HyperEdge(*({v
                      for v in self.vertices if v in e.getVertices()}))
         for e in other.getEdges()
     ]
Esempio n. 3
0
    def __init__(self, *vertices, **kwargs):
        # TODO redo

        QtWidgets.QGraphicsPathItem.__init__(self)

        if 'other' in kwargs:
            edge = kwargs.pop('other')
            if type(edge) == HyperEdge:
                vertices = {CanvasVertex(other=v) for v in edge.getVertices()}
                HyperEdge.__init__(self, *vertices)
            else:
                HyperEdge.__init__(self, other=edge)
        else:
            vertices = {CanvasVertex(other=x) for x in vertices}
            HyperEdge.__init__(self, *vertices)
            # HyperEdge.__init__(self, *[CanvasVertex(vertex, self) for vertex in vertices], **kwargs)

        self.real_point_gap = 50.

        self.default_pen = QtGui.QPen()
        self.setPen(self.default_pen)

        self.hovered_pen = QtGui.QPen()
        self.hovered_pen.setColor(QtCore.Qt.red)

        self.hovered_brush = QtGui.QBrush()
        self.hovered_brush.setColor(QtCore.Qt.red)

        self.default_brush = QtGui.QBrush()
        # self.score = 0
        self.setBrush(self.hovered_brush)

        self.support_convex = []
        self.setAcceptHoverEvents(True)
        self.multiplicity = 1
Esempio n. 4
0
    def __buildHyperEdge(self, node):
        """
    Use:
      Creates a complex abstraction of the hyperedge. 
      1) HyperEdge --> Represends the multiple sources/outputs of the edge
      2) HyperNode --> Represents just the center of the edge
      3) HyperEdgeComponent --> Represents each source-target pair as a directed
                                edge.
    Parameter:
      node is an ASGNode of the AToM3 variety, representing a hyper-edge
      
    NOTE: AToM3 dependent method
    """
        semObj2NodeMap = AbstractNode.SemanticObject2NodeMap

        # Create a HyperEdge "master" for this edge's representation
        hyperEdge = HyperEdge(node)
        self.__HyperEdgeList.append(hyperEdge)

        # Create a new HyperNode representing the center of the hyperedge
        hyperNode = HyperNode(node, hyperEdge)
        self.__HyperEdgeNodeList.append(hyperNode)
        semObj2NodeMap[node] = hyperNode

        #===============================================================================
        #    Create HyperEdgeComponent, a set of directed edges equivelent to
        #    the original hyper edge
        #===============================================================================
        # Source object incomming to the hyperedge center
        direction = HyperEdgeComponent.SOURCE2CENTER
        i = 0
        for i in range(0, len(node.in_connections_)):
            sourceSemObj = node.in_connections_[i]
            sourceTargetTuple = (semObj2NodeMap[sourceSemObj], hyperNode)

            hyperEdgeComponent = HyperEdgeComponent(node, sourceTargetTuple,
                                                    hyperEdge, direction, i)
            self.__HyperEdgeComponentList.append(hyperEdgeComponent)

        # Hyperedge center outgoing to the target object
        direction = HyperEdgeComponent.CENTER2TARGET
        i = 0
        for i in range(0, len(node.out_connections_)):
            targetSemObj = node.out_connections_[i]
            sourceTargetTuple = (hyperNode, semObj2NodeMap[targetSemObj])

            hyperEdgeComponent = HyperEdgeComponent(node, sourceTargetTuple,
                                                    hyperEdge, direction, i)
            self.__HyperEdgeComponentList.append(hyperEdgeComponent)
Esempio n. 5
0
def loadSampleHyperGraph():
    h = HyperGraph()
    # vertices = [Vertex(i) for i in range(1, 9)]
    # h.addVertices(vertices)
    edges = [
        (1, 2),
        (2, 8),
        (2, 7, 4),
        (4, 8),
        (8, 6),
        (8, 5, 6),
        (6, 3)
    ]
    edges = [HyperEdge(*[Vertex(x) for x in vertices]) for vertices in edges]
    h.addEdges(edges)
    # h.addVertex(Vertex('ok'))
    return h
Esempio n. 6
0
    def loadJson(self, file):
        hg_dict = json.loads(file.read())
        if 'edges' in hg_dict:
            for edge_dict in hg_dict['edges']:
                vertices = []
                for vertex_dict in edge_dict['vertices']:
                    vertex = Vertex(vertex_dict['id'])
                    # TODO проверять на повторяющиеся вершины
                    vertices.append(vertex)
                edge = HyperEdge(*vertices)
                self.addEdge(edge)
                self.addVertices(set(vertices))

        if 'vertices' in hg_dict:
            for vertex_dict in hg_dict['vertices']:
                vertex = Vertex(vertex_dict['id'])
                self.addVertex(vertex)
Esempio n. 7
0
 def toEdge(self):
     if hasattr(self, 'v1') and hasattr(self, 'v2'):
         return HyperEdge(self.v1, self.v2)
     else:
         raise ValueError("Impossible to construct edge from one vertex!")
Esempio n. 8
0
 def addEdge(self, edge: HyperEdge):
     self.vertices |= edge.getVertices()
     self.edges.append(edge)
Esempio n. 9
0
    def isContractable(self, with_linear_condition=False):
        """
            using simple algorithm
        """
        # TODO
        if not self.isConnected() or not self.edges:
            return False

        edges = self.edges
        vertices = self.vertices
        delete_stack = [
        ]  # deleted edges would be placed there (index_of_edge, complex_vertex)
        edge_to_start_with = 0

        EdgeDeletion = namedtuple('EdgeDeletion', [
            'index', 'new_vertex', 'first_vertex', 'second_vertex',
            'first_indices', 'second_indices'
        ])

        while len(vertices) > 1:
            edge_deleted = False
            for i, edge in enumerate(
                    edges[edge_to_start_with:]):  # search edge to delete
                if edge.getDegree() == 2:
                    vertices_to_contract = edge.getVertices()
                    first_vertex_to_contract, second_vertex_to_contract = tuple(
                        vertices_to_contract)
                    new_vertex = first_vertex_to_contract + second_vertex_to_contract
                    first_indices = []
                    second_indices = []

                    for j, reducing_edge in enumerate(edges):
                        if edge is reducing_edge:
                            continue

                        reducing_edge_vertices = reducing_edge.getVertices()
                        if not reducing_edge_vertices.isdisjoint(
                                vertices_to_contract):
                            common_vertices = reducing_edge_vertices & vertices_to_contract
                            if len(common_vertices) == 1:
                                common_vertex = common_vertices.pop()
                                if common_vertex is first_vertex_to_contract:
                                    first_indices.append(j)
                                elif common_vertex is second_vertex_to_contract:
                                    second_indices.append(j)
                                edges[j].deleteVertex(common_vertex)
                                edges[j].addVertex(new_vertex)
                            else:
                                first_indices.append(j)
                                second_indices.append(j)
                                edges[j].deleteVertex(common_vertices.pop())
                                edges[j].deleteVertex(common_vertices.pop())
                                edges[j].addVertex(new_vertex)

                    edges.remove(edge)
                    vertices -= {
                        first_vertex_to_contract, second_vertex_to_contract
                    }
                    vertices.add(new_vertex)
                    # print(HyperGraph(vertices=vertices, edges=edges))
                    delete_stack.append(
                        EdgeDeletion(i + edge_to_start_with, new_vertex,
                                     first_vertex_to_contract,
                                     second_vertex_to_contract, first_indices,
                                     second_indices))
                    edge_deleted = True
                    break

            edge_to_start_with = 0
            if not edge_deleted and delete_stack:  # rollback
                while True:  # edge is not last in the edges list
                    if not delete_stack:
                        return False

                    last_deletion = delete_stack.pop()
                    # restore ComplexVertices in all edges
                    edges.insert(
                        last_deletion.index,
                        HyperEdge(*[
                            last_deletion.first_vertex,
                            last_deletion.second_vertex
                        ]))
                    for i in last_deletion.first_indices:
                        edges[i].replaceVertex(last_deletion.new_vertex,
                                               last_deletion.first_vertex)
                    for i in last_deletion.second_indices:
                        if last_deletion.new_vertex in edges[i].getVertices():
                            edges[i].replaceVertex(last_deletion.new_vertex,
                                                   last_deletion.second_vertex)
                        else:
                            edges[i].addVertex(last_deletion.second_vertex)
                    edge_to_start_with = last_deletion[0] + 1
                    vertices -= {last_deletion.new_vertex}
                    vertices |= {
                        last_deletion.first_vertex, last_deletion.second_vertex
                    }
                    # print(HyperGraph(vertices=vertices, edges=edges))
                    if edge_to_start_with < len(edges):
                        break

        hypergraphs = [
            HyperGraph(
                other=HyperGraph(vertices=vertices.copy(), edges=edges.copy()))
        ]
        while delete_stack:
            edge_deletion = delete_stack.pop()
            edges.insert(
                edge_deletion.index,
                HyperEdge(*[
                    Vertex(other=edge_deletion.first_vertex),
                    Vertex(other=edge_deletion.second_vertex)
                ]))
            for i in edge_deletion.first_indices:
                edges[i].replaceVertex(edge_deletion.new_vertex,
                                       edge_deletion.first_vertex)
            for i in edge_deletion.second_indices:
                if edge_deletion.new_vertex in edges[i].getVertices():
                    edges[i].replaceVertex(edge_deletion.new_vertex,
                                           edge_deletion.second_vertex)
                else:
                    edges[i].addVertex(edge_deletion.second_vertex)
            vertices -= {edge_deletion.new_vertex}
            vertices |= {
                edge_deletion.first_vertex, edge_deletion.second_vertex
            }
            hypergraphs.append(
                HyperGraph(other=HyperGraph(vertices=vertices.copy(),
                                            edges=edges.copy())))

        self.contraction_sequence = reversed(hypergraphs)

        return True