Exemplo n.º 1
0
  /**
   * Derive the split components of this palm tree. This method is taken from the paper of Gutwenger
   * and Mutzel "A linear time implementation of SPQR trees".
   *
   * @param v
   */
  public List<SplitComponent> determineSplitComponents() {
    try {
      this.preparePathSearch();

      this.tStackPushEos();
      //            System.out.println("NEW NUMBERS: " + NEWNUM);
      //            System.out.println("ND: " + ND);
      //            System.out.println("LOW1:" + LOWPT1);
      //            System.out.println("LOW2:" + LOWPT2);
      //            System.out.println("ORD ADJ: " + ADJ);
      //            System.out.println("--------------------------");

      this.pathSearch(this.m_start);

      SplitComponent newCmp = new SplitComponent();

      if (ESTACK.size() == 1) newCmp.setType(ComponentType.TRIVIAL);
      else if (ESTACK.size() >= 4) newCmp.setType(ComponentType.TRICONNECTED);
      else newCmp.setType(ComponentType.POLYGON);

      while (!ESTACK.empty()) {
        newCmp.add(ESTACK.pop());
      }

      //            System.err.println("COMP: " + newCmp);
      //
      this.splitComponents.add(newCmp);
      this.splitComponents.addAll(graph.getMultipleEdgeBonds());

      //            System.err.println("\n\nALL COMPONENTS: ");
      //            System.err.println(this.splitComponents);
      //            System.err.println("\n\n");
    } catch (Exception e) {
      e.printStackTrace();
    }

    return this.splitComponents;
  }
Exemplo n.º 2
0
  /**
   * Derive the split components of this palm tree. This method is taken from the paper of Gutwenger
   * and Mutzel "A linear time implementation of SPQR trees". UPDATE: This is more taken from the
   * OGDF C++ implementation since the paper hides a lot of necessary information.
   *
   * @param v the start node
   */
  private void pathSearch(Node v) {
    //        System.err.println("BEGIN pS(" + v + ");" );
    int vnum = NEWNUM.get(v);
    int wnum;
    int y = 0;
    int a, b;

    IterableAdjacencyList adj = ADJ.get(v);
    adj.reset();
    Node w;
    int outv = adj.size();

    while (adj.hasNext()) {
      Edge e = adj.next();
      //            System.err.println("CURRENT EDGE: " + e);
      w = e.getTarget();
      wnum = NEWNUM.get(w);

      if (TYPE.get(e).equals(ArcType.TREE)) {
        if (START.get(e)) {
          y = 0;
          if (tStackGetTopA() > LOWPT1.get(w)) {
            do {
              y = Math.max(y, tStackGetTopH());
              b = tStackGetTopB();
              TSTACK.pop();
            } while (tStackGetTopA() > LOWPT1.get(w));
            Triple t = new Triple(Math.max(y, wnum + ND.get(w) - 1), LOWPT1.get(w), b);
            TSTACK.push(t);
            //                        System.err.println("TSTACK push 1: " + t);
          } else {
            Triple t = new Triple(wnum + ND.get(w) - 1, LOWPT1.get(w), vnum);
            TSTACK.push(t);
            //                        System.err.println("TSTACK push 2: " + t);
          }
          tStackPushEos();
        }

        pathSearch(w);
        ESTACK.push(TREE_ARC.get(w));
        //                System.err.println("TSTACK: " + TSTACK);
        //                System.err.println("CURRENT VNUM: " + vnum);
        //                System.err.println("DEG(w): " + DEGREE.get(w));
        // check for type 2 pairs
        while (vnum != 1
            && ((tStackGetTopA() == vnum)
                || (DEGREE.get(w) == 2 && NEWNUM.get(firstChild(w)) > wnum))) {
          a = tStackGetTopA();
          b = tStackGetTopB();

          Edge eVirt = null;

          if (a == vnum && FATHER.get(NODEAT[b]) == NODEAT[a]) {
            TSTACK.pop();
          } else {
            Edge e_ab = null;
            Node x = null;
            //                        System.err.println("W: " + w);
            //                        System.err.println("DEG(W): " + DEGREE.get(w) );
            if (DEGREE.get(w) == 2 && NEWNUM.get(firstChild(w)) > wnum) {
              //                            System.err.println("FOUND type-2 pair " + v + " , " +
              // firstChild(w));
              //                            System.err.println("ESTACK: " + ESTACK);
              Edge e1 = ESTACK.pop();
              Edge e2 = ESTACK.pop();

              ADJ.get(e2.getSource()).remove(e2);
              ADJ.get(e1.getSource()).remove(e1);
              x = e2.getTarget();
              //                            System.err.println("X:" + x);

              decrementDegree(x);
              decrementDegree(v);

              eVirt = new Edge(0, v, x);
              eVirt.setVirtual(true);
              SplitComponent sc = new SplitComponent();
              sc.add(e1);
              sc.add(e2);
              sc.add(eVirt);
              sc.setType(ComponentType.POLYGON);
              splitComponents.add(sc);
              //                            System.err.println("COMP1: " + sc);
              //                            System.err.println("ESTACK: " + ESTACK);
              if (!ESTACK.empty()
                  && ESTACK.peek().getSource() == x
                  && ESTACK.peek().getTarget() == v) {
                e_ab = ESTACK.pop();
                ADJ.get(x).remove(e_ab);
                delHigh(e_ab);
              }
            } else {
              //                            System.err.println("ESTACK: " + ESTACK);
              //                            System.err.println("FOUND type-2 pair " + NODEAT[a] + "
              // , " + NODEAT[b]);
              int h = TSTACK.peek().h;
              TSTACK.pop();
              SplitComponent sc = new SplitComponent();
              while (true) {
                Edge xy = ESTACK.peek();
                x = xy.getSource();

                if (!(a <= NEWNUM.get(x)
                    && NEWNUM.get(x) <= h
                    && a <= NEWNUM.get(xy.getTarget())
                    && NEWNUM.get(xy.getTarget()) <= h)) {
                  break;
                }

                if ((NEWNUM.get(x) == a && NEWNUM.get(xy.getTarget()) == b)
                    || (NEWNUM.get(xy.getTarget()) == a && NEWNUM.get(x) == b)) {
                  e_ab = ESTACK.pop();
                  ADJ.get(e_ab.getSource()).remove(e_ab);
                  delHigh(e_ab);
                } else {
                  Edge eh = ESTACK.pop();
                  if (e != eh) {
                    ADJ.get(eh.getSource()).remove(eh);
                    delHigh(eh);
                  }

                  sc.add(eh);
                  decrementDegree(x);
                  decrementDegree(xy.getTarget());
                }
              }

              eVirt = new Edge(0, NODEAT[a], NODEAT[b]);
              eVirt.setVirtual(true);
              sc.add(eVirt);
              sc.finishTriconnectedOrPolygon();
              splitComponents.add(sc);
              //                            System.err.println("COMP2: " + sc);
              x = NODEAT[b];
            }

            if (e_ab != null) {
              SplitComponent sc = new SplitComponent();
              sc.setType(ComponentType.BOND);

              sc.add(e_ab);
              sc.add(eVirt);

              eVirt = new Edge(0, v, x);
              eVirt.setVirtual(true);
              sc.add(eVirt);

              splitComponents.add(sc);
              //                            System.err.println("COMP: " + sc);
              decrementDegree(x);
              decrementDegree(v);
            }

            ESTACK.push(eVirt);
            adj.insert(eVirt);

            START.put(eVirt, START.get(e));

            incrementDegree(x);
            incrementDegree(v);

            FATHER.put(x, v);
            TREE_ARC.put(x, eVirt);
            TYPE.put(eVirt, ArcType.TREE);

            w = x;
            wnum = NEWNUM.get(w);
          }
        }

        // check for type 1 pair
        if (LOWPT2.get(w) >= vnum
            && LOWPT1.get(w) < vnum
            && (FATHER.get(v) != m_start || outv >= 2)) {
          //                    System.err.println( "Found type-1 pair( " +  v + "," + NODEAT[
          // LOWPT1.get(w) ] + ")");

          SplitComponent c = new SplitComponent();
          Edge xy = null;
          int xnum, ynum;
          //                    System.err.println("ESTACK: " + ESTACK);
          while (!ESTACK.isEmpty()) {
            xy = ESTACK.peek();
            xnum = NEWNUM.get(xy.getSource());
            ynum = NEWNUM.get(xy.getTarget());
            if (!((wnum <= xnum && xnum < wnum + ND.get(w))
                || (wnum <= ynum && ynum < wnum + ND.get(w)))) {
              break;
            }
            ESTACK.pop();

            c.add(xy);
            delHigh(xy);
            decrementDegree(xy.getSource());
            ADJ.get(xy.getSource()).remove(xy);
            this.graphCopy.edges.remove(xy);
            decrementDegree(xy.getTarget());
          }

          Edge eVirt = new Edge(0, v, NODEAT[LOWPT1.get(w)]);
          eVirt.setVirtual(true);
          this.graphCopy.addEdge(eVirt);
          c.add(eVirt);
          c.finishTriconnectedOrPolygon();
          splitComponents.add(c);
          //                    System.err.println("COMP: " + c);
          //                    System.out.println("STACK HERE: " + ESTACK);
          if (
          /*!ESTACK.isEmpty() && */ (xy.getSource() == v && xy.getTarget() == NODEAT[LOWPT1.get(w)])
              || (xy.getTarget() == v && xy.getSource() == NODEAT[LOWPT1.get(w)])) {

            SplitComponent sc = new SplitComponent();
            sc.setType(ComponentType.BOND);

            Edge eh = ESTACK.pop();
            if (eh != e) {
              ADJ.get(eh.getSource()).remove(eh);
            }

            sc.add(eh);
            ADJ.get(eh.getSource()).remove(eh);
            this.graphCopy.edges.remove(eh);
            decrementDegree(eh.getSource());
            decrementDegree(eh.getTarget());
            sc.add(eVirt);

            eVirt = new Edge(0, v, NODEAT[LOWPT1.get(w)]);
            eVirt.setVirtual(true);

            // BLOCK IN OGDF left out --> m_IN_HIGH
            sc.add(eVirt);
            splitComponents.add(sc);
            //                            System.err.println("COMP: " + sc );
          }

          if ((NODEAT[LOWPT1.get(w)] != FATHER.get(v))) {
            ESTACK.push(eVirt);
            adj.insert(eVirt);
            START.put(eVirt, false);

            TYPE.put(eVirt, ArcType.FROND);
            if (high(NODEAT[LOWPT1.get(w)]) < vnum) HIGHPT.get(NODEAT[LOWPT1.get(w)]).add(0, vnum);

            incrementDegree(v);
            incrementDegree(NODEAT[LOWPT1.get(w)]);
          } else {
            adj.remove(e); // BLOCK from OGDF --> Adj.del(it);

            SplitComponent sc = new SplitComponent();
            sc.setType(ComponentType.BOND);
            sc.add(eVirt);
            Edge eh = TREE_ARC.get(v);
            sc.add(eh);

            splitComponents.add(sc);

            ADJ.get(eh.getSource()).remove(eh);

            eVirt = new Edge(0, NODEAT[LOWPT1.get(w)], v);
            eVirt.setVirtual(true);

            sc.add(eVirt);
            //                        System.err.println("COMP: " + sc);

            TYPE.put(eVirt, ArcType.TREE);

            //                        System.out.println("INSERT HERE into " + eh.getSource() +
            // "TARGET: " + eh.getTarget());
            ADJ.get(eh.getSource()).insert(eVirt);
            TREE_ARC.put(v, eVirt);

            START.put(eVirt, START.get(eh));
          }
        }

        if (START.get(e)) {
          while (tStackNotEos()) {
            TSTACK.pop();
          }
          TSTACK.pop();
        }

        while (tStackNotEos()
            && tStackGetTopA() != vnum
            && tStackGetTopB() != vnum
            && high(v) > tStackGetTopH()) {
          TSTACK.pop();
        }

        outv--;

      } else { // frond arc
        //                System.err.println("TSTACK 2: " + TSTACK);
        if (START.get(e)) {
          y = 0;
          if (tStackGetTopA() > LOWPT1.get(w)) {
            do {
              y = Math.max(y, tStackGetTopH());
              b = tStackGetTopB();
              TSTACK.pop();
            } while (tStackGetTopA() > LOWPT1.get(w));
            Triple t = new Triple(y, wnum, b);
            TSTACK.push(t);
            //                        System.err.println("TSTACK push3: " + t);
          } else {
            Triple t = new Triple(vnum, wnum, vnum);
            TSTACK.push(new Triple(vnum, wnum, vnum));
            //                        System.err.println("TSTACK push4: " + t);
          }
          // tStackPushEos();
        }

        // BLOCK FROM PAPER left out --> if ( w = parent(v) )

        ESTACK.push(e);
      }
    }

    //        System.err.println("END pS(" + v + ");" );
  }