sbromberger / SimpleWeightedGraphs.jl

Simple weighted graphs. Requires LightGraphs.jl.
Other
49 stars 22 forks source link

Removing an edge just sets the edge weight to 0 #43

Open evanfields opened 5 years ago

evanfields commented 5 years ago
julia> g = SimpleWeightedGraph(2); add_edge!(g, 1, 2); collect(edges(g))
1-element Array{SimpleWeightedEdge{Int64,Float64},1}:
 Edge 1 => 2 with weight 1.0

julia> rem_edge!(g, 1, 2); collect(edges(g))
1-element Array{SimpleWeightedEdge{Int64,Float64},1}:
 Edge 1 => 2 with weight 0.0

Brief Slack discussion suggests this behavior arises from performance considerations around using sparse matrices; changing a value in a sparse matrix is much faster than changing the sparsity structure. For some use cases, this is totally okay. For example, if edges are "pipes" and edge weights are capacities, then a 0-weight edge and an absent edge are no different.

On the other hand, if edges represent possible movements between locations and edge weights are distances or costs, then a 0-weight edge means something very different than the absence of an edge.

sbromberger commented 5 years ago

My feeling is that edges for SimpleWeightedGraphs should ignore 0-weight edges, and that the package should explicitly state that it does not support edges with zero weights.

simonschoelly commented 5 years ago

We could implement the dropzeros! method for SimpleWeightedGraphs, so we could remove all zero weight edges after a bunch of edge removals.

EliasBcd commented 5 years ago

May I add that it also means that for some algorithm, like looking for a cycle in a DiGraph, a zero weight and the absence of an edge are completely different.

giordano commented 4 years ago

Today I bumped into an issue that I think is closely related to this one:

julia> using SimpleWeightedGraphs

julia> g = SimpleWeightedGraph(4)
{4, 0} undirected simple Int64 graph with Float64 weights

julia> ne(g)
0

julia> adjacency_matrix(g)
4×4 SparseArrays.SparseMatrixCSC{Int64,Int64} with 0 stored entries

julia> add_edge!(g, 1, 3)
true

julia> g.weights
4×4 SparseArrays.SparseMatrixCSC{Float64,Int64} with 2 stored entries:
  [3, 1]  =  1.0
  [1, 3]  =  1.0

julia> ne(g)
1

julia> adjacency_matrix(g)
4×4 SparseArrays.SparseMatrixCSC{Int64,Int64} with 2 stored entries:
  [3, 1]  =  1
  [1, 3]  =  1

julia> rem_edge!(g, 1, 3)
true

julia> g.weights
4×4 SparseArrays.SparseMatrixCSC{Float64,Int64} with 2 stored entries:
  [3, 1]  =  0.0
  [1, 3]  =  0.0

julia> ne(g)
1

julia> adjacency_matrix(g)
4×4 SparseArrays.SparseMatrixCSC{Int64,Int64} with 2 stored entries:
  [3, 1]  =  1

After removing the only edge, ne(g) returns 1 and the adjacency matrix is the same as 1-edge case.