Skip to content

Commit e17c186

Browse files
InterdisciplinaryPhysicsTeampitmonticoneClaudMor
committed
Update
Implement a version of those constructors that takes a list of nodes as `vertices` and a list of 2-tuples of `MultilayerVertex`s as `edge_list` (still unfinished) TODO: - Complete the task above - Write tests for it and for the new layer constructors - Bring the new changes to Interlayers Co-Authored-By: Pietro Monticone <38562595+pitmonticone@users.noreply.github.com> Co-Authored-By: Claudio Moroni <43729990+ClaudMor@users.noreply.github.com>
1 parent b823555 commit e17c186

File tree

2 files changed

+62
-47
lines changed

2 files changed

+62
-47
lines changed

src/multilayeredge.jl

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -36,31 +36,23 @@ end
3636
3737
Convert to `MultilayerEdge{Nothing}(src, dst, nothing, NamedTuple())`.
3838
"""
39-
function MultilayerEdge(src::AbstractMultilayerVertex, dst::AbstractMultilayerVertex)
40-
return MultilayerEdge{Nothing}(src, dst, nothing, NamedTuple())
41-
end
39+
MultilayerEdge(src::AbstractMultilayerVertex, dst::AbstractMultilayerVertex) = MultilayerEdge{Nothing}(src, dst, nothing, NamedTuple())
40+
4241

4342
"""
4443
MultilayerEdge(src::AbstractMultilayerVertex, dst::AbstractMultilayerVertex, weight::U) where {U <: Real}
4544
4645
Convert to `MultilayerEdge{U}(src, dst, weight, NamedTuple())`.
4746
"""
48-
function MultilayerEdge(
49-
src::AbstractMultilayerVertex, dst::AbstractMultilayerVertex, weight::U
50-
) where {U<:Real}
51-
return MultilayerEdge{U}(src, dst, weight, NamedTuple())
52-
end
47+
MultilayerEdge(src::AbstractMultilayerVertex, dst::AbstractMultilayerVertex, weight::U) where {U<:Real} = MultilayerEdge{U}(src, dst, weight, NamedTuple())
48+
5349

5450
"""
5551
MultilayerEdge(src::AbstractMultilayerVertex, dst::AbstractMultilayerVertex, metadata::NamedTuple)
5652
5753
Convert to `MultilayerEdge{Nothing}(src, dst, nothing, metadata)`.
5854
"""
59-
function MultilayerEdge(
60-
src::AbstractMultilayerVertex, dst::AbstractMultilayerVertex, metadata::NamedTuple
61-
)
62-
return MultilayerEdge{Nothing}(src, dst, nothing, metadata)
63-
end
55+
MultilayerEdge(src::AbstractMultilayerVertex, dst::AbstractMultilayerVertex, metadata::NamedTuple) = MultilayerEdge{Nothing}(src, dst, nothing, metadata)
6456

6557
"""
6658
ME
@@ -112,9 +104,9 @@ function compare_multilayeredges(
112104
check_metadata::Bool=false,
113105
)
114106
# Check source
115-
_check_src = lhs.src == rhs.src ? true : return false
107+
lhs.src != rhs.src && return false
116108
# check destination
117-
_check_dst = lhs.dst == rhs.dst ? true : return false
109+
lhs.dst != rhs.dst && return false
118110
# Check weight
119111
_check_weight = false
120112
if check_weight

src/subgraphs/layer.jl

Lines changed: 55 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,13 @@ Constructor for `Layer`.
5757
# ARGUMENTS
5858
5959
- `descriptor::LayerDescriptor{T}`;
60-
- `vertices::Vector{<: MultilayerVertex}`;
61-
- `edge_list::Vector{<:MultilayerEdge}`;
60+
- `vertices::Union{Vector{<:MultilayerVertex}, Vector{<:Node}}`;
61+
- `edge_list::Union{Vector{<:MultilayerEdge}, Vector{Tuple{MultilayerVertex, MultilayerVertex}}}`;
6262
"""
6363
function Layer(
6464
descriptor::LayerDescriptor{T},
6565
vertices::Union{Vector{<:MultilayerVertex}, Vector{<:Node}},
66-
edge_list::Union{Vector{<:MultilayerEdge}, Vector{Tuple{MultilayerVertex, MultilayerVertex}}}
66+
edge_list::Union{Vector{<:MultilayerEdge}, Vector{Tuple{MultilayerVertex{nothing}, MultilayerVertex{nothing}}}}
6767
) where {T<:Integer}
6868
# First check that the vertices are of the correct type
6969
if hasproperty(eltype(vertices), :parameters)
@@ -89,25 +89,24 @@ function Layer(
8989
check_consistency=false,
9090
)
9191
# Add the vertices one by one
92-
@debug "" vertices isa Vector{MultilayerVertex{nothing}} vertices
93-
if vertices isa Vector{MultilayerVertex}
92+
if typeof(vertices) <: Vector{ <: MultilayerVertex}
9493
for mv in vertices
9594
add_vertex!(layer, mv)
9695
end
9796
else
9897
for node in vertices
99-
add_vertex!(layer, MV(node, descriptor.default_vertex_metadata(MV(node))))
98+
add_vertex!(layer, MV(node, metadata = descriptor.default_vertex_metadata(MV(node))))
10099
end
101100
end
102101
# Add the edges
103-
if edge_list isa Vector{MultilayerEdge}
102+
if typeof(edge_list) <: Vector{<:MultilayerEdge}
104103
for edge in edge_list
105104
add_edge!(layer, edge)
106105
end
107106
else
108107
for tup in edge_list
109108
src_mv,dst_mv = tup
110-
add_edge!(layer, ME(src_mv, dst_mv, weight = descriptor.default_edge_weight(src_mv, dst_mv), metadata = descriptor.default_edge_metadata(src_mv, dst_mv) ))
109+
add_edge!(layer, ME(src_mv, dst_mv, descriptor.default_edge_weight(src_mv, dst_mv), descriptor.default_edge_metadata(src_mv, dst_mv) ))
111110
end
112111
end
113112
return layer
@@ -130,7 +129,7 @@ Constructor for `Layer`.
130129
function Layer(
131130
name::Symbol,
132131
vertices::Vector{MultilayerVertex{nothing}},
133-
edge_list::Vector{<:MultilayerEdge},
132+
edge_list::Union{Vector{<:MultilayerEdge}, Vector{Tuple{MultilayerVertex, MultilayerVertex}}},
134133
null_graph::G,
135134
weighttype::Type{U};
136135
default_vertex_metadata::Function=mv -> NamedTuple(),
@@ -182,53 +181,77 @@ Return a random `Layer`.
182181
"""
183182
function Layer(
184183
name::Symbol,
185-
vertices::Vector{MultilayerVertex{nothing}},#Vector{MultilayerVertex{ <: Union{Val{name}, Val{nothing}}}},
184+
vertices::Union{V, N},#Vector{MultilayerVertex{ <: Union{Val{name}, Val{nothing}}}},
186185
ne::Int64,
187186
null_graph::G,
188187
weighttype::Type{U};
189188
default_vertex_metadata::Function=mv -> NamedTuple(),
190189
default_edge_weight::Function=(src, dst) -> nothing,
191190
default_edge_metadata::Function=(src, dst) -> NamedTuple(),
192191
allow_self_loops::Bool=false,
193-
) where {T<:Integer,U<:Real,G<:AbstractGraph{T}}
192+
) where {T<:Integer,U<:Real,G<:AbstractGraph{T}, V <: Vector{MultilayerVertex{nothing}}, N <: Vector{Node}}
194193

195-
descriptor = LayerDescriptor(
196-
name,
197-
null_graph,
198-
weighttype;
199-
default_vertex_metadata = default_vertex_metadata,
200-
default_edge_weight = default_edge_weight,
201-
default_edge_metadata = default_edge_metadata,
202-
)
194+
_nv = length(vertices)
195+
@assert(length(unique(vertices)) == _nv, "The argument `vertices` must be a unique list")
203196

204-
edge_list = MultilayerEdge[]
197+
directed = is_directed(null_graph)
198+
maxe = directed ? _nv*(_nv - 1) : _nv*(_nv - 1) ÷ 2
199+
200+
@assert(ne <= maxe, "The number of required edges, $ne, is greater than the number of edges the provided graph supports i.e. $maxe" )
201+
202+
edge_list = NTuple{2, MultilayerVertex}[] #MultilayerEdge
203+
already_chosen = Dict{MultilayerVertex, Vector{MultilayerVertex}}()
205204

205+
max_links_per_vertex = directed ? _nv : _nv-1
206206
for i in 1:ne
207207
# Generate a random vertex
208-
rand_vertex_1 = rand(vertices)
208+
rand_vertex_1 = rand(setdiff(vertices, [mv for mv in keys(already_chosen) if length(already_chosen[mv]) == max_links_per_vertex]))
209+
if !haskey(already_chosen, rand_vertex_1)
210+
already_chosen[rand_vertex_1] = Vector{MultilayerVertex}()
211+
end
212+
209213
# Generate another random vertex
210-
rand_vertex_2 = nothing
211214
# If we don't allow self loops, keep generating until we get a vertex that isn't the same as the previous one.
212-
if !allow_self_loops
213-
while isnothing(rand_vertex_2) || rand_vertex_2.node == rand_vertex_1.node
214-
rand_vertex_2 = rand(vertices)
215-
end
215+
rand_vertex_2 = if !allow_self_loops
216+
rand(setdiff(vertices, vcat([rand_vertex_1], already_chosen[rand_vertex_1] )) )
217+
else
218+
rand(setdiff(vertices, vcat(already_chosen[rand_vertex_1] )))
219+
end
220+
221+
push!(already_chosen[rand_vertex_1], rand_vertex_2)
222+
# Add the edge to the edge list. Convert it to a MultilayerVertex if a list of Nodes was given as `vertices`
223+
if @isdefined(V)
224+
push!(
225+
edge_list,
226+
(rand_vertex_1, rand_vertex_2)
227+
)
216228
else
217-
rand_vertex_2 = rand(vertices)
229+
push!(
230+
edge_list,
231+
(MV(rand_vertex_1), MV(rand_vertex_2))
232+
)
218233
end
219-
# Add the edge to the edge list
220-
push!(
234+
#= push!(
221235
edge_list,
222236
MultilayerEdge(
223237
MV(rand_vertex_1.node, name),
224238
MV(rand_vertex_2.node, name),
225239
default_edge_weight(rand_vertex_1, rand_vertex_2),
226240
default_edge_metadata(rand_vertex_1, rand_vertex_2),
227241
),
228-
)
242+
) =#
229243
end
230244

231-
edge_list = MultilayerEdge[rand() < 0.5 ? me : reverse(me) for me in edge_list]
245+
descriptor = LayerDescriptor(
246+
name,
247+
null_graph,
248+
weighttype;
249+
default_vertex_metadata = default_vertex_metadata,
250+
default_edge_weight = default_edge_weight,
251+
default_edge_metadata = default_edge_metadata,
252+
)
253+
254+
edge_list = [rand() < 0.5 ? me : reverse(me) for me in edge_list]
232255
layer = Layer(descriptor, vertices, edge_list)
233256

234257
return layer
@@ -791,7 +814,7 @@ Constructor for a `Layer` whose underlying graph is a `SimpleWeightedDiGraph` fr
791814
- `vertextype::Type{T} = Int64`: The type of the underlying integer labels associated to vertices.
792815
- `weighttype::Type{U} = Float64`: The type of the `MultilayerEdge` weights (even when the underlying Layer's graph is unweighted, we need to specify a weight type since the `MultilayerGraph`s will always be weighted)
793816
"""
794-
function simple_weighted_layer(
817+
function simple_weighted_dilayer(
795818
name::Symbol,
796819
vertices::Vector{MultilayerVertex{nothing}},
797820
edge_list::Vector{<:MultilayerEdge};

0 commit comments

Comments
 (0)