| 1 | Graph Theory in Sage |
| 2 | ==================== |
| 3 | |
| 4 | First steps |
| 5 | ----------- |
| 6 | |
| 7 | A Graph is a set of vertices connected by edges |
| 8 | (see `Wikipedia <http://en.wikipedia.org/wiki/Graph_(mathematics)>`_ ) |
| 9 | |
| 10 | One can very easily create a graph in sage by typing :: |
| 11 | |
| 12 | sage: g=Graph() |
| 13 | |
| 14 | By typing the name of the Graph, one can get some basic information |
| 15 | about it:: |
| 16 | |
| 17 | sage: g |
| 18 | Graph on 0 vertices |
| 19 | |
| 20 | This graph is not very interesting as it is by default the empty graph.. But |
| 21 | Sage contains a large collection of predefined graph classes |
| 22 | that can be listed this way : |
| 23 | |
| 24 | * type in Sage : ``graphs.`` |
| 25 | ( do not press "Enter", and do not forget the final "." ) |
| 26 | * hit "tabulation" two times in a row |
| 27 | |
| 28 | You will see the list of methods defined in the class ``graphs``, |
| 29 | all of which generate graphs you can play with ! |
| 30 | |
| 31 | If you want to see what they look like, begin this way :: |
| 32 | |
| 33 | sage: g=graphs.PetersenGraph() |
| 34 | sage: g.plot() |
| 35 | |
| 36 | or:: |
| 37 | |
| 38 | sage: g=graphs.ChvatalGraph() |
| 39 | sage: g.plot() |
| 40 | |
| 41 | If you are curious about what these graphs are, for example |
| 42 | if you wonder what ``RandomGNP`` actually is, you but have to type :: |
| 43 | |
| 44 | sage: graphs.RandomGNP? |
| 45 | |
| 46 | Once you have defined the graph you want, you can begin |
| 47 | to work on it by using thealmost 200 functions on graphs |
| 48 | in the Sage library !If your graph is named ``g``, you can |
| 49 | list these functions as previously this way : |
| 50 | |
| 51 | * type in Sage : ``g.`` |
| 52 | ( do not press "Enter", and do not forget the final "." ) |
| 53 | * hit "tabulation" two times in a row |
| 54 | |
| 55 | As usual, you can get some information about what these |
| 56 | functions do by typing( if you want to know about the ``diameter()`` |
| 57 | method ):: |
| 58 | |
| 59 | sage: g.diameter? |
| 60 | |
| 61 | If you have defined a graph ``g`` having several connected |
| 62 | components ( = which is notconnected... Type ``g.is_connected()`` |
| 63 | to know whether your graph is ), you canprint each one of |
| 64 | its connected components with only two lines : |
| 65 | |
| 66 | ( if you do not have such a graph G, here is one |
| 67 | for free : ``g=graphs.RandomGNP(30,.05)`` ):: |
| 68 | |
| 69 | sage: for component in g.connected_components(): |
| 70 | ... g.subgraph(component).plot() |
| 71 | |
| 72 | |
| 73 | Basic notions |
| 74 | ------------- |
| 75 | |
| 76 | The first elements you want to find in a graph are its vertices |
| 77 | and its edges. The vertices of a graph ``g`` are returned |
| 78 | by ``g.vertices()`` and its edges are returned by ``g.edges()``. |
| 79 | In Sage, the edges of a graph are represented as tuples ``(u,v,l)`` |
| 80 | where ``u`` and ``v`` are vertices, and ``l`` a label attached |
| 81 | to the edge ( this label can be of any type, even though |
| 82 | several functions expect it to be a real value ). |
| 83 | |
| 84 | The methods ``g.order()`` and ``g.size()`` respectively return the number |
| 85 | of vertices and the number of edges. |
| 86 | |
| 87 | At any moment, you can display the adjacency matrix of you graph |
| 88 | by using the method ``g.am()`` and plot the graph with ``g.plot()``. |
| 89 | |
| 90 | What interesting things can you do with Graphs in Sage ? |
| 91 | --------------------------------------------------------- |
| 92 | |
| 93 | Computing matching |
| 94 | ^^^^^^^^^^^^^^^^^^^ |
| 95 | |
| 96 | Maximum Matching a polynomial problem in Graph Theory, and |
| 97 | have a thousand of different applications. This, just to |
| 98 | mean that the following list of examples is not (yet?) exhaustive. |
| 99 | |
| 100 | For more information on matching : |
| 101 | `Matching <http://en.wikipedia.org/wiki/Matching>`_ |
| 102 | |
| 103 | Small company |
| 104 | """""""""""""""" |
| 105 | |
| 106 | Let us say that you are in charge of a small company with 4 employees |
| 107 | `\{e_1,e_2,e_3,e_4\}` and have several tasks `\{t_1,t_2,t_3,t_4\}` |
| 108 | to give them. Unfortunately, no worker is skilled enough to do all of them : |
| 109 | |
| 110 | * `e_1` can do `t_1, t_3, t_4` |
| 111 | * `e_2` can do `t_1, t_3, t_5` |
| 112 | * `e_3` can do `t_1, t_2, t_3, t_4, t_5` |
| 113 | * `e_4` can do `t_4, t_5` |
| 114 | * `e_5` can do `t_2, t_4` |
| 115 | |
| 116 | |
| 117 | You are lucky if you do not know how to solve this problem manually, |
| 118 | because this is typically an application of matching in graphs |
| 119 | (and if you have found the solution, I assure you it gets harder |
| 120 | when you have more of them) ! |
| 121 | |
| 122 | To solve this problem, you but have to create the graph corresponding |
| 123 | to the information above, and solve the matching problem ::: |
| 124 | |
| 125 | sage: g=Graph({"e0":['t1', 't3', 't4'],"e1":['t1', 't3', |
| 126 | 't5'],"e2":['t1', 't2', 't3', 't4', 't5'], |
| 127 | "e3":['t4', 't5'],"e4":['t2', 't4']}) |
| 128 | sage: print g.max_matching() |
| 129 | [('e2', 't4', None), ('e3', 't5', None), ('e0', 't3', None), |
| 130 | ('e1', 't1', None), ('e4', 't2', None)] |
| 131 | |
| 132 | If you prefer to "see" the result, you can also type :: |
| 133 | |
| 134 | sage: g.plot(edge_colors={"red":g.max_matching()}) |
| 135 | |
| 136 | Sage 1 : Pain 0 |
| 137 | |
| 138 | Summer camp |
| 139 | """""""""""" |
| 140 | |
| 141 | You know have under your responsibility 5 rooms and 10 children |
| 142 | `\{c_0,...,c_9\}`. You need to decide those of them who will |
| 143 | sleep in the same rooms, but you do not want two of them to be |
| 144 | together if they do not like each other or if you expect trouble |
| 145 | from the pair... Here are the constraints : |
| 146 | |
| 147 | * `c_0` can sleep with `c_5` |
| 148 | * `c_1` can sleep with `c_5, c_8` |
| 149 | * `c_2` can sleep with `c_3, c_8, c_9` |
| 150 | * `c_3` can sleep with `c_9` |
| 151 | * `c_4` can sleep with `c_9` |
| 152 | * `c_5` can sleep with `c_9` |
| 153 | * `c_6` can sleep with `c_7, c_9` |
| 154 | * `c_7` can sleep with `c_9` |
| 155 | |
| 156 | As previously, this defines a graph whose adjacency matrix has |
| 157 | just been defined ! You now but have to create it in Sage, and |
| 158 | look for a maximum matching...:: |
| 159 | |
| 160 | sage: g=Graph({'c0':['c5'],'c1':['c5', 'c8'],'c2':['c3', |
| 161 | 'c8', 'c9'],'c3':['c9'],'c4':['c9'],'c5':['c9'], |
| 162 | 'c6':['c7', 'c9'],'c7':['c9']}) |
| 163 | sage: print g.max_matching() |
| 164 | [('c0', 'c5', None), ('c6', 'c7', None), ('c2', 'c3', None), |
| 165 | ('c4', 'c9', None), ('c1', 'c8', None)] |
| 166 | |
| 167 | If you prefer to "see" the result, you can also type :: |
| 168 | |
| 169 | sage: g.plot(edge_colors={"red":g.max_matching()}) |
| 170 | |
| 171 | And this is another problem Sage solved for you ! |
| 172 | |
| 173 | |
| 174 | |
| 175 | Vertex coloring |
| 176 | ^^^^^^^^^^^^^^^ |
| 177 | |
| 178 | You are in front of a map of Western Europe that you would like |
| 179 | to color. Obviously, you can not color both France and Italy |
| 180 | with the same color as they have a common boundary, and you would |
| 181 | not like to mix the two.. Actually, you want to color : |
| 182 | |
| 183 | * Austria |
| 184 | * Belgium |
| 185 | * France |
| 186 | * Germany |
| 187 | * Ireland |
| 188 | * Italy |
| 189 | * Luxembourg |
| 190 | * Netherlands |
| 191 | * Portugal |
| 192 | * Spain |
| 193 | * Swiss |
| 194 | * United Kingdom |
| 195 | |
| 196 | And would like to know how many colors you need, and how to color |
| 197 | them. Well, as Sage was specially built to help you solve this |
| 198 | kind of tremendously exciting questions, here is the way to solve them : |
| 199 | |
| 200 | * First, create the graph of Western Europe in Sage |
| 201 | * Use the ``vertex_coloring()`` method |
| 202 | |
| 203 | In Sage :: |
| 204 | |
| 205 | sage: g=Graph({"France":["Italy","Spain","Swiss","Luxembourg","Belgium", |
| 206 | "Germany","Austria"], |
| 207 | "Spain":["Portugal"], |
| 208 | "Italy":["Swiss","Austria"], |
| 209 | "Swiss":["Germany"], |
| 210 | "Germany":["Luxembourg","Belgium","Netherlands"], |
| 211 | "Belgium":["Luxembourg","Netherlands"], |
| 212 | "United Kingdom":["Ireland"]}) |
| 213 | sage: g.vertex_coloring() |
| 214 | [['France', 'Portugal', 'Netherlands', 'Ireland'], |
| 215 | ['Germany', 'Spain', 'Austria', 'United Kingdom'], |
| 216 | ['Belgium', 'Swiss'], |
| 217 | ['Luxembourg', 'Italy']] |
| 218 | |
| 219 | You can now look for your pens. 4 of them :-) |
| 220 | |
| 221 | For more information on graph |
| 222 | coloring : `Graph coloring <http://en.wikipedia.org/wiki/Graph_coloring>`_ |
| 223 | |
| 224 | For more informations on why it could not have required more pens : |
| 225 | `Four color theorem <http://en.wikipedia.org/wiki/Four_color_theorem>`_ |
| 226 | |
| 227 | Edge coloring |
| 228 | ^^^^^^^^^^^^^^ |
| 229 | |
| 230 | You are organizing a soccer tournament ( or table tennis if you |
| 231 | do not like soccer, but this is not really relevant ), with 10 |
| 232 | different teams that are to play against each other. Besides, |
| 233 | the teams will play every Wednesday and will not be able to play |
| 234 | two times the same day. How can you schedule them in such a way |
| 235 | that the tournament will not last for too long ? |
| 236 | |
| 237 | This is an easy application of the Edge Coloring problem on a |
| 238 | complete graph. If you number your teams as `1,...,10`, here |
| 239 | is how you can obtain your scheduling :: |
| 240 | |
| 241 | sage: g=graphs.CompleteGraph(10) |
| 242 | sage: g.edge_coloring() |
| 243 | [[(2, 9, None), (3, 7, None), (5, 6, None), (0, 8, None), (1, 4, None)], |
| 244 | [(3, 5, None), (1, 2, None), (7, 9, None), (0, 6, None), (4, 8, None)], |
| 245 | [(5, 7, None), (0, 3, None), (1, 6, None), (4, 9, None), (2, 8, None)], |
| 246 | [(1, 7, None), (0, 9, None), (4, 5, None), (2, 3, None), (6, 8, None)], |
| 247 | [(2, 6, None), (0, 1, None), (4, 7, None), (5, 8, None), (3, 9, None)], |
| 248 | [(7, 8, None), (3, 4, None), (1, 5, None), (6, 9, None), (0, 2, None)], |
| 249 | [(5, 9, None), (0, 4, None), (1, 8, None), (3, 6, None), (2, 7, None)], |
| 250 | [(0, 5, None), (1, 3, None), (6, 7, None), (2, 4, None), (8, 9, None)], |
| 251 | [(3, 8, None), (4, 6, None), (1, 9, None), (0, 7, None), (2, 5, None)]] |
| 252 | |
| 253 | And each line you see is the set of games being played on a particular |
| 254 | day. If you prefer to plot the result, try :: |
| 255 | |
| 256 | sage: g.plot(edge_colors=g.edge_coloring(hex_colors=True)) |
| 257 | |
| 258 | Pretty, isn´t it ? Each day has its own color. |
| 259 | |
| 260 | |
| 261 | |
| 262 | Two links for more information : |
| 263 | * `About edge coloring <http://en.wikipedia.org/wiki/Edge_coloring>`_ |
| 264 | * `About the scheduling of tournaments <http://en.wikipedia.org/wiki/Round-robin>`_ |
| 265 | |
| 266 | |
| 267 | |