Пример #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);
   }
 }