コード例 #1
0
 public double tryRemoveFakeEdge(double temp, double currentEnergy) {
   if (fakeEdges.size() > 0) {
     PEdge<V, E> choice = fakeEdges.get(random.nextInt(fakeEdges.size()));
     ArrayList<PEdge<V, E>> toBeRemoved = new ArrayList<PEdge<V, E>>();
     if (Math.random() < 0.5) { // remove single edge
       toBeRemoved.add(choice);
     } else {
       for (PEdge<V, E> parent : choice.to.getParents()) {
         if (parent.isFake && !parent.from.isRoot) {
           toBeRemoved.add(parent);
         }
       }
     }
     ArrayList<Integer> positions = new ArrayList<Integer>(toBeRemoved.size());
     for (PEdge<V, E> fakeEdge : toBeRemoved) {
       int position = fakeEdge.from.getChildren().indexOf(fakeEdge);
       fakeEdge.from.getChildren().remove(position);
       positions.add(position);
       fakeEdge.to.removeParent(fakeEdge);
     }
     double newEnergy = getEnergy();
     if (acceptChange(currentEnergy, newEnergy, temp)) {
       fakeEdges.removeAll(toBeRemoved);
       return newEnergy;
     } else {
       for (int i = positions.size() - 1; i >= 0; i--) {
         PEdge<V, E> fakeEdge = toBeRemoved.get(i);
         fakeEdge.from.getChildren().add(positions.get(i), fakeEdge);
         fakeEdge.to.addParent(fakeEdge);
       }
       return currentEnergy;
     }
   }
   return currentEnergy;
 }
コード例 #2
0
  public double runSimulatedAnnealing(int iterations) {
    if (!locked) lock();
    double temp = 1;
    double coolingFactor = Math.pow(0.001, 1d / iterations);
    double currentEnergy = getEnergy();
    if (nodes.isEmpty()) return currentEnergy;
    Collections.shuffle(nodesWithSeveralChildrenScaled, random);
    Collections.shuffle(sourceFakeEdges, random);

    while (temp > 0.001) {
      double action = random.nextDouble();
      if (action < 0.19) { // add fake edge
        currentEnergy = tryAddFakeEdge(temp, currentEnergy);
        assert currentEnergy == getEnergy();
      } else if (action
          < 0.36) { // remove fake edge (slightly higher probability - we don't want too many fake
        // edges) - update: apparently, that hypothesis is wrong
        currentEnergy = tryRemoveFakeEdge(temp, currentEnergy);
        assert currentEnergy == getEnergy();
      } else if (action < 0.7) { // swap two children of some node
        currentEnergy = trySwapChildren(temp, currentEnergy);
        assert currentEnergy == getEnergy();
      } else { // change where one of the sources is attached to
        currentEnergy = tryChangeSource(temp, currentEnergy);
        assert currentEnergy == getEnergy();
      }
      temp *= coolingFactor;
    }
    return currentEnergy;
  }
コード例 #3
0
  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;
  }
コード例 #4
0
 public double getEnergy() {
   fillTmpLGraph();
   double energy = tmpLGraph.getNumberOfIntersections();
   // energy += 1 - Math.exp(-Math.sqrt(lgraph.getNumberOfDummyNodes()));  // removing
   // intersections has strict priority
   energy += 0.5 * tmpLGraph.getNumberOfDummyNodes() / (double) nodes.size();
   energy += 0.2 * Math.sqrt(tmpLGraph.getDensityMeasure());
   return energy;
 }
コード例 #5
0
  public boolean acceptChange(double oldEnergy, double newEnergy, double temp) {
    if (newEnergy < oldEnergy) return true;

    return Math.exp((oldEnergy - newEnergy) / temp) > Math.random();
  }