@Override public void addEdge(Edge edge) { checkInTransaction(); if (edge == null) { throw new IllegalArgumentException("edge must not be null"); } Vertex source = edge.getSource(); Vertex target = edge.getTarget(); // Validate to ensure the model does not become corrupted. int si = vertexList.indexOf(source); int ti = vertexList.indexOf(target); if (si == -1 || ti == -1 || si >= adjacencies.size() || ti >= adjacencies.size()) { throw new IllegalStateException("vertices not in model"); } if (source.equals(target)) { throw new IllegalStateException("edge endpoints are same"); } if (findEdge(source, target) != null || (!edge.isDirected() && findEdge(target, source) != null)) { throw new IllegalArgumentException("edge already exists"); } // Add the new edge to the list and make the source vertex // adjacent to the target vertex. If the edge is undirected, // then make target adjacent to source, as well. edgeList.add(edge); addAdjacency(source, target); if (!edge.isDirected()) { addAdjacency(target, source); } fireModelEvent(new ModelEvent(this, ModelEventType.EDGE_ADDED)); fireUndoableEdit(new EdgeAddUndoableEdit(this, edge)); }
public boolean isViolatedBy(Graph graph) { for (Edge edge : graph.getEdges()) { if (!edge.isDirected()) { continue; } Node from = Edges.getDirectedEdgeTail(edge); Node to = Edges.getDirectedEdgeHead(edge); if (isForbidden(from.getName(), to.getName())) { return true; } } return false; }
@Override public Edge findEdge(Vertex source, Vertex target) { if (source == null || target == null || source == target) { return null; } int si = vertexList.indexOf(source); int ti = vertexList.indexOf(target); if (si == -1 || ti == -1) { return null; } // Perform a quick search of the adjlist, to see if the edge exists. int[] list = adjacencies.get(si); if (list == null) { list = adjacencies.get(ti); if (list == null) { return null; } ti = si; } int ii; for (ii = 0; ii < list.length; ii++) { if (list[ii] == ti) { break; } } if (ii == list.length) { return null; } // Look through all of the edges, looking for one whose "source" // and "target" match the parameters. for (Edge edge : edgeList) { if (edge.getSource().equals(source) && edge.getTarget().equals(target)) { return edge; } // If the edge is undirected, then we can match // the source and target in the reverse order. if (!edge.isDirected() && edge.getSource().equals(target) && edge.getTarget().equals(source)) { return edge; } } return null; }
@Override public void removeEdge(Edge edge) { checkInTransaction(); if (edge == null) { throw new IllegalArgumentException("edge must not be null"); } if (!edgeList.remove(edge)) { throw new IllegalArgumentException("edge not in model"); } // Remove the connections from the adjancency list. Vertex source = edge.getSource(); Vertex target = edge.getTarget(); removeAdjacency(source, target); if (!edge.isDirected()) { removeAdjacency(target, source); } fireModelEvent(new ModelEvent(this, ModelEventType.EDGE_REMOVED)); fireUndoableEdit(new EdgeRemoveUndoableEdit(this, edge)); }
@Override public IVertexSequence<V> next() { if (!hasNext()) throw new NoSuchElementException(); // Generate a weighted random walk starting at vertex order[current] int currVertexIdx = order[position++]; int[] indices = new int[walkLength + 1]; indices[0] = currVertexIdx; if (walkLength == 0) return new VertexSequence<>(graph, indices); for (int i = 1; i <= walkLength; i++) { List<? extends Edge<? extends Number>> edgeList = graph.getEdgesOut(currVertexIdx); // First: check if there are any outgoing edges from this vertex. If not: handle the situation if (edgeList == null || edgeList.size() == 0) { switch (mode) { case SELF_LOOP_ON_DISCONNECTED: for (int j = i; j < walkLength; j++) indices[j] = currVertexIdx; return new VertexSequence<>(graph, indices); case EXCEPTION_ON_DISCONNECTED: throw new NoEdgesException( "Cannot conduct random walk: vertex " + currVertexIdx + " has no outgoing edges. " + " Set NoEdgeHandling mode to NoEdgeHandlingMode.SELF_LOOP_ON_DISCONNECTED to self loop instead of " + "throwing an exception in this situation."); default: throw new RuntimeException("Unknown/not implemented NoEdgeHandling mode: " + mode); } } // To do a weighted random walk: we need to know total weight of all outgoing edges double totalWeight = 0.0; for (Edge<? extends Number> edge : edgeList) { totalWeight += edge.getValue().doubleValue(); } double d = rng.nextDouble(); double threshold = d * totalWeight; double sumWeight = 0.0; for (Edge<? extends Number> edge : edgeList) { sumWeight += edge.getValue().doubleValue(); if (sumWeight >= threshold) { if (edge.isDirected()) { currVertexIdx = edge.getTo(); } else { if (edge.getFrom() == currVertexIdx) { currVertexIdx = edge.getTo(); } else { currVertexIdx = edge .getFrom(); // Undirected edge: might be next--currVertexIdx instead of // currVertexIdx--next } } indices[i] = currVertexIdx; break; } } } return new VertexSequence<>(graph, indices); }
/** * Checks if an edge leaves this node. Utility method that can be useful in subclasses. * * @param e an edge * @return {@code true} if {@code e} is leaving edge for this node. */ public boolean isLeavingEdge(Edge e) { return e.getSourceNode() == this || (!e.isDirected() && e.getTargetNode() == this); }