コード例 #1
0
 protected void setLayersDFS(PNode<V, E> node, int layer) {
   if (layer > node.getLayer()) {
     node.setLayer(layer);
     for (PEdge<V, E> edge : node.getChildren()) {
       setLayersDFS(edge.to, layer + 1);
     }
   }
 }
コード例 #2
0
 public void addEdge(Edge<V, E> edge) {
   assert !locked;
   PNode<V, E> pnodeFrom = nodeMap.get(edge.getFrom());
   PNode<V, E> pnodeTo = nodeMap.get(edge.getTo());
   PEdge<V, E> pedge = new PEdge<V, E>(edge, pnodeFrom, pnodeTo);
   pnodeFrom.addChild(pedge);
   pnodeTo.addParent(pedge);
   edges.add(pedge);
 }
コード例 #3
0
  private void fillTmpLGraph() {
    tmpLGraph.reset();
    resetLayers();
    for (PEdge<V, E> edge : root.getChildren()) {
      setLayersDFS(edge.to, 0);
    }

    for (PEdge<V, E> edge : root.getChildren()) {
      tmpLGraph.addNode(edge.to.node, edge.to.getLayer());
      populateLGraph(tmpLGraph, edge.to);
    }
  }
コード例 #4
0
 public void lock() {
   if (locked) return;
   locked = true;
   nodesWithSeveralChildren = new ArrayList<PNode<V, E>>();
   nodesWithSeveralChildrenScaled = new ArrayList<PNode<V, E>>();
   nodesWithSeveralParents = new ArrayList<PNode<V, E>>();
   nodesWithoutChildren = new ArrayList<PNode<V, E>>();
   sourceFakeEdges = new ArrayList<PEdge<V, E>>();
   for (PNode<V, E> pnode : nodes) {
     if (pnode.isSource()) {
       PEdge<V, E> fakeEdge = new PEdge<V, E>(root, pnode);
       pnode.addParent(fakeEdge);
       root.addChild(fakeEdge);
       sourceFakeEdges.add(fakeEdge);
     }
     if (pnode.getChildren().size() >= 2) {
       nodesWithSeveralChildren.add(pnode);
       int i = pnode.getChildren().size();
       while (--i > 0) {
         nodesWithSeveralChildrenScaled.add(pnode);
       }
     }
     if (pnode.getParents().size() >= 2) {
       nodesWithSeveralParents.add(pnode);
     }
     if (pnode.getChildren().size() == 0) {
       nodesWithoutChildren.add(pnode);
     }
   }
 }
コード例 #5
0
  /* The difference to generateLGraph is that it tries to be really efficient, not visually appealing,
    by pulling nodes down etc. It's just supposed to be used for assessments, e.g. for the simulated annealing.
  */
  public LGraph<V, E> generateLGraphEfficiently(LGraphConfig lconfig) {
    if (!locked) lock();
    LGraph<V, E> lgraph = new LGraph<V, E>(lconfig);
    resetLayers();
    for (PEdge<V, E> edge : root.getChildren()) {
      setLayersDFS(edge.to, 0);
    }

    for (PEdge<V, E> edge : root.getChildren()) {
      lgraph.addNode(edge.to.node, edge.to.getLayer());
      populateLGraph(lgraph, edge.to);
    }

    return lgraph;
  }
コード例 #6
0
 protected void populateLGraph(LGraph<V, E> lgraph, PNode<V, E> node) {
   for (PEdge<V, E> edge : node.getChildren()) {
     if (!lgraph.containsNode(edge.to.node)) {
       lgraph.addNode(edge.to.node, edge.to.getLayer());
       populateLGraph(lgraph, edge.to);
     }
     if (!edge.isFake) {
       lgraph.addEdge(edge.edge);
     }
   }
 }
コード例 #7
0
 public double trySwapChildren(double temp, double currentEnergy) {
   if (nodesWithSeveralChildrenScaled.size() > 0) {
     PNode<V, E> parent =
         nodesWithSeveralChildrenScaled.get(
             quadraticRandint(nodesWithSeveralChildrenScaled.size()));
     nodesWithSeveralChildrenScaled.remove(parent);
     nodesWithSeveralChildrenScaled.add(
         parent); // move it to the end - less likely to be picked again in near future
     int numberOfChildren = parent.getChildren().size();
     int i1 = random.nextInt(numberOfChildren);
     int i2 = random.nextInt(numberOfChildren - 1);
     i2 = i2 >= i1 ? i2 + 1 : i2;
     parent.swapChildren(i1, i2);
     double newEnergy = getEnergy();
     if (acceptChange(currentEnergy, newEnergy, temp)) {
       return newEnergy;
     } else {
       parent.swapChildren(i1, i2); // swap back
       return currentEnergy;
     }
   }
   return currentEnergy;
 }
コード例 #8
0
 boolean cycleDetector(PNode<V, E> node, HashMap<PNode<V, E>, Boolean> map) {
   if (!map.containsKey(node)) {
     map.put(node, true);
   } else if (map.get(node)) {
     return true;
   } else {
     map.put(node, true);
   }
   for (PEdge<V, E> edge : node.getChildren()) {
     if (cycleDetector(edge.to, map)) {
       return true;
     }
   }
   map.put(node, false);
   return false;
 }
コード例 #9
0
  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;
  }
コード例 #10
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;
  }
コード例 #11
0
 protected void resetLayers() {
   for (PNode<V, E> pnode : nodes) {
     pnode.resetLayer();
   }
 }
コード例 #12
0
 protected void setLayers() {
   for (PEdge<V, E> edge : root.getChildren()) {
     setLayersDFS(edge.to, 0);
   }
 }