public void initSubproblems() { // initVisibility first int i; i = reflexIter(); if (i == 0) { setAfter(i); i = reflexNext(i); } if (i == 1) { subD.setWeight(0, 1, 0); setAfter(i); i = reflexNext(i); } while (i < n - 2) { setBefore(i); setAfter(i); i = reflexNext(i); } if (i == n - 2) { setBefore(i); subD.setWeight(i, i + 1, 0); i = reflexNext(i); } if (i == n - 1) { setBefore(i); } }
/* * We have a new solution for subprob a,b with weight w, using i,j. If it is * better than previous solutions, we update. We assume that a<b and i < j. */ public void update(int a, int b, int w, int i, int j) { // System.out.print("update("+a+","+b+" w:"+w+" "+i+","+j+")"); int ow = subD.weight(a, b); if (w <= ow) { PairDeque pair = subD.pairs(a, b); if (w < ow) { pair.flush(); subD.setWeight(a, b, w); } pair.pushNarrow(i, j); } }
public void typeB(int i, int j, int k) { /* k reflex, i not. */ // System.out.print("\nB "+i+","+j+","+k+":"); if (!visible(j, k)) return; int top = j; int w = subD.weight(j, k); if (j - i > 1) { if (!visible(i, j)) return; w += subD.weight(i, j) + 1; } if (k - j > 1) { // check if must use jk, too. PairDeque pair = subD.pairs(j, k); if (!Point.right(sp.p(i), sp.p(j), sp.p(pair.aF()))) { while (pair.more1() && !Point.right(sp.p(i), sp.p(j), sp.p(pair.underaF()))) pair.pop(); if ((!pair.empty()) && !Point.left(sp.p(i), sp.p(k), sp.p(pair.bF()))) top = pair.bF(); else w++; // yes, use jk. top=j already } else w++; // yes, use jk. top=j already } update(i, k, w, j, top); }
public void initVisibility() { // initReflex() first // if (animating()) // animGraphics.setColor(Color.yellow); VisPoly vp = new VisPoly(sp); for (int i = reflexIter(); i < n; i = reflexNext(i)) { vp.build(i); while (!vp.empty()) { int j = vp.popVisible() % n; if (j < i) subD.setWeight(j, i, INFINITY); else subD.setWeight(i, j, INFINITY); // if (animating()) // animGraphics.drawLine(sp.p(i).x(), sp.p(i).y(), // sp.p(j).x(), sp.p(j).y()); } } // if (animating()) { // animGraphics.setColor(Color.blue); // try { Thread.sleep(DELAY); // } catch(InterruptedException e) { // } // } }
public void typeA(int i, int j, int k) { /* i reflex; use jk */ // System.out.print("\nA "+i+","+j+","+k+":"); // assert(reflex(i), "non reflex i in typeA("+i+","+j+","+k+")"); // assert(k-i > 1, "too small in typeA("+i+","+j+","+k+")"); if (!visible(i, j)) return; int top = j; int w = subD.weight(i, j); if (k - j > 1) { if (!visible(j, k)) return; w += subD.weight(j, k) + 1; } if (j - i > 1) { // check if must use ij, too. PairDeque pair = subD.pairs(i, j); if (!Point.left(sp.p(k), sp.p(j), sp.p(pair.bB()))) { while (pair.more1B() && !Point.left(sp.p(k), sp.p(j), sp.p(pair.underbB()))) pair.popB(); if ((!pair.emptyB()) && !Point.right(sp.p(k), sp.p(i), sp.p(pair.aB()))) top = pair.aB(); else w++; // yes, need ij. top = j already } else w++; // yes, need ij. top = j already } update(i, k, w, top, j); }
public void recoverSolution(int i, int k) { int j; if (guard-- < 0) { // System.out.println("Can't recover" + i + "," + k); return; } if (k - i <= 1) return; PairDeque pair = subD.pairs(i, k); if (reflex(i)) { j = pair.bB(); recoverSolution(j, k); if (j - i > 1) { if (pair.aB() != pair.bB()) { PairDeque pd = subD.pairs(i, j); pd.restore(); while ((!pd.emptyB()) && pair.aB() != pd.aB()) pd.popB(); // assert(!pd.emptyB(), // "emptied pd "+i+","+j+","+k+" "+pair.toString()); } recoverSolution(i, j); } } else { j = pair.aF(); recoverSolution(i, j); if (k - j > 1) { if (pair.aF() != pair.bF()) { PairDeque pd = subD.pairs(j, k); pd.restore(); while ((!pd.empty()) && pair.bF() != pd.bF()) pd.pop(); // assert(!pd.empty(), // "emptied pd "+i+","+j+","+k+" "+pair.toString()); } recoverSolution(j, k); } } }
private void drawHelper(Graphics g, int i, int k) { int j; boolean ijreal = true, jkreal = true; if (k - i <= 1) return; PairDeque pair = subD.pairs(i, k); if (reflex(i)) { j = pair.bB(); ijreal = (pair.aB() == pair.bB()); } else { j = pair.aF(); jkreal = (pair.bF() == pair.aF()); } if (ijreal) { drawDiagonal(g, i, j); } // else if (label) { // g.setColor(Color.orange); // drawDiagonal(g, label, i, j); // g.setColor(Color.blue); // } if (jkreal) { drawDiagonal(g, j, k); } // else if (label) { // g.setColor(Color.orange); // drawDiagonal(g, label, j, k); // g.setColor(Color.blue); // } if (guard-- < 0) { // System.out.println("Infinite Loop drawing" + i + "," + k); return; } drawHelper(g, i, j); drawHelper(g, j, k); }
public boolean visible(int i, int j) { return subD.weight(i, j) < BAD; }
public void initPairs(int i, int k) { subD.init(i, k); }
private void setBefore(int i) { // i reflex // assert(reflex(i), "non reflex i in setAfter("+i+")"); subD.setWeight(i - 1, i, 0); if (visible(i - 2, i)) subD.init(i - 2, i, 0, i - 1, i - 1); }
private void setAfter(int i) { // i reflex // assert(reflex(i), "non reflex i in setAfter("+i+")"); subD.setWeight(i, i + 1, 0); if (visible(i, i + 2)) subD.init(i, i + 2, 0, i + 1, i + 1); }