11

I am trying to use arbitrary edge properties in Graphs, and I am looking for easy ways to work with them.

In many cases it would be convenient to be able to set edge properties in a single go, specifying them as a list, where each element corresponds to the respective element in EdgeList. Is this possible? Is there an easy way?

There are a few standard edge properties which apply to edges only (thus the system knows that they are not vertex properties) and which can be set this way. EdgeWeight, EdgeCapacity and EdgeCost are such properties.

pg = SetProperty[g, EdgeWeight -> {2, 3}];

PropertyValue[{pg, 1 <-> 2}, EdgeWeight]
(* 2 *)

This won't work with arbitrary properties because the system doesn't know that they refer to edges.

pg = SetProperty[g, "foo" -> {2, 3}];

Options[pg, Properties]
(* {Properties -> {"GraphProperties" -> {"foo" -> {2, 3}}}} *)

It's set as a graph property, not as an edge property.

This won't work either:

pg = SetProperty[g, "foo" -> {1 <-> 2 -> 2, 2 <-> 3 -> 3}];

Options[pg, Properties]
(* {Properties -> {"GraphProperties" -> {"foo" -> {1 <-> 2 -> 2, 2 <-> 3 -> 3}}}} *)

This will work, but it's very cumbersome and probably slow even if automated:

pg = SetProperty[{g, 1 <-> 2}, "foo" -> 2];
pg = SetProperty[{pg, 2 <-> 3}, "foo" -> 3];

Options[pg, Properties]
(* {Properties -> {2 <-> 3 -> {"foo" -> 3}, 1 <-> 2 -> {"foo" -> 2}}} *)

Then the question is: is there a better way to set arbitrary edge properties in one go for all edges? Is there a better way to get arbitrary edge properties?

Why do I think that there may be a better way?

One hint is that WeightedAdjacencyMatrix has an undocumented (but used elsewhere in the documentation) option EdgeWeights which generates the adjacency matrix based on an arbitrary edge property.

WeightedAdjacencyMatrix[pg] // Normal
(* {{0, 1, 0}, {1, 0, 1}, {0, 1, 0} *)

WeightedAdjacencyMatrix[pg, EdgeWeight -> "foo"] // Normal
(* {{0, 2, 0}, {2, 0, 3}, {0, 3, 0}} *)

So I'm hopeful that there's a way to manage edge properties more easily.


Part of this question is mapping one edge property into another. Say, I import a GML file which has an edge attribute "Capacity", and I want to easily transfer this into Mathematica's standard EdgeCapacity.

Szabolcs
  • 234,956
  • 30
  • 623
  • 1,263

1 Answers1

3

You can set each edge properties with Properties like you observed:

g = CompleteGraph[50];

pg = SetProperty[g, 
   Properties -> 
    Thread[EdgeList[g] -> 
      List /@ Thread["foo" -> Range[EdgeCount[g]]]]];

WeightedAdjacencyMatrix[pg, 
   EdgeWeight -> "foo"][[;; 10, ;; 10]] // MatrixForm

{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, {1, 0, 50, 51, 52, 53, 54, 55, 56,
57}, {2, 50, 0, 98, 99, 100, 101, 102, 103, 104}, {3, 51, 98, 0,
145, 146, 147, 148, 149, 150}, {4, 52, 99, 145, 0, 191, 192, 193,
194, 195}, {5, 53, 100, 146, 191, 0, 236, 237, 238, 239}, {6, 54,
101, 147, 192, 236, 0, 280, 281, 282}, {7, 55, 102, 148, 193, 237,
280, 0, 323, 324}, {8, 56, 103, 149, 194, 238, 281, 323, 0, 365}, {9, 57, 104, 150, 195, 239, 282, 324, 365, 0}}

halmir
  • 15,082
  • 37
  • 53
  • But if there's a custom property other than "foo", then this will destroy it, no? Trying to work around that might get messy. – Szabolcs Oct 02 '15 at 13:32
  • @Szabolcs no, it will be added to existing ones.. – halmir Oct 02 '15 at 13:57
  • You're right, it doesn't! I assume it would simply re-set the Properties option on the graph object. Then getting the property is best done with WeightedAdjacencyMatrix in such cases? – Szabolcs Oct 02 '15 at 15:43
  • This is a special use of the EdgeWeight option in WegithedAdjacencyMatrix. Is there an equivalent for WeightedAdjacencyGraph? I.e. is there a direct way to fill the EdgeCapacity (not the EdgeWeight) from a matrix ? – Szabolcs Mar 09 '17 at 10:25
  • @Szabolcs not for EdgeCapacity... – halmir Mar 09 '17 at 15:03
  • It would be nice to have this feature: be able to fill other properties than EdgeWeight from the matrix, especially "standard" properties like EdgeCost, EdgeCapacity, etc. It would also be nice to be able to control what matrix element represents a missing edge. Now it is Infinity but it would sometimes be useful to be able to use 0 or 0.. Do you think it would be useful to request these features from Wolfram Support? Is there any chance that they might get added? – Szabolcs Mar 09 '17 at 15:38
  • @Szabolcs you could contact wolfram support and suggest feature. – halmir Mar 09 '17 at 17:15
  • I just re-discovered this. Can you give an answer here? I guess, setting would be done as you showed above, but I would still need to special-case standard properties like VertexWeight. What about getting? Is there anything better than what I showed in the question? – Szabolcs Apr 14 '17 at 16:56
  • About the WegithedAdjacencyMatrix method to get edge properties: it is much faster than PropertyValue, but it only works if "foo" is set for every single edge. Is there a fast method that also works when some edges do not have the property set? – Szabolcs Apr 14 '17 at 18:17
  • @Szabolcs then you need to use PropertyValue.. – halmir Apr 14 '17 at 21:58