Пример #1
0
  /**
   * Random graph. Generates randomly k directed edges out of each node. The neighbors (edge
   * targets) are chosen randomly without replacement from the nodes of the graph other than the
   * source node (i.e. no loop edge is added). If k is larger than N-1 (where N is the number of
   * nodes) then k is set to be N-1 and a complete graph is returned.
   *
   * @param g the graph to be wired
   * @param k samples to be drawn for each node
   * @param r source of randomness
   * @return returns g for convenience
   */
  public static Graph wireKOut(Graph g, int k, Random r) {

    final int n = g.size();
    if (n < 2) {
      return g;
    }
    if (n <= k) {
      k = n - 1;
    }
    int[] nodes = new int[n];
    for (int i = 0; i < nodes.length; ++i) {
      nodes[i] = i;
    }
    for (int i = 0; i < n; ++i) {
      int j = 0;
      while (j < k) {
        int newedge = j + r.nextInt(n - j);
        int tmp = nodes[j];
        nodes[j] = nodes[newedge];
        nodes[newedge] = tmp;
        if (nodes[j] != i) {
          g.setEdge(i, nodes[j]);
          j++;
        }
      }
    }
    return g;
  }
Пример #2
0
  /**
   * A sink star. Wires a sink star topology adding a link to 0 from all other nodes.
   *
   * @param g the graph to be wired
   * @return returns g for convenience
   */
  public static Graph wireStar(Graph g) {

    final int n = g.size();
    for (int i = 1; i < n; ++i) {
      g.setEdge(i, 0);
    }
    return g;
  }
Пример #3
0
  /**
   * This contains the implementation of the Barabasi-Albert model of growing scale free networks.
   * The original model is described in <a href="http://arxiv.org/abs/cond-mat/0106096">
   * http://arxiv.org/abs/cond-mat/0106096</a>. It also works if the graph is directed, in which
   * case the model is a variation of the BA model described in <a
   * href="http://arxiv.org/pdf/cond-mat/0408391">http://arxiv.org/pdf/cond-mat/0408391</a>. In both
   * cases, the number of the initial set of nodes is the same as the degree parameter, and no links
   * are added. The first added node is connected to all of the initial nodes, and after that the BA
   * model is used normally.
   *
   * @param k the number of edges that are generated for each new node, also the number of initial
   *     nodes (that have no edges).
   * @param r the randomness to be used
   * @return returns g for convenience
   */
  public static Graph wireScaleFreeBA(Graph g, int k, Random r) {

    final int nodes = g.size();
    if (nodes <= k) {
      return g;
    }

    // edge i has ends (ends[2*i],ends[2*i+1])
    int[] ends = new int[2 * k * (nodes - k)];

    // Add initial edges from k to 0,1,...,k-1
    for (int i = 0; i < k; i++) {
      g.setEdge(k, i);
      ends[2 * i] = k;
      ends[2 * i + 1] = i;
    }

    int len = 2 * k; // edges drawn so far is len/2
    for (int i = k + 1; i < nodes; i++) // over the remaining nodes
    {
      for (int j = 0; j < k; j++) // over the new edges
      {
        int target;
        do {
          target = ends[r.nextInt(len)];
          int m = 0;
          while (m < j && ends[len + 2 * m + 1] != target) {
            ++m;
          }
          if (m == j) {
            break;
          }
          // we don't check in the graph because
          // this wire method should accept graphs
          // that already have edges.
        } while (true);
        g.setEdge(i, target);
        ends[len + 2 * j] = i;
        ends[len + 2 * j + 1] = target;
      }
      len += 2 * k;
    }

    return g;
  }
Пример #4
0
  /**
   * A regular rooted tree. Wires a regular rooted tree. The root is 0, it has links to 1,...,k. In
   * general, node i has links to i*k+1,...,i*k+k.
   *
   * @param g the graph to be wired
   * @param k the number of outgoing links of nodes in the tree (except leaves that have zero
   *     out-links, and exactly one node that might have less than k).
   * @return returns g for convenience
   */
  public static Graph wireRegRootedTree(Graph g, int k) {

    if (k == 0) {
      return g;
    }
    final int n = g.size();
    int i = 0; // node we wire
    int j = 1; // next free node to link to
    while (j < n) {
      for (int l = 0; l < k && j < n; ++l, ++j) {
        g.setEdge(i, j);
      }
      ++i;
    }
    return g;
  }
Пример #5
0
  /**
   * Wires a ring lattice. The added connections are defined as follows. If k is even, links to
   * i-k/2, i-k/2+1, ..., i+k/2 are added (but not to i), thus adding an equal number of
   * predecessors and successors. If k is odd, then we add one more successors than predecessors.
   * For example, for k=4: 2 predecessors, 2 successors. For k=5: 2 predecessors, 3 successors. For
   * k=1: each node is linked only to its successor. All values are understood mod n to make the
   * lattice circular, where n is the number of nodes in g.
   *
   * @param g the graph to be wired
   * @param k lattice parameter
   * @return returns g for convenience
   */
  public static Graph wireRingLattice(Graph g, int k) {

    final int n = g.size();

    int pred = k / 2;
    int succ = k - pred;

    for (int i = 0; i < n; ++i) {
      for (int j = -pred; j <= succ; ++j) {
        if (j == 0) {
          continue;
        }
        final int v = (i + j + n) % n;
        g.setEdge(i, v);
      }
    }
    return g;
  }
Пример #6
0
  /**
   * A hypercube. Wires a hypercube. For a node i the following links are added: i xor 2^0, i xor
   * 2^1, etc. this define a log(graphsize) dimensional hypercube (if the log is an integer).
   *
   * @param g the graph to be wired
   * @return returns g for convenience
   */
  public static Graph wireHypercube(Graph g) {

    final int n = g.size();
    if (n <= 1) {
      return g;
    }
    final int highestone = Integer.highestOneBit(n - 1); // not zero
    for (int i = 0; i < n; ++i) {
      int mask = highestone;
      while (mask > 0) {
        int j = i ^ mask;
        if (j < n) {
          g.setEdge(i, j);
        }
        mask = mask >> 1;
      }
    }
    return g;
  }
Пример #7
0
 /**
  * Watts-Strogatz model. A bit modified though: by default assumes a directed graph. This means
  * that directed links are re-wired, and the undirected edges in the original (undirected) lattice
  * are modeled by double directed links pointing in opposite directions. Rewiring is done with
  * replacement, so the possibility of wiring two links to the same target is positive (though very
  * small).
  *
  * <p>Note that it is possible to pass an undirected graph as a parameter. In that case the output
  * is the directed graph produced by the method, converted to an undirected graph by dropping
  * directionality of the edges. This graph is still not from the original undirected WS model
  * though.
  *
  * @param g the graph to be wired
  * @param k lattice parameter: this is the out-degree of a node in the ring lattice before
  *     rewiring
  * @param p the probability of rewiring each
  * @param r source of randomness
  * @return returns g for convenience
  */
 public static Graph wireWS(Graph g, int k, double p, Random r) {
   // XXX unintuitive to call it WS due to the slight mods
   final int n = g.size();
   for (int i = 0; i < n; ++i) {
     for (int j = -k / 2; j <= k / 2; ++j) {
       if (j == 0) {
         continue;
       }
       int newedge = (i + j + n) % n;
       if (r.nextDouble() < p) {
         newedge = r.nextInt(n - 1);
         if (newedge >= i) {
           newedge++; // random _other_ node
         }
       }
       g.setEdge(i, newedge);
     }
   }
   return g;
 }
Пример #8
0
 private boolean dfs(
     final Node<Integer> node, final Node<Integer> goal, Graph<Integer> accumulator) {
   try {
     this.visitNode(node);
     if (node.value() == goal.value()) {
       return true;
     }
     ArrayList<Node<Integer>> stack = this.adjacencyList.get(node);
     for (Node<Integer> next : stack) {
       if (!this.isVisited(next) && next.value() != node.value()) {
         accumulator.setNode(next.value());
         accumulator.setEdge(next, node);
         if (dfs(next, goal, accumulator)) {
           return true;
         }
       }
     }
     return false;
   } catch (NodeNotFoundException e) {
     System.out.println("darf net passiern damn!");
     return false;
   }
 }