-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathrand_rw.jl
120 lines (87 loc) · 2.67 KB
/
rand_rw.jl
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
# random graph generating functions
using Distributions
function randomWalkMultiGraph(;n_edges::Int=100, alpha_prob::AbstractFloat=0.5,length_distribution::DiscreteUnivariateDistribution=Poisson(1), sizeBias::Bool=false)
g = zeros(Int64,n_edges,2)
g[1,:] = [1 2] # first edge
n = 1
nv = 2
deg = [1;1]
min_offset = 1 - minimum(length_distribution)
coinDist = Bernoulli(alpha_prob)
for i = 2:n_edges
coin = rand(coinDist)
vweights = (sizeBias ? deg : ones(Float64,nv) )
stv = wsample(1:nv, vweights) # sample start vertex
if(Bool(coin)) # add a vertex
nv += 1
g[i,:] = [stv,nv]
push!(deg,1)
else # random walk edge
K = rand(length_distribution) + min_offset
edv = (K > 0 ? randomwalk(g[1:i-1,:], stv, K)[end] : stv)
g[i,:] = [stv,edv]
deg[stv] += 1
deg[edv] += 1
end
end
return g
end
function randomWalkSimpleGraph(;n_edges::Int=100, alpha_prob::AbstractFloat=0.5,length_distribution::DiscreteUnivariateDistribution=Poisson(1), sizeBias::Bool=false)
# generates a simple graph from the random walk model with new vertex probability β
# and random walk length distribution `length_distribution`
g = zeros(Int64,n_edges,2)
g[1,:] = [1 2] # first edge
n = 1
nv = 2
deg = [1;1]
min_offset = 1 - minimum(length_distribution)
coinDist = Bernoulli(alpha_prob)
for i = 2:n_edges
coin = rand(coinDist)
vweights = (sizeBias ? deg : ones(Float64,nv) )
stv = wsample(1:nv, vweights) # sample start vertex
if(Bool(coin)) # add a vertex
nv += 1
g[i,:] = [stv,nv]
push!(deg,1)
else # random walk edge
K = rand(length_distribution) + min_offset
edv = (K > 0 ? randomwalk(g[1:i-1,:], stv, K)[end] : stv)
if edv==stv || has_edge(g[1:i-1,:], stv, edv) # new vertex
nv += 1
g[i,:] = [stv,nv]
push!(deg,1)
else
g[i,:] = [stv,edv]
deg[stv] += 1
deg[edv] += 1
end
end
end
return g
end
function has_edge(edgelist::Array{Int64,2},edge::Vector{Int64})
"""
Checks for the directed edge in edgelist
"""
return any( [ edge == edgelist[i,:] for i = 1:size(edgelist,1) ] )
end
function has_edge(edgelist::Array{Int64,2},v1::Int64,v2::Int64)
"""
Checks for the undirected edge [v1, v2] in edgelist
"""
return any( [ ([v1,v2] == edgelist[i,:] || [v2,v1] == edgelist[i,:]) for i = 1:size(edgelist,1) ] )
end
function randomwalk(edgelist::Array{Int64,2},start_vertex::Int64,len::Int64)
A = edgelist2adj(edgelist)
nv = size(A,2)
vc = start_vertex
p = zeros(Int64,len+1)
p[1] = vc
for k = 1:len
vn = wsample(1:nv,full(A[:,vc]))
vc = vn
p[k+1] = vc
end
return p
end