File: sample_degseq.Rd

package info (click to toggle)
r-cran-igraph 2.1.4-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 27,044 kB
  • sloc: ansic: 204,981; cpp: 21,711; fortran: 4,090; yacc: 1,229; lex: 519; sh: 52; makefile: 8
file content (228 lines) | stat: -rw-r--r-- 9,451 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/games.R
\name{sample_degseq}
\alias{sample_degseq}
\alias{degseq}
\title{Generate random graphs with a given degree sequence}
\usage{
sample_degseq(
  out.deg,
  in.deg = NULL,
  method = c("configuration", "vl", "fast.heur.simple", "configuration.simple",
    "edge.switching.simple")
)

degseq(..., deterministic = FALSE)
}
\arguments{
\item{out.deg}{Numeric vector, the sequence of degrees (for undirected
graphs) or out-degrees (for directed graphs). For undirected graphs its sum
should be even. For directed graphs its sum should be the same as the sum of
\code{in.deg}.}

\item{in.deg}{For directed graph, the in-degree sequence. By default this is
\code{NULL} and an undirected graph is created.}

\item{method}{Character, the method for generating the graph. See Details.}

\item{...}{Passed to \code{realize_degseq()} if \sQuote{deterministic} is true,
or to \code{sample_degseq()} otherwise.}

\item{deterministic}{Whether the construction should be deterministic}
}
\value{
The new graph object.
}
\description{
It is often useful to create a graph with given vertex degrees. This function
creates such a graph in a randomized manner.
}
\details{
The \dQuote{configuration} method (formerly called "simple") implements the
configuration model. For undirected graphs, it puts all vertex IDs in a bag
such that the multiplicity of a vertex in the bag is the same as its degree.
Then it draws pairs from the bag until the bag becomes empty. This method may
generate both loop (self) edges and multiple edges. For directed graphs,
the algorithm is basically the same, but two separate bags are used
for the in- and out-degrees. Undirected graphs are generated
with probability proportional to \eqn{(\prod_{i<j} A_{ij} ! \prod_i A_{ii} !!)^{-1}},
where A denotes the adjacency matrix and !! denotes the double factorial.
Here A is assumed to have twice the number of self-loops on its diagonal.
The corresponding expression for directed graphs is \eqn{(\prod_{i,j} A_{ij}!)^{-1}}.
Thus the probability of all simple graphs
(which only have 0s and 1s in the adjacency matrix)
is the same, while that of non-simple ones depends on their edge and
self-loop multiplicities.

The \dQuote{fast.heur.simple} method (formerly called "simple.no.multiple")
generates simple graphs.
It is similar to \dQuote{configuration} but tries to avoid multiple and
loop edges and restarts the generation from scratch if it gets stuck.
It can generate all simple realizations of a degree sequence,
but it is not guaranteed to sample them uniformly.
This method is relatively fast and it will eventually succeed
if the provided degree sequence is graphical, but there is no upper bound on
the number of iterations.

The \dQuote{configuration.simple} method (formerly called "simple.no.multiple.uniform")
is
identical to \dQuote{configuration}, but if the generated graph is not simple,
it rejects it and re-starts the generation.
It generates all simple graphs with the same probability.

The \dQuote{vl} method samples undirected connected graphs approximately uniformly.
It is a Monte Carlo method based on degree-preserving edge switches.
This generator should be favoured if undirected and connected graphs are to be
generated and execution time is not a concern. igraph uses
the original implementation of Fabien Viger; for the algorithm, see
\url{https://www-complexnetworks.lip6.fr/~latapy/FV/generation.html}
and the paper \url{https://arxiv.org/abs/cs/0502085}.

The \dQuote{edge.switching.simple} is an MCMC sampler based on
degree-preserving edge switches. It generates simple undirected or directed graphs.
}
\examples{

## The simple generator
undirected_graph <- sample_degseq(rep(2, 100))
degree(undirected_graph)
is_simple(undirected_graph) # sometimes TRUE, but can be FALSE


directed_graph <- sample_degseq(1:10, 10:1)
degree(directed_graph, mode = "out")
degree(directed_graph, mode = "in")

## The vl generator
vl_graph <- sample_degseq(rep(2, 100), method = "vl")
degree(vl_graph)
is_simple(vl_graph) # always TRUE

## Exponential degree distribution
## We fix the seed as there's no guarantee
##  that randomly picked integers will form a graphical degree sequence
## (i.e. that there's a graph with these degrees)
## withr::with_seed(42, {
## exponential_degrees <- sample(1:100, 100, replace = TRUE, prob = exp(-0.5 * (1:100)))
## })
exponential_degrees <- c(
  5L, 6L, 1L, 4L, 3L, 2L, 3L, 1L, 3L, 3L, 2L, 3L, 6L, 1L, 2L,
  6L, 8L, 1L, 2L, 2L, 5L, 1L, 10L, 6L, 1L, 2L, 1L, 5L, 2L, 4L,
  3L, 4L, 1L, 3L, 1L, 4L, 1L, 1L, 5L, 2L, 1L, 2L, 1L, 8L, 2L, 7L,
  5L, 3L, 8L, 2L, 1L, 1L, 2L, 4L, 1L, 3L, 3L, 1L, 1L, 2L, 3L, 9L,
  3L, 2L, 4L, 1L, 1L, 4L, 3L, 1L, 1L, 1L, 1L, 2L, 1L, 3L, 1L, 1L,
  2L, 1L, 2L, 1L, 1L, 3L, 3L, 2L, 1L, 1L, 1L, 1L, 3L, 1L, 1L, 6L,
  6L, 3L, 1L, 2L, 3L, 2L
)
## Note, that we'd have to correct the degree sequence if its sum is odd
is_exponential_degrees_sum_odd <- (sum(exponential_degrees) \%\% 2 != 0)
if (is_exponential_degrees_sum_odd) {
  exponential_degrees[1] <- exponential_degrees[1] + 1
}
exp_vl_graph <- sample_degseq(exponential_degrees, method = "vl")
all(degree(exp_vl_graph) == exponential_degrees)

## An example that does not work
\dontshow{if (rlang::is_interactive()) withAutoprint(\{ # examplesIf}
## withr::with_seed(11, {
## exponential_degrees <- sample(1:100, 100, replace = TRUE, prob = exp(-0.5 * (1:100)))
## })
exponential_degrees <- c(
  1L, 1L, 2L, 1L, 1L, 7L, 1L, 1L, 5L, 1L, 1L, 2L, 5L, 4L, 3L,
  2L, 2L, 1L, 1L, 2L, 1L, 3L, 1L, 1L, 1L, 2L, 2L, 1L, 1L, 2L, 2L,
  1L, 2L, 1L, 4L, 3L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 3L, 1L, 4L, 3L,
  1L, 2L, 4L, 2L, 2L, 2L, 1L, 1L, 2L, 2L, 4L, 1L, 2L, 1L, 3L, 1L,
  2L, 3L, 1L, 1L, 2L, 1L, 2L, 3L, 2L, 2L, 1L, 6L, 2L, 1L, 1L, 1L,
  1L, 1L, 2L, 2L, 1L, 4L, 2L, 1L, 3L, 4L, 1L, 1L, 3L, 1L, 2L, 4L,
  1L, 3L, 1L, 2L, 1L
)
## Note, that we'd have to correct the degree sequence if its sum is odd
is_exponential_degrees_sum_odd <- (sum(exponential_degrees) \%\% 2 != 0)
if (is_exponential_degrees_sum_odd) {
  exponential_degrees[1] <- exponential_degrees[1] + 1
}
exp_vl_graph <- sample_degseq(exponential_degrees, method = "vl")
\dontshow{\}) # examplesIf}
## Power-law degree distribution
## We fix the seed as there's no guarantee
##  that randomly picked integers will form a graphical degree sequence
## (i.e. that there's a graph with these degrees)
## withr::with_seed(1, {
##  powerlaw_degrees <- sample(1:100, 100, replace = TRUE, prob = (1:100)^-2)
## })
powerlaw_degrees <- c(
  1L, 1L, 1L, 6L, 1L, 6L, 10L, 2L, 2L, 1L, 1L, 1L, 2L, 1L, 3L,
  1L, 2L, 43L, 1L, 3L, 9L, 1L, 2L, 1L, 1L, 1L, 1L, 1L, 4L, 1L,
  1L, 1L, 1L, 1L, 3L, 2L, 3L, 1L, 2L, 1L, 3L, 2L, 3L, 1L, 1L, 3L,
  1L, 1L, 2L, 2L, 1L, 4L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 1L, 7L, 1L,
  1L, 1L, 2L, 1L, 1L, 3L, 1L, 5L, 1L, 4L, 1L, 1L, 1L, 5L, 4L, 1L,
  3L, 13L, 1L, 2L, 1L, 1L, 2L, 1L, 2L, 1L, 1L, 1L, 1L, 1L, 2L,
  5L, 3L, 3L, 1L, 1L, 3L, 1L
)
## Note, that we correct the degree sequence if its sum is odd
is_exponential_degrees_sum_odd <- (sum(powerlaw_degrees) \%\% 2 != 0)
if (is_exponential_degrees_sum_odd) {
  powerlaw_degrees[1] <- powerlaw_degrees[1] + 1
}
powerlaw_vl_graph <- sample_degseq(powerlaw_degrees, method = "vl")
all(degree(powerlaw_vl_graph) == powerlaw_degrees)

## An example that does not work
\dontshow{if (rlang::is_interactive()) withAutoprint(\{ # examplesIf}
## withr::with_seed(2, {
##  powerlaw_degrees <- sample(1:100, 100, replace = TRUE, prob = (1:100)^-2)
## })
powerlaw_degrees <- c(
  1L, 2L, 1L, 1L, 10L, 10L, 1L, 4L, 1L, 1L, 1L, 1L, 2L, 1L, 1L,
  4L, 21L, 1L, 1L, 1L, 2L, 1L, 4L, 1L, 1L, 1L, 1L, 1L, 14L, 1L,
  1L, 1L, 3L, 4L, 1L, 2L, 4L, 1L, 2L, 1L, 25L, 1L, 1L, 1L, 10L,
  3L, 19L, 1L, 1L, 3L, 1L, 1L, 2L, 8L, 1L, 3L, 3L, 36L, 2L, 2L,
  3L, 5L, 2L, 1L, 4L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L,
  1L, 4L, 1L, 1L, 1L, 2L, 1L, 1L, 1L, 4L, 18L, 1L, 2L, 1L, 21L,
  1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L
)
## Note, that we correct the degree sequence if its sum is odd
is_exponential_degrees_sum_odd <- (sum(powerlaw_degrees) \%\% 2 != 0)
if (is_exponential_degrees_sum_odd) {
  powerlaw_degrees[1] <- powerlaw_degrees[1] + 1
}
powerlaw_vl_graph <- sample_degseq(powerlaw_degrees, method = "vl")
all(degree(powerlaw_vl_graph) == powerlaw_degrees)
\dontshow{\}) # examplesIf}
}
\seealso{
\code{\link[=simplify]{simplify()}} to get rid of the multiple and/or loops edges,
\code{\link[=realize_degseq]{realize_degseq()}} for a deterministic variant.

Random graph models (games)
\code{\link{erdos.renyi.game}()},
\code{\link{sample_}()},
\code{\link{sample_bipartite}()},
\code{\link{sample_chung_lu}()},
\code{\link{sample_correlated_gnp}()},
\code{\link{sample_correlated_gnp_pair}()},
\code{\link{sample_dot_product}()},
\code{\link{sample_fitness}()},
\code{\link{sample_fitness_pl}()},
\code{\link{sample_forestfire}()},
\code{\link{sample_gnm}()},
\code{\link{sample_gnp}()},
\code{\link{sample_grg}()},
\code{\link{sample_growing}()},
\code{\link{sample_hierarchical_sbm}()},
\code{\link{sample_islands}()},
\code{\link{sample_k_regular}()},
\code{\link{sample_last_cit}()},
\code{\link{sample_pa}()},
\code{\link{sample_pa_age}()},
\code{\link{sample_pref}()},
\code{\link{sample_sbm}()},
\code{\link{sample_smallworld}()},
\code{\link{sample_traits_callaway}()},
\code{\link{sample_tree}()}
}
\author{
Gabor Csardi \email{csardi.gabor@gmail.com}
}
\concept{games}
\keyword{graphs}