Get or set vertex properties for all graph vertices at once
Pardon the rant, but IMO graph related property value infrastructure was poorly designed. The Graph[]
api was created before the advent of Associations, and I don't think it has changed since version 8.0.
Anyway, PropertyValue is typically faster than SetProperty according to the docs, maybe this works for you:
ClearAll@setVertexProp;
setVertexProp[g_, prop_, vals_] := Module[{h=g, vl=VertexList@g},
Do[PropertyValue[{h, vl[[i]]}, prop] = vals[[i]], {i,Length@vl}];
Return @ h
]
And the timings:
g=ExampleData[{"NetworkGraph","BipartiteDiseasomeNetwork"}];
values = getVertexProp[g, "Type"];
res=test1[g,"Foo",values];//AbsoluteTiming
res===g
(*
{0.0307, Null}
False
*)
I haven't run this through all of the use cases, but just to get the creative juices flowing:
setVertexPropSemiImperative[g_?GraphQ, prop_, values_List] :=
Module[{vertices = VertexList[g] // Developer`FromPackedArray, i = 0}
, If[Length[values] =!= Length[vertices]
, $Failed
, SetProperty[{g, vertices}, prop :> values[[++i]]]
]
]
Timings, on my machine:
setVertexProp[g, "Foo", values]; // AbsoluteTiming
(* 33.4833 *)
setVertexPropSemiImperative[g, "Foo", values]; // AbsoluteTiming
(* 0.0413123 *)
Notes
Developer`FromPackedArray?
is used here because it has been empirically shown that SetProperty
will not accept a packed array of indices (in version 11.1 at least):
SetProperty[{WheelGraph[3], {1, 2, 3}}, "foo" -> 999]
(* ... a graph ... *)
SetProperty[{WheelGraph[3], {1, 2, 3} // Developer`ToPackedArray}, "foo" -> 999]
(* $Failed *)
The VertexList
of the graph in the question is not a packed array. But some graph types have a packed vertex list, e.g.
PetersenGraph[] // VertexList // Developer`PackedArrayQ
(* True *)