SimpleWeightedGraphs.jl icon indicating copy to clipboard operation
SimpleWeightedGraphs.jl copied to clipboard

Removing an edge just sets the edge weight to 0

Open evanfields opened this issue 6 years ago • 4 comments

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.

evanfields avatar Feb 04 '19 16:02 evanfields

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.

sbromberger avatar Feb 04 '19 17:02 sbromberger

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

simonschoelly avatar Feb 09 '19 05:02 simonschoelly

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.

EliasBcd avatar Mar 11 '19 13:03 EliasBcd

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.

giordano avatar Nov 21 '19 18:11 giordano