@@ -66,13 +66,13 @@ badjlist = [[1,2,5,6],[3,4,6]]
66
66
bg = BipartiteGraph(7, fadjlist, badjlist)
67
67
```
68
68
"""
69
- mutable struct BipartiteGraph{I<: Integer ,M} <: LightGraphs.AbstractGraph{I}
69
+ mutable struct BipartiteGraph{I<: Integer ,F <: Vector{Vector{I}} ,B <: Union{Vector{Vector{I}},Nothing} , M} <: LightGraphs.AbstractGraph{I}
70
70
ne:: Int
71
- fadjlist:: Vector{Vector{I}} # `fadjlist[src] => dsts`
72
- badjlist:: Vector{Vector{I}} # `badjlist[dst] => srcs`
71
+ fadjlist:: F # `fadjlist[src] => dsts`
72
+ badjlist:: B # `badjlist[dst] => srcs`
73
73
metadata:: M
74
74
end
75
- BipartiteGraph (ne:: Integer , fadj:: AbstractVector , badj:: AbstractVector ) = BipartiteGraph (ne, fadj, badj, nothing )
75
+ BipartiteGraph (ne:: Integer , fadj:: AbstractVector , badj:: Union{ AbstractVector} = nothing ) = BipartiteGraph (ne, fadj, badj, nothing )
76
76
77
77
"""
78
78
```julia
@@ -84,7 +84,9 @@ Test whether two [`BipartiteGraph`](@ref)s are equal.
84
84
function Base. isequal (bg1:: BipartiteGraph{T} , bg2:: BipartiteGraph{T} ) where {T<: Integer }
85
85
iseq = (bg1. ne == bg2. ne)
86
86
iseq &= (bg1. fadjlist == bg2. fadjlist)
87
- iseq &= (bg1. badjlist == bg2. badjlist)
87
+ if bg1. badjlist != = nothing && bg2. badjlist != = nothing
88
+ iseq &= (bg1. badjlist == bg2. badjlist)
89
+ end
88
90
iseq
89
91
end
90
92
@@ -93,16 +95,16 @@ $(SIGNATURES)
93
95
94
96
Build an empty `BipartiteGraph` with `nsrcs` sources and `ndsts` destinations.
95
97
"""
96
- function BipartiteGraph (nsrcs:: T , ndsts:: T ; metadata= nothing ) where T
98
+ function BipartiteGraph (nsrcs:: T , ndsts:: T , backedge :: Val{B} = Val ( true ) ; metadata= nothing ) where {T,B}
97
99
fadjlist = map (_-> T[], 1 : nsrcs)
98
- badjlist = map (_-> T[], 1 : ndsts)
100
+ badjlist = B ? map (_-> T[], 1 : ndsts) : nothing
99
101
BipartiteGraph (0 , fadjlist, badjlist, metadata)
100
102
end
101
103
102
104
Base. eltype (:: Type{<:BipartiteGraph{I}} ) where I = I
103
105
function Base. empty! (g:: BipartiteGraph )
104
106
foreach (empty!, g. fadjlist)
105
- foreach (empty!, g. badjlist)
107
+ g . badjlist === nothing || foreach (empty!, g. badjlist)
106
108
g. ne = 0
107
109
if g. metadata != = nothing
108
110
foreach (empty!, g. metadata)
@@ -111,17 +113,22 @@ function Base.empty!(g::BipartiteGraph)
111
113
end
112
114
Base. length (:: BipartiteGraph ) = error (" length is not well defined! Use `ne` or `nv`." )
113
115
116
+ @noinline throw_no_back_edges () = throw (ArgumentError (" The graph has no back edges." ))
117
+
114
118
if isdefined (LightGraphs, :has_contiguous_vertices )
115
119
LightGraphs. has_contiguous_vertices (:: Type{<:BipartiteGraph} ) = false
116
120
end
117
121
LightGraphs. is_directed (:: Type{<:BipartiteGraph} ) = false
118
122
LightGraphs. vertices (g:: BipartiteGraph ) = (𝑠vertices (g), 𝑑vertices (g))
119
123
𝑠vertices (g:: BipartiteGraph ) = axes (g. fadjlist, 1 )
120
- 𝑑vertices (g:: BipartiteGraph ) = axes (g. badjlist, 1 )
124
+ 𝑑vertices (g:: BipartiteGraph ) = g . badjlist === nothing ? throw_no_back_edges () : axes (g. badjlist, 1 )
121
125
has_𝑠vertex (g:: BipartiteGraph , v:: Integer ) = v in 𝑠vertices (g)
122
126
has_𝑑vertex (g:: BipartiteGraph , v:: Integer ) = v in 𝑑vertices (g)
123
127
𝑠neighbors (g:: BipartiteGraph , i:: Integer , with_metadata:: Val{M} = Val (false )) where M = M ? zip (g. fadjlist[i], g. metadata[i]) : g. fadjlist[i]
124
- 𝑑neighbors (g:: BipartiteGraph , j:: Integer , with_metadata:: Val{M} = Val (false )) where M = M ? zip (g. badjlist[j], (g. metadata[i][j] for i in g. badjlist[j])) : g. badjlist[j]
128
+ function 𝑑neighbors (g:: BipartiteGraph , j:: Integer , with_metadata:: Val{M} = Val (false )) where M
129
+ g. badjlist === nothing && throw_no_back_edges ()
130
+ M ? zip (g. badjlist[j], (g. metadata[i][j] for i in g. badjlist[j])) : g. badjlist[j]
131
+ end
125
132
LightGraphs. ne (g:: BipartiteGraph ) = g. ne
126
133
LightGraphs. nv (g:: BipartiteGraph ) = sum (length, vertices (g))
127
134
LightGraphs. edgetype (g:: BipartiteGraph{I} ) where I = BipartiteEdge{I}
@@ -157,14 +164,16 @@ function LightGraphs.add_edge!(g::BipartiteGraph, edge::BipartiteEdge, md=NO_MET
157
164
end
158
165
159
166
g. ne += 1
160
- @inbounds list = badjlist[d]
161
- index = searchsortedfirst (list, s)
162
- insert! (list, index, s)
167
+ if badjlist != = nothing
168
+ @inbounds list = badjlist[d]
169
+ index = searchsortedfirst (list, s)
170
+ insert! (list, index, s)
171
+ end
163
172
return true # edge successfully added
164
173
end
165
174
166
175
function LightGraphs. add_vertex! (g:: BipartiteGraph{T} , type:: VertType ) where T
167
- if type === DST
176
+ if type === DST && g . badjlist != = nothing
168
177
push! (g. badjlist, T[])
169
178
elseif type === SRC
170
179
push! (g. fadjlist, T[])
0 commit comments