I wanted to generate a directed random network adjacency matrix by determining the average in-degree myself.

Due to the rules of the model I use, any edge (or matrix element) can be zero or nonzero in an $n*n$ random matrix. Just like;

W = Array[RandomChoice[{-1, 0, 1}] &, {n, n}];
W // MatrixForm

and every element of the matrix

W[[j]][[i]] (*used part command*)

In case of a constant "number of nonzero $w_(ij)$ value" say k, it means every column or row ($w_{ji}$ for column or $w_{ij}$ for row - does not matter) will have k elements different than zero. And in case of an average value of k, the arithmetic average of all "k"s will be k. Is there any way to create a random matrix with each column will have k nonzero elements that I want to enter manually? And is there any way that number of nonzero elements can be different in each column and their average will be k?


  • 1
    $\begingroup$ Let's simplify the question and clarify a few things. It seems irrelevant that you can have either -1 or 1. All you seem to care about is if an adjacency matrix entry is zero or non-zero. I suggest you drop the irrelevant parts of the question, including that it is a Boolean network and that there are both 1 and -1. You want a directed network on $n$ nodes. Then clarify what you mean by average $k$. Do you want to fix the degree averaged over all vertices of a single network? I.e. should the model generate only networks where the average in-degree is precisely your prescribed value? $\endgroup$ – Szabolcs Jan 17 '17 at 15:35
  • $\begingroup$ Or are you averaging over several sampled networks from the model? Each network may have a different average degree, but the model has the property that the average mean-degree, as computed over many samples, is your prescribed value? Finally: many different models will satisfy these constraints but they won't produce the same distribution. Often by "random" one means selecting the model with maximal entropy. Is this what you need? $\endgroup$ – Szabolcs Jan 17 '17 at 15:36
  • $\begingroup$ Thank you for your advice. First as you stated, the importance is matrix entries are only zero or non-zero. Second, k(in degree) is the number of non-zero elements in each column. They ("k"s) can be same or their average can be k, which I want to determine. Simply, I just want to create a matrix that every of its columns will have k (I will enter the quantity in the beginning) nonzero elements. For now i m not interested in any distribution or entropy. And finally, I just want to learn the code required to create one network, not a sample of networks. Gonna edit the question. Thank you again. $\endgroup$ – Haliki Jan 17 '17 at 16:01
  • $\begingroup$ It's still not clear what you want to do. Do you want each vertex to have the same degree $k$? Or do you want the average degree to be $k$, while allowing different degrees for each vertex? Note that the average degree is just the total number of edges divided by the number of vertices. So you seem to be asking for a graph where you specify the number of edges. RandomGraph will do that, use DirectedGraph -> True as an option. $\endgroup$ – Szabolcs Jan 17 '17 at 18:10
  • $\begingroup$ Also, do you want just one graph satisfying these constraints, or a random graph model? $\endgroup$ – Szabolcs Jan 17 '17 at 18:10

Let $E$ be the number of edges and $V$ be the number of vertices in a directed graph. Then both the average in-degree and out-degree is $E/V$.

The following generates a random directed graph with v vertices and e edges, i.e. with a mean degree of e/v:

g = RandomGraph[{v, e}, DirectedEdges -> True]

Now we can take the adjacency matrix as a SparseArray:

am = AdjacencyMatrix[g]

These are the positions with nonzero elements:

pos = am["NonzeroPositions"];

This syntax is undocumented but well-known and convenient. You can alternatively use the documented ArrayRules.

Now to replace a random selection of n of these 1 elements with -1, we can use

am2 = SparseArray[
  pos -> RandomSample@Join[ConstantArray[-1, n], ConstantArray[1, Length[pos] - n]]

Plot it with MatrixPlot[am2].

If instead you want each vertex to have an out-degree of precisely k, then you can generate each row of the adjacency matrix with k 1s and v-k 0s. Transpose the result if you want the in-degree to be k.

One row can be generated using

RandomSample@Join[ConstantArray[1, k], ConstantArray[0, v - k]]
| improve this answer | |
  • $\begingroup$ That is exactly what I'm looking for. I've no words to explain my gratitude. $\endgroup$ – Haliki Jan 18 '17 at 11:25
  • $\begingroup$ One more thing if possible. When creating a random graph with g = RandomGraph[{v, e}, DirectedEdges -> True], how can I adjust it to include self loops? Some of "e (directed edges)" can be self loop. Its adjacency matrix does not have to be zero diagonal. $\endgroup$ – Haliki Jan 20 '17 at 10:40
  • $\begingroup$ @Haliki Use the option SelfLoops -> True. $\endgroup$ – Szabolcs Jan 20 '17 at 10:41
  • $\begingroup$ RandomGraph[{v, e}, DirectedEdges -> True, SelfLoops -> True] I'm sorry but its not available at the options. Also turn out to be red in syntax. I use Mathematica 10. $\endgroup$ – Haliki Jan 20 '17 at 10:52
  • $\begingroup$ @Haliki Try it, it works fine in M10.0. I don't know why it's undocumented. $\endgroup$ – Szabolcs Jan 20 '17 at 10:54

Not the answer you're looking for? Browse other questions tagged or ask your own question.