示例#1
0
  /**
   * Simple single-function interface to split and then update a graph
   *
   * @param graph the graph containing the vertices in toMerge
   * @param v The bottom node whose incoming vertices we'd like to split
   * @return true if some useful splitting was done, false otherwise
   */
  public boolean split(final SeqGraph graph, final SeqVertex v) {
    if (graph == null) throw new IllegalArgumentException("graph cannot be null");
    if (v == null) throw new IllegalArgumentException("v cannot be null");
    if (!graph.vertexSet().contains(v))
      throw new IllegalArgumentException("graph doesn't contain vertex v " + v);

    final Collection<SeqVertex> toSplit = graph.incomingVerticesOf(v);
    if (toSplit.size() < 2)
      // Can only split at least 2 vertices
      return false;
    else if (!safeToSplit(graph, v, toSplit)) {
      return false;
    } else {
      final SeqVertex suffixVTemplate = commonSuffix(toSplit);
      if (suffixVTemplate.isEmpty()) {
        return false;
      } else if (wouldEliminateRefSource(graph, suffixVTemplate, toSplit)) {
        return false;
      } else if (allVerticesAreTheCommonSuffix(suffixVTemplate, toSplit)) {
        return false;
      } else {
        final List<BaseEdge> edgesToRemove = new LinkedList<BaseEdge>();

        //                graph.printGraph(new File("split.pre_" + v.getSequenceString() + "." +
        // counter + ".dot"), 0);
        for (final SeqVertex mid : toSplit) {
          // create my own copy of the suffix
          final SeqVertex suffixV = new SeqVertex(suffixVTemplate.getSequence());
          graph.addVertex(suffixV);
          final SeqVertex prefixV = mid.withoutSuffix(suffixV.getSequence());
          final BaseEdge out = graph.outgoingEdgeOf(mid);

          final SeqVertex incomingTarget;
          if (prefixV == null) {
            // this node is entirely explained by suffix
            incomingTarget = suffixV;
          } else {
            incomingTarget = prefixV;
            graph.addVertex(prefixV);
            graph.addEdge(prefixV, suffixV, new BaseEdge(out.isRef(), 1));
            edgesToRemove.add(out);
          }

          graph.addEdge(suffixV, graph.getEdgeTarget(out), out.copy());

          for (final BaseEdge in : graph.incomingEdgesOf(mid)) {
            graph.addEdge(graph.getEdgeSource(in), incomingTarget, in.copy());
            edgesToRemove.add(in);
          }
        }

        graph.removeAllVertices(toSplit);
        graph.removeAllEdges(edgesToRemove);
        //                graph.printGraph(new File("split.post_" + v.getSequenceString() + "." +
        // counter++ + ".dot"), 0);

        return true;
      }
    }
  }