void link(HeapNode y, HeapNode x) { // moves y to a child position of x rootList.remove(y); x.addChild(y); y.setParent(x); y.setMark(false); }
/** * removes child node from tree and starts a new one with it. * * @param x * @param y */ protected void cut(HeapNode x, HeapNode y) { // remove x from child list of y and decrement y.degree y.removeChild(x); // add x to root list rootList.insert(x); x.setParent(null); x.setMark(false); }
/** * c*O(1) * * @param y */ protected void cascadingCut(HeapNode y) { HeapNode z = y.getParent(); if (z != null) { if (!y.isMark()) { y.setMark(true); } else { cut(y, z); cascadingCut(z); } } }
/** * extract minimum from the heap. * * <p>minor differences from Cormen et al. pseudocode are present. * * @return */ public HeapNode extractMin() { int sentinel = DoubleLinkedCircularList.sentinelKey; HeapNode z = minimumNode; if (z != null) { // detach each child and add it to heap HeapNode x = z.getChildren().getSentinel().getRight(); // for each child x of z while (x.getKey() != sentinel) { HeapNode next = x.getRight(); rootList.insert(x); x = next; } rootList.remove(z); if (z.getRight().getKey() == z.getKey()) { minimumNode = null; } else { minimumNode = z.getRight(); consolidate(); } n--; } return z; }
/** * Creates a deep copy of this {@link HeapNode}. The clone is not reset from the current * position of the original. * * @return the cloned heap node */ public HeapNode cloneHeapNode() { HeapNode clone; try { clone = (HeapNode) super.clone(); } catch (CloneNotSupportedException e) { BasisLibrary.runTimeError(BasisLibrary.ITERATOR_CLONE_ERR, e.toString()); return null; } clone._node = _node; clone._markedNode = _node; return clone; }
@Override public void runAlgorithm() throws InterruptedException { final HeapNode v = new HeapNode(H, K, ZDepth.ACTIONNODE); addToScene(v); setHeader("insertion"); if (H.getN() == 1000) { addStep("heapfull"); removeFromScene(v); return; } HeapNode w; // link H.setN(H.getN() + 1); final int n = H.getN(); int k = 1 << 10; if (n == 1) { H.setRoot(w = v); v.goToRoot(); pause(); } else { while ((k & n) == 0) { k >>= 1; } k >>= 1; w = H.getRoot(); while (k > 1) { w = ((n & k) == 0) ? w.getLeft() : w.getRight(); k >>= 1; } if ((k & n) == 0) { w.linkLeft(v); } else { w.linkRight(v); } v.mark(); H.reposition(); pause(); } removeFromScene(v); v.unmark(); // pause(); bubbleup(v); }
/** * a depth first search of all nodes (that is, it descends all children of a node before * proceeding to the next in the current doubly linked circular list). * * @param key * @return */ HeapNode search(long key) { HeapNode node = rootList.getSentinel().getRight(); int sentinel = DoubleLinkedCircularList.sentinelKey; Stack<HeapNode> stack = new Stack<HeapNode>(); while (!stack.isEmpty() || (node.getKey() != sentinel)) { if (node.getKey() != sentinel) { stack.push(node); node = node.getRight(); } else { node = stack.pop(); // System.out.println(node.key); if (node.getKey() == key) { return node; } node = node.getChildren().getSentinel().getRight(); } } return null; }
/** * decrease key for node x * * <p>runtime is O(1) * * @param x * @param decreaseToThisKey */ public void decreaseKey(HeapNode x, long decreaseToThisKey) { if (decreaseToThisKey > x.getKey()) { throw new IllegalArgumentException("key cannot be larger than x.key"); } x.setKey(decreaseToThisKey); HeapNode y = x.getParent(); if ((y != null) && (x.getKey() < y.getKey())) { cut(x, y); cascadingCut(y); } if (x.getKey() < minimumNode.getKey()) { minimumNode = x; } }
/** * insert node into heap. runtime is O(1). makes no attempt to consolidate tree. * * @param node */ public void insert(HeapNode node) { if (node.getKey() == DoubleLinkedCircularList.noValue) { throw new IllegalArgumentException("node.key must be set before insert into heap"); } node.setNumberOfChildren(0); node.setParent(null); node.removeChildren(); node.setLeft(node); node.setRight(node); node.setMark(false); // concatenate root list containing node with this.rootList rootList.insert(node); if ((minimumNode == null) || (node.getKey() < minimumNode.getKey())) { minimumNode = node; } n++; }
protected void printRootList() { StringBuffer sb = new StringBuffer(); HeapNode t = this.rootList.getSentinel().getRight(); while (t.getKey() != DoubleLinkedCircularList.sentinelKey) { if ((minimumNode == null) || (t.getKey() < minimumNode.getKey())) { minimumNode = t; } String str = String.format("%d", t.getKey()); if (sb.length() > 0) { sb.append(" "); } sb.append(str); t = t.getRight(); } sb.insert(0, "Looking for " + minimumNode + " :"); log.info(sb.toString()); }
void consolidate() { // D[n] = max degree of any node = lg_2(n) = lg_2(Integer.MAX) = 31 // int maxDegree = (int) (Math.log(this.n)/Math.log(2)); int maxDegree = 31; HeapNode[] a = new HeapNode[maxDegree]; HeapNode w = rootList.getSentinel().getRight(); // n*m*(constants) while (w.getKey() != DoubleLinkedCircularList.sentinelKey) { HeapNode x = w; // because the x.right gets changed in link(), nab the next // reference before link HeapNode next = w.getRight(); int d = x.getNumberOfChildren(); // is there another node of the same degree, that is, has the // same number of children? while ((d < a.length) && (a[d] != null)) { HeapNode y = a[d]; if (x.getKey() > y.getKey()) { HeapNode tmp = x; x = y; y = tmp; } // link removes y (which has a key larger than x now) from // rootList and adds it as a child of x link(y, x); a[d] = null; d++; } if (d < a.length) { a[d] = x; } else { throw new IllegalStateException("maxDegree=" + maxDegree + " but d is " + d); } w = next; } minimumNode = null; for (int i = 0; i < a.length; i++) { if (a[i] != null) { rootList.remove(a[i]); rootList.insert(a[i]); // not changing the minimumNode because the rootList content // has not changed, so the minimum in that has not changed if ((minimumNode == null) || (a[i].getKey() < minimumNode.getKey())) { minimumNode = a[i]; } } } }
public static int addNewHeapNode( ClassInfo typeClassInfo, ThreadInfo ti, Object attr, PathCondition pcHeap, SymbolicInputHeap symInputHeap, int numSymRefs, HeapNode[] prevSymRefs, boolean setShared) { int daIndex = ti.getHeap().newObject(typeClassInfo, ti).getObjectRef(); ti.getHeap().registerPinDown(daIndex); String refChain = ((SymbolicInteger) attr) .getName(); // + "[" + daIndex + "]"; // do we really need to add daIndex here? SymbolicInteger newSymRef = new SymbolicInteger(refChain); ElementInfo eiRef = ti.getModifiableElementInfo(daIndex); // ti.getElementInfo(daIndex); // TODO to review! if (setShared) { eiRef.setShared(ti, true); // ?? } // daIndex.getObjectRef() -> number // neha: this change allows all the fields in the class hierarchy of the // object to be initialized as symbolic and not just its instance fields int numOfFields = eiRef.getNumberOfFields(); FieldInfo[] fields = new FieldInfo[numOfFields]; for (int fieldIndex = 0; fieldIndex < numOfFields; fieldIndex++) { fields[fieldIndex] = eiRef.getFieldInfo(fieldIndex); } Helper.initializeInstanceFields(fields, eiRef, refChain); // neha: this change allows all the static fields in the class hierarchy // of the object to be initialized as symbolic and not just its immediate // static fields ClassInfo superClass = typeClassInfo; while (superClass != null) { FieldInfo[] staticFields = superClass.getDeclaredStaticFields(); Helper.initializeStaticFields(staticFields, superClass, ti); superClass = superClass.getSuperClass(); } // Put symbolic array in PC if we create a new array. if (typeClassInfo.isArray()) { String typeClass = typeClassInfo.getType(); ArrayExpression arrayAttr = null; if (typeClass.charAt(1) != 'L') { arrayAttr = new ArrayExpression(eiRef.toString()); } else { arrayAttr = new ArrayExpression(eiRef.toString(), typeClass.substring(2, typeClass.length() - 1)); } ti.getVM() .getLastChoiceGeneratorOfType(PCChoiceGenerator.class) .getCurrentPC() .arrayExpressions .put(eiRef.toString(), arrayAttr); } // create new HeapNode based on above info // update associated symbolic input heap HeapNode n = new HeapNode(daIndex, typeClassInfo, newSymRef); symInputHeap._add(n); pcHeap._addDet(Comparator.NE, newSymRef, new IntegerConstant(-1)); pcHeap._addDet(Comparator.EQ, newSymRef, new IntegerConstant(numSymRefs)); for (int i = 0; i < numSymRefs; i++) pcHeap._addDet(Comparator.NE, n.getSymbolic(), prevSymRefs[i].getSymbolic()); return daIndex; }