9

I am completely new to designing algorithms with graphs. I am following CLRS and other video lectures in Youtube, notably from IIT/MIT. They are pretty good, and I currently have decent idea about graph data structures, search, spanning-tree, etc. However, I am completely clueless as to how to identify a coding problem (the likes of which you see in Topcoder/Codechef) that requires a graph-based approach. In which problem, shall I need to use a minimum spanning tree? Where do I need to use Prim's Algorithm?

Is there ay book/resource which covers lots of problems on graphs, explaining (well, kind of spoon feeding) how to identify that this problem requires a graph-based solution, and finally how to do it?

4
  • Implement some path-finding algorithms. Those are used in nearly all games, where a player runs over the map to calculate his path.
    – Kolyunya
    Jun 3, 2013 at 7:21
  • Graph, Network and Algorithms by Dieter Jungnickel.
    – Manoj R
    Jun 3, 2013 at 8:16
  • routing wires on a chip
    – jk.
    Jun 3, 2013 at 9:37
  • Not quite an answer, but the graphs tag on the codegolf stack will give you a few problems which you could treat as exercises (and you could also search for graph to see where people describe their solutions as using graphs). (Just don't post your answers to the questions tagged codegolf unless you've made an effort to write the shortest solution you can rather than the clearest, which is what you'd probably want to do when studying graph algorithms). Jun 3, 2013 at 9:48

1 Answer 1

11

Very good question, but very tough to answer. I highly doubt, that such a book exists, because graphs are just another formalism and whether you apply it to your problem or not is a matter of two things:

  1. Knowledge about its existence. People who do not know about graphs and the corresponding algorithms for some very strange reason never come up with graph-based solutions to their problems.

  2. Being the most suitable formalism for your problem.

As for 1. you are well on your way already. Point 2 is much harder due to the genericity of graphs. If you take it to the extreme, do remember that every list or array is nothing but a graph in disguise. Now you could consider looping through a linked list in order to find a certain element as a depth-first search on a directed acyclic graph, but there's really no point in it apart from the mental masturbation.

On the other hand, there are myriads of problems which naturally lend themselves to graph-based solutions. The more experience you have with graphs, the more you will see them wherever you go, but it takes even more experience to decide when the time is right to pull out that full-blown graph library, or even roll your own algorithm.

If you are looking for a problem that requires a graph-based solution, then my guess is you won't find one, as it all could be solved in a different way as well. But if you're looking for problems for which graph-based solutions are a good fit, then your best bet might be to look at an abstraction of the problem.

Abstraction is the one thing that brings out graph datastructures the best. Try to translate your problem domain into nodes and figure out what the meaning of an edge between these nodes would be. If you cannot do that easily, chances are you are better off without graphs. However, most of the times everything just falls into place naturally.

Here are a few examples and how abstraction leads you to the corresponding graph algorithms:

  • Buildsystem: you have a lot of projects/libraries which depend on each other. You must ensure that one is built before another, oh and of course, if possible, you want to build them in parallel. Now do the abstraction: library = node and edge = dependency and voila.. you have a graph. Next question: what structure does this graph have? is it directed or undirected? has to be directed, as you have a direct relation that one library needs to be built before the other. Is it acyclic? indeed, you cannot have cyclic dependencies, or you would not have a place to start your build - but you may have to account for your tool being able to stop on detecting cycles, because someone configured something wrong. Ops, cycle-detection algorithm.. should be in your toolbox. Next up: determine the execution order for builds, or in other words: find a traversal through your graph that visits nodes only after all nodes from incoming edges have been visited. Check your toolbox, as this is the topological sort algorithm. And so on, and so on...

  • Power net: You have a city/country and several power plants and places where you can redirect power and of course, everyone needs to be supplied. Nodes are the homes and power plants, edges are the power lines, and if you want to find the minimal length of power lines you need to build, it comes down to the minimal amount of edges required to connect all of your nodes together.. or in toolbox-speech: minimum spanning tree.

  • Piping system: You have an elaborate setup of pipes through which you can run water. At several points you have the option to open/close valves to allow the water to pass through your system in different ways. However, the pipes differ in diameter, so that the throughput varies and you wonder: how much water can we get pumped through this system at most (in a given unit of time)? Abstraction leads you to model the tap, sink, and valves as nodes and pipes as edges. Edge weights will be involved due to the diameters affecting the throughput and now you want to find quite literally the maximum flow. Luckily, the graph toolbox has algorithms for just that.

  • Routing wires on a chip (example proposed by @jk.) : When you have to do wiring, you have the limitation, that wires must not cross due to the electrical charges. Abstraction is straight-forward at first, because you have components and wires between them, hence, nodes and edges. The next step is to identify the problem in graph-based terms, which in this case means you have to layout the edges on a plane. Whether or not a graph can be drawn on a plane without intersecting the edges is again checkable via an algorithm from the graph toolbox - keyword: planar graphs.

As for the spoon-feeding book: This is actually not a good idea. Let me stress again, that graphs can be applied to almost every problem if you force your mind around it. A book that shows you problems and how they are solved with graph algorithms is pretty much useless, because you will have to deal with other problems in your daily work. All it comes down to is experience with this kind of abstraction, because you have to adapt everything to the current situation at hand.

2
  • 1
    Great reply! My problem is that how to start the approach. Arrays are also a very important data structure, right? But I never had to worry bout learning where to apply (virtually everywhere!) them since almost all coding examples involved it. Learning that was a natural process. For graphs, it is not being natural..That's why I was looking for some kind of spoon-feeding book. Where all problems are graph problems. Guess there's none. I will write one after I master it.. :) Jun 3, 2013 at 8:43
  • 1
    The major difference between arrays and graphs in terms of example code is that the latter can be implemented in a thousand ways, whereas arrays are usually a fixed part of the language already.
    – Frank
    Jun 3, 2013 at 9:58

Not the answer you're looking for? Browse other questions tagged or ask your own question.