WeightedAdjacencyGraph
takes Infinity
(not 0
!) to represent absent connections.
The IGraph/M package provides the IGWeightedAdjacencyGraph
and IGWeightedAdjacencyMatrix
functions, both of which let you specify which element should represent absent connections. By default, zero is used in both.
Here's a function that is analogous to WeightedAdjacencyMatrix
, but also allows specifying the element that represents absent connections.
Options[weightedAdjacencyMatrix] = Options[WeightedAdjacencyMatrix];
weightedAdjacencyMatrix[graph_?GraphQ, unconnected : Except[_?OptionQ] : 0, opt : OptionsPattern[]] :=
With[{sa = WeightedAdjacencyMatrix[graph, opt]},
SparseArray[sa["NonzeroPositions"] -> sa["NonzeroValues"], Dimensions[sa], unconnected]
]
(But Carl's is probably faster.)
Since IGWeightedAdjacencyGraph
is implemented purely in Mathematica, I will copy here its current implementation (Feb 2018). It relies on an undocumented syntax of Graph
where edges are given in terms of vertex indices (not vertex names).
Example: Graph[{a,b,c}, {{1,2}, {1,3}}]
gives the same graph as Graph[{a,b,c}, {a<->b, a<->c}]
. Since the index-based edge list may be a packed array, operations on it can be very fast. This implementation of IGWeightedAdjacencyGraph
is typically slightly faster than WeightedAdjacencyGraph
—I believe for this reason.
IGWeightedAdjacencyGraph[wam_?SquareMatrixQ, unconnected : Except[_?OptionQ] : 0, opt : OptionsPattern[Graph]] :=
IGWeightedAdjacencyGraph[Range@Length[wam], wam, unconnected, opt]
IGWeightedAdjacencyGraph[vertices_List, wam_?SquareMatrixQ, unconnected : Except[_?OptionQ] : 0, opt : OptionsPattern[Graph]] :=
Module[{sa = SparseArray[wam, Automatic, unconnected], directedEdges = OptionValue[DirectedEdges]},
If[Length[vertices] != Length[sa],
Message[IGWeightedAdjacencyGraph::ndims, vertices, wam];
Return[$Failed]
];
If[directedEdges === Automatic,
directedEdges = Not@SymmetricMatrixQ[sa]
];
If[Not[directedEdges],
sa = UpperTriangularize[sa]
];
Graph[vertices, sa["NonzeroPositions"], EdgeWeight -> sa["NonzeroValues"], DirectedEdges -> directedEdges, opt]
]
The key parts of the code are:
Re-build the sparse matrix with the desired background element: sa = SparseArray[wam, Automatic, unconnected]
. Note that this does not change the matrix (like in Carl's answer). It simply changes what is stored explicitly.
Extract the non-zero positions and values to build the weighted graph: Graph[vertices, sa["NonzeroPositions"], EdgeWeight -> sa["NonzeroValues"]
The rest is just for handling directed/undirected graphs and error checking.