views:

97

answers:

5

How do I make a Mathematica graph from edges with named vertices? EG:

http://pastebin.com/Se1Nhe3M

I've tried the above and several variations, but Combinatorica never quite accepts it right. Apparently, Graph[] wants coordinate positions, which I want Combinatorica to figure out itself.

AddVertex to EmptyGraph[0] (or whatever) also fails.

GraphUtilities isn't an option, since I want to do fairly complex analysis on my graphs.

This seems like a simple problem. Graphviz easily creates graphs from edges with named vertices, so I'm sure Mathematica can too?

I've read:

http://stackoverflow.com/questions/2941727/showgraph-e1-e2-e1-e3-e1-e2-e3-what-is-the-problem-here

but it doesn't seem to help with my specific case.

+2  A: 

If you have Mathematica 7, try the built-in GraphPlot:

GraphPlot[{"Conga" -> "Egypt", "Egypt" -> "Conga", 
  "Conga" -> "Sarah Desert", "Sarah Desert" -> "Conga", 
  "Egypt" -> "Europe", "Europe" -> "Egypt", "Egypt" -> "Arabia", 
  "Arabia" -> "Egypt", "Egypt" -> "Sarah Desert", 
  "Sarah Desert" -> "Egypt", "UK" -> "Europe", "Europe" -> "UK", 
  "UK" -> "Iceland", "Iceland" -> "UK", "UK" -> "Greenland", 
  "Greenland" -> "UK", "Europe" -> "Arabia", "Arabia" -> "Europe", 
  "Europe" -> "Germany", "Germany" -> "Europe", "Europe" -> "Iceland",
   "Iceland" -> "Europe", "Europe" -> "Sarah Desert", 
  "Sarah Desert" -> "Europe", "Germany" -> "Russia", 
  "Russia" -> "Germany", "Germany" -> "Arabia", "Arabia" -> "Germany",
   "Germany" -> "Iceland", "Iceland" -> "Germany", 
  "Germany" -> "Irakistan", "Irakistan" -> "Germany", 
  "Austr(al)ia" -> "China", "China" -> "Austr(al)ia", 
  "Arabia" -> "Irakistan", "Irakistan" -> "Arabia", 
  "Canada" -> "More Russia", "More Russia" -> "Canada", 
  "Canada" -> "USA", "USA" -> "Canada", 
  "Canada" -> "Andy's Mountains", "Andy's Mountains" -> "Canada", 
  "More Russia" -> "Russia", "Russia" -> "More Russia", 
  "More Russia" -> "China", "China" -> "More Russia", 
  "More Russia" -> "Irakistan", "Irakistan" -> "More Russia", 
  "China" -> "Irakistan", "Irakistan" -> "China", 
  "USA" -> "Greenland", "Greenland" -> "USA", 
  "USA" -> "Andy's Mountains", "Andy's Mountains" -> "USA", 
  "Brazil" -> "Sarah Desert", "Sarah Desert" -> "Brazil", 
  "Brazil" -> "Andy's Mountains", "Andy's Mountains" -> "Brazil", 
  "Russia" -> "Irakistan", "Irakistan" -> "Russia"}, 
 DirectedEdges -> True]

That will give you the following, for example:

alt text

There are many options for layout, vertex and edge labeling and style, etc.

Michael Pilat
Thanks, Michael. This does create a cool represenatation of my graph, but I also want to use things like MaximumClique[] and other Combinatorica functions, so I think I need a real Mathematica Graph[] object, not just a visual representation.
barrycarter
+1  A: 

If the sticking point is nodes represented as strings and the heavy-duty graph analysis functions want them as integers, you might consider mapping your strings to integers and vice versa:

nodes = DeleteDuplicates@Flatten[graph /. Rule -> List]

{"Conga", "Egypt", "Sarah Desert", "Europe", "Arabia", "UK", "Iceland", 
 "Greenland", "Germany", "Russia", "Irakistan", "Austr(al)ia", "China", "Canada",
 "More Russia", "USA", "Andy's Mountains", "Brazil"}

Now you have the list of nodes. Next do the mapping to and from integers:

each[{i_, s_}, Transpose[{Range@Length@nodes, nodes}],
  numify[s] = i;
  namify[i] = s]

You can now easily convert the nodes to and from integers:

numify["Europe"]

4

namify[4]

"Europe"

Convert the whole graph like this:

graph /. s_String -> numify[s]

Note that each is the following utility function, discussed here: http://stackoverflow.com/questions/160216/foreach-loop-in-mathematica

SetAttributes[each, HoldAll];               (* each[pattern, list, body]      *)
each[pat_, lst_, bod_] := ReleaseHold[      (*  converts pattern to body for  *)
  Hold[Cases[Evaluate@lst, pat:>bod];]];    (*   each element of list.        *)
dreeves
Yup, that was it. I feel dumb. More specifically:<pre><code>(* this works fine *)ShowGraph[FromOrderedPairs[{{1,2}}]](*this does not *)ShowGraph[FromOrderedPairs[{{"x","y"}}]](* this is what confused me *)FromOrderedPairs[{{"x","y"}}] Graph[{{{x, y}}}, CircularEmbedding[Max[x, y]], EdgeDirection -> True]It looks like a graph but it isn't one. Also "x" (string) somehow gets changed to x (variable).</code></pre>
barrycarter
+1  A: 

Since you asked specifically for Combinatorica and since I'm always hesitant to start tromping around on the internal details of a package then perhaps this will help you:

Load Combinatorica using << or Needs if your version needs this. Then using your data:

edges={{"Conga" -> "Egypt"}, {"Egypt" -> "Conga"}, {"Conga" -> "Sarah Desert"}, {"Sarah Desert" -> "Conga"}, {"Egypt" -> "Europe"}, {"Europe" -> "Egypt"}, {"Egypt" -> "Arabia"}, {"Arabia" -> "Egypt"}, {"Egypt" -> "Sarah Desert"}, {"Sarah Desert" -> "Egypt"}, {"UK" -> "Europe"}, {"Europe" -> "UK"}, {"UK" -> "Iceland"}, {"Iceland" -> "UK"}, {"UK" -> "Greenland"}, {"Greenland" -> "UK"}, {"Europe" -> "Arabia"}, {"Arabia" -> "Europe"}, {"Europe" -> "Germany"}, {"Germany" -> "Europe"}, {"Europe" -> "Iceland"}, {"Iceland" -> "Europe"}, {"Europe" -> "Sarah Desert"}, {"Sarah Desert" -> "Europe"}, {"Germany" -> "Russia"}, {"Russia" -> "Germany"}, {"Germany" -> "Arabia"}, {"Arabia" -> "Germany"}, {"Germany" -> "Iceland"}, {"Iceland" -> "Germany"}, {"Germany" -> "Irakistan"}, {"Irakistan" -> "Germany"}, {"Austr(al)ia" -> "China"}, {"China" -> "Austr(al)ia"}, {"Arabia" -> "Irakistan"}, {"Irakistan" -> "Arabia"}, {"Canada" -> "More Russia"}, {"More Russia" -> "Canada"}, {"Canada" -> "USA"}, {"USA" -> "Canada"}, {"Canada" -> "Andy's Mountains"}, {"Andy's Mountains" -> "Canada"}, {"More Russia" -> "Russia"}, {"Russia" -> "More Russia"}, {"More Russia" -> "China"}, {"China" -> "More Russia"}, {"More Russia" -> "Irakistan"}, {"Irakistan" -> "More Russia"}, {"China" -> "Irakistan"}, {"Irakistan" -> "China"}, {"USA" -> "Greenland"}, {"Greenland" -> "USA"}, {"USA" -> "Andy's Mountains"}, {"Andy's Mountains" -> "USA"}, {"Brazil" -> "Sarah Desert"}, {"Sarah Desert" -> "Brazil"}, {"Brazil" -> "Andy's Mountains"}, {"Andy's Mountains" -> "Brazil"}, {"Russia" -> "Irakistan"}, {"Irakistan" -> "Russia"}}/.Rule[from_,to_]->{from,to};

labels={"Canada", "USA", "Greenland", "Brazil", "Andy's Mountains", "UK", "Iceland", "Germany", "Europe", "Russia", "More Russia", "Irakistan", "Arabia", "China", "Austr(al)ia", "Egypt", "Sarah Desert", "Conga"};

numberededges=Partition[Flatten[edges/.Thread[Rule[labels,Range[Length[labels]]]]],2];

ShowGraph[AddEdges[EmptyGraph[Length[labels]],numberededges], VertexLabel->labels,PlotRange->All]

Now if the autoreformatting hasn't ruined this then I think you might be ready.

I haven't made the edges directed in this and I assume you might want to do that. Hopefully this is enough to get you started.

All this is based on paging back and forth for a few minutes in "Computational Discrete Mathematics: Combinatorics and Graph Theory with Mathematica" by Pemmaraju and Skiena. I believe anyone trying to use Combinatorica without having this in front of them is just nuts. I wish we could convince them to bring out a new edition of that, fix some of the typos, and get them to make it a little easier for someone who doesn't know all about Combinatorica to be able to use it to get started.

Thanks, Bill. Question: can I do things like MaximumClique using this? I think I need an actual Graph[]. ShowGraph is weird in that it works on vertices/edges, but not on Combinatorica graphs.
barrycarter
FullForm[AddEdges[EmptyGraph[Length[labels]],numberededges]] shows you that the result I provided is a full fleged Combinatorica graph and which you should be able to use in any of the available Combinatorica graph functions.For example, ShowGraph[] takes a Combinatorica graph and renders it into a collection of graphics primitives that can be displayed.Perhaps I should have writteng=AddEdges[EmptyGraph[Length[labels],Type->Directed],numberededges];ShowGraph[g,VertexLabel->labels, PlotRange->All]Does MaximumClique work on g? Is what I wrote correct and clear enough now?
MaximumClique[g]/.Thread[Rule[Range[Length[labels]],labels]]returns{Canada, USA, Andy's Mountains}
A: 
Yaroslav Bulatov
I had to delete the line that imports Combinatorica because it breaks formatting, any idea how to make it work?
Yaroslav Bulatov
A: 

Combinatorica Graph[] object is not easy to deal with. Did you try www.sagenb.org? Sage's Graph object is really cool.

Sazzad
I've heard Sage is aiming to be open-source Mathematica, which is great. Does Sage's Graph object do things like MaximumClique, PlanarQ, etc? IE, some of the harder graph functions?
barrycarter
MaximumClique : YES. PlanarQ : NO. Please refer to this page: http://wiki.sagemath.org/CombinatoricaCompare
Sazzad