public double tryChangeSource(double temp, double currentEnergy) { PEdge<V, E> fakeEdge = sourceFakeEdges.get(random.nextInt(sourceFakeEdges.size())); PNode<V, E> child = fakeEdge.to; int oldIndex = fakeEdge.from.getChildren().indexOf(fakeEdge); child.removeParent(fakeEdge); fakeEdge.from.removeChild(fakeEdge); PEdge<V, E> fakeEdge2; int fakeEdge2Swap = -1; if (fakeEdge.from.isRoot || random.nextDouble() < 0.4) { // try attaching it somewhere else PNode<V, E> parent; if (Math.random() < 0.5 || nodesWithSeveralChildrenScaled.size() == 0) { // try some completely random node parent = nodes.get(random.nextInt(nodes.size())); } else { parent = nodesWithSeveralChildrenScaled.get( random.nextInt(nodesWithSeveralChildrenScaled.size())); } fakeEdge2 = new PEdge<V, E>(parent, child); parent.addChild(fakeEdge2); if (parent.getChildren().size() > 1) { fakeEdge2Swap = random.nextInt(parent.getChildren().size() - 1); parent.swapChildren(parent.getChildren().size() - 1, fakeEdge2Swap); } child.addParent(fakeEdge2); } else { // try attaching it back to root. fakeEdge2 = new PEdge<V, E>(root, child); root.addChild(fakeEdge2); if (root.getChildren().size() > 1) { fakeEdge2Swap = random.nextInt(root.getChildren().size() - 1); root.swapChildren(root.getChildren().size() - 1, fakeEdge2Swap); } child.addParent(fakeEdge2); } if (!graphHasCycle(fakeEdge2.to)) { double newEnergy = getEnergy(); if (acceptChange(currentEnergy, newEnergy, temp)) { sourceFakeEdges.remove(fakeEdge); sourceFakeEdges.add(fakeEdge2); return newEnergy; } } fakeEdge2.from.removeChild(fakeEdge2); child.removeParent(fakeEdge2); if (fakeEdge2Swap != -1) { PEdge<V, E> e = fakeEdge2.from.getChildren().get(fakeEdge2.from.getChildren().size() - 1); fakeEdge2.from.getChildren().remove(fakeEdge2.from.getChildren().size() - 1); fakeEdge2.from.getChildren().add(fakeEdge2Swap, e); } // fakeEdge.from.addChild(fakeEdge); fakeEdge.from.getChildren().add(oldIndex, fakeEdge); child.addParent(fakeEdge); return currentEnergy; }
public double tryAddFakeEdge(double temp, double currentEnergy) { // it's sufficient to only add fake edges from leaves to nodes with multiple parents if (nodesWithoutChildren.size() > 0 && nodesWithSeveralParents.size() > 0) { PNode<V, E> from = nodesWithoutChildren.get(random.nextInt(nodesWithoutChildren.size())); PNode<V, E> to = nodesWithSeveralParents.get(random.nextInt(nodesWithSeveralParents.size())); PEdge<V, E> fakeEdge = new PEdge<V, E>(from, to); from.addChild(fakeEdge); to.addParent(fakeEdge); if (!graphHasCycle(to)) { double newEnergy = getEnergy(); if (acceptChange(currentEnergy, newEnergy, temp)) { fakeEdges.add(fakeEdge); return newEnergy; } } // otherwise undo changes from.removeChild(fakeEdge); to.removeParent(fakeEdge); return currentEnergy; } return currentEnergy; }