Skip to main content

bugs - Removing edge weights from a Graph


Bug introduced in 8.0 and persisting through 12.0




How can I remove EdgeWeights from a Graph without affecting any other properties of the graph?


Let's construct a graph with weights:


g = RandomGraph[{10, 20}, EdgeWeight -> ConstantArray[1, 20]]


Based on the documentation I would expect the following to return Automatic (the same thing it returns for a graph that has no edge weights):


PropertyValue[RemoveProperty[g, EdgeWeight], EdgeWeight]

(* ==> {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} *)

However, it returns the weights that were originally set.


The following seems to work, but it removes other properties as well


PropertyValue[RemoveProperty[g], EdgeWeight]

(* ==> Automatic *)


Extracting the edges and vertices, then re-building the graph will discard other properties as well. Graph objects are atomic, and they don't have a Mathematica-expression form, so trying to modify them at the expression level is not a possibility either.


How can one then remove EdgeWeights from a Graph without modifying any other properties of the Graph?


Update: It turns out WeightedGraphQ@RemoveProperty[g] still returns True. So even though the weight values are removed, the system still considers the graph to be weighted.



Answer



This has to be a bug. I think Graph never really associates EdgeWeight with corresponding edges.


Here is a simplified example.


g = Graph[{1, 2, 3}, {
Property[1 <-> 2, EdgeWeight -> x],
1 <-> 3,

Property[2 <-> 3, EdgeWeight -> y]
}];

gNew = RemoveProperty[{g, 1 <-> 2}, EdgeWeight];
gNew2 = SetProperty[{g, 1 <-> 2}, EdgeWeight -> Missing["Nonexistent"]];


Outer[
PropertyValue[{#1, #2}, EdgeWeight] &,
{g, gNew, gNew2},

{1 <-> 2, 1 <-> 3, 2 <-> 3}
] // TableForm[#,
TableHeadings -> {{"g", "gNew", "gNew2"},
{1 <-> 2, 1 <-> 3, 2 <-> 3}}] & // Quiet

comparison of EdgeWeight list after removing


Notice the gNew row, how EdgeWeights are mis-aligned when the preceding one (i.e. x) deleted. And the 3rd column gives us a clue how PropertyValue extracts EdgeWeight -- that is, by Part.


I would definitely call this a bug.




The workaround I can come up with are two ways. The easy way is as I did for gNew2 -- instead of removing it, replacing it with a placeholder. While the hard way is to permute the to-be-delete edge to the end of edge-list before performing the delete:



myRemoveEdgeWeight[g_, e_] :=
Module[{vl = VertexList[g], el = EdgeList[g], pos, ewl, ew},
pos = Position[el, e];
el = Insert[Delete[el, pos], e, -1];
ewl = PropertyValue[g, EdgeWeight];
ew = Extract[ewl, pos][[1]];
ewl = Insert[Delete[ewl, pos], ew, -1];
Graph[vl, el, EdgeWeight -> ewl] //
RemoveProperty[{#, e}, EdgeWeight] &
]


PropertyValue[{myRemoveEdgeWeight[g, 1 <-> 2], #}, EdgeWeight] & /@
{1 <-> 2, 1 <-> 3, 2 <-> 3}


{{1, y}[[3]], 1, y}

Comments