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()
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() ]
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
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)
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
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)
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!")
def addEdge(self, edge: HyperEdge): self.vertices |= edge.getVertices() self.edges.append(edge)
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