Graph Theory Package For Giac/Xcas Graphtheory User Manual

User Manual:

Open the PDF directly: View PDF PDF.
Page Count: 87

DownloadGraph Theory Package For Giac/Xcas Graphtheory-user Manual
Open PDF In BrowserView PDF
Graph theory
package for
Giac/Xcas
Reference manual

June 2018
draft

Table of contents
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.1. Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.2. Notations used in this manual . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2. Constructing graphs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.1. General graphs . . . . . . . . . . . . . . . . . . . . . . . . .
2.1.1. Creating undirected graphs . . . . . . . . . . . . . .
2.1.2. Creating directed graphs . . . . . . . . . . . . . . .
2.1.3. Creating vertices . . . . . . . . . . . . . . . . . . . .
2.1.4. Creating edges and arcs . . . . . . . . . . . . . . . .
2.1.5. Creating paths and trails . . . . . . . . . . . . . . .
2.1.6. Specifying adjacency or weight matrix . . . . . . .
2.2. Promoting to directed and undirected graphs . . . . . .
2.2.1. Converting edges to pairs of arcs . . . . . . . . . .
2.2.2. Assigning weight matrix to an unweighted graph
2.3. Cycle and path graphs . . . . . . . . . . . . . . . . . . . .
2.3.1. Cycle graphs . . . . . . . . . . . . . . . . . . . . . . .
2.3.2. Path graphs . . . . . . . . . . . . . . . . . . . . . . . .
2.3.3. Trails of edges . . . . . . . . . . . . . . . . . . . . . .
2.4. Complete graphs . . . . . . . . . . . . . . . . . . . . . . . .
2.4.1. Complete graphs with multiple vertex partitions
2.4.2. Complete trees . . . . . . . . . . . . . . . . . . . . . .
2.5. Sequence graphs . . . . . . . . . . . . . . . . . . . . . . . .
2.5.1. Creating graphs from degree sequences . . . . . .
2.5.2. Validating graphic sequences . . . . . . . . . . . . .
2.6. Intersection graphs . . . . . . . . . . . . . . . . . . . . . .
2.6.1. Interval graphs . . . . . . . . . . . . . . . . . . . . . .
2.6.2. Kneser graphs . . . . . . . . . . . . . . . . . . . . . .
2.7. Special graphs . . . . . . . . . . . . . . . . . . . . . . . . .
2.7.1. Hypercube graphs . . . . . . . . . . . . . . . . . . . .
2.7.2. Star graphs . . . . . . . . . . . . . . . . . . . . . . . .
2.7.3. Wheel graphs . . . . . . . . . . . . . . . . . . . . . . .
2.7.4. Web graphs . . . . . . . . . . . . . . . . . . . . . . . .
2.7.5. Prism graphs . . . . . . . . . . . . . . . . . . . . . . .
2.7.6. Antiprism graphs . . . . . . . . . . . . . . . . . . . .
2.7.7. Grid graphs . . . . . . . . . . . . . . . . . . . . . . . .
2.7.8. Sierpi«ski graphs . . . . . . . . . . . . . . . . . . . .
2.7.9. Generalized Petersen graphs . . . . . . . . . . . . .
2.7.10. LCF graphs . . . . . . . . . . . . . . . . . . . . . . .
2.8. Isomorphic copies of graphs . . . . . . . . . . . . . . . . .
2.8.1. Creating an isomorphic copy of a graph . . . . . .
2.8.2. Permuting graph vertices . . . . . . . . . . . . . . .
2.8.3. Relabeling graph vertices . . . . . . . . . . . . . . .
2.9. Subgraphs . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.9.1. Extracting subgraphs . . . . . . . . . . . . . . . . . .
2.9.2. Induced subgraphs . . . . . . . . . . . . . . . . . . .
2.9.3. Underlying graphs . . . . . . . . . . . . . . . . . . .
2.10. Operations on graphs . . . . . . . . . . . . . . . . . . . .
2.10.1. Graph complement . . . . . . . . . . . . . . . . . .
3

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

. . 9
. . 9
. 10
. 10
. 10
. 11
. 11
. 12
. 12
. 12
. 12
. 12
. 13
. 13
. 13
. 13
. 14
. 15
. 15
. 15
. 15
. 15
. 15
. 16
. 16
. 17
. 17
. 17
. 18
. 18
. 18
. 20
. 20
. 21
. 22
. 22
. 22
. 22
. 23
. 23
. 23
. 24
. 24
. 24

4

Table of contents

2.10.2. Seidel switching . . . . . .
2.10.3. Transposing graphs . . . .
2.10.4. Union of graphs . . . . . .
2.10.5. Disjoint union of graphs .
2.10.6. Joining two graphs . . . .
2.10.7. Power graphs . . . . . . . .
2.10.8. Graph products . . . . . .
2.10.9. Transitive closure graph .
2.10.10. Line graph . . . . . . . . .
2.10.11. Plane dual graph . . . . .
2.11. Random graphs . . . . . . . . . .
2.11.1. Random general graphs .
2.11.2. Random bipartite graphs
2.11.3. Random trees . . . . . . . .
2.11.4. Random planar graphs . .
2.11.5. Random regular graphs .
2.11.6. Random tournaments . . .
2.11.7. Random ow networks . .
2.11.8. Randomizing edge weights

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

24
25
25
26
26
26
27
28
30
30
31
31
32
32
33
34
35
35
35

3. Modifying graphs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

37

3.1. Modifying vertices of a graph . . . . . . . . .
3.1.1. Adding and removing single vertices .
3.2. Modifying edges of a graph . . . . . . . . . .
3.2.1. Adding and removing single edges . .
3.2.2. Accessing and modifying edge weights
3.2.3. Contracting edges . . . . . . . . . . . . .
3.2.4. Subdividing edges . . . . . . . . . . . . .
3.3. Using attributes . . . . . . . . . . . . . . . . .
3.3.1. Graph attributes . . . . . . . . . . . . .
3.3.2. Vertex attributes . . . . . . . . . . . . .
3.3.3. Edge attributes . . . . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.

37
37
37
37
38
38
39
40
40
40
41

. .. .. ... .. .. .. .. .. .. .. ... .. .. .. .. .. .. ...

43

4. Import and export

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

4.1. Importing graphs . . . . . . . . . . . .
4.1.1. Loading graphs from dot les . .
4.1.2. The dot le format overview . .
4.2. Exporting graphs . . . . . . . . . . . .
4.2.1. Saving graphs in dot format . .
4.2.2. Saving graph drawings in LATEX
5. Graph properties

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

47

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.. .. .. ... .. .. .. .. .. .. .. ... .. .. .. .. .. .. ...
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

43
43
43
44
44
44

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.

5.1. Basic properties . . . . . . . . .
5.1.1. Listing vertices and edges
5.1.2. Vertex degrees . . . . . . .
5.1.3. Vertex adjacency . . . . .
5.1.4. Edge incidence . . . . . . .
5.2. Algebraic properties . . . . . . .
5.2.1. Adjacency matrix . . . . .
5.2.2. Weight matrix . . . . . . .
5.2.3. Incidence matrix . . . . . .
5.2.4. Characteristic polynomial
5.2.5. Graph spectrum . . . . . .
5.2.6. Seidel spectrum . . . . . .
5.2.7. Integer graphs . . . . . . .

.. .. .
.. .. .
.. .. .
.. .. .
.. .. .
format

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

47
47
47
48
49
50
50
51
51
52
53
53
54

Table of contents

5

5.3. Connectivity . . . . . . . . . . . . . . . . . . . . . .
5.3.1. Vertex connectivity . . . . . . . . . . . . . . .
5.3.2. Connected and biconnected components .
5.3.3. Graph rank . . . . . . . . . . . . . . . . . . . .
5.3.4. Articulation points . . . . . . . . . . . . . . .
5.3.5. Strongly connected components . . . . . . .
5.3.6. Edge connectivity . . . . . . . . . . . . . . . .
5.4. Trees . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.4.1. Tree graphs . . . . . . . . . . . . . . . . . . . .
5.4.2. Forest graphs . . . . . . . . . . . . . . . . . . .
5.4.3. Height of a tree . . . . . . . . . . . . . . . . .
5.4.4. Lowest common ancestor of a pair of nodes
5.5. Distance . . . . . . . . . . . . . . . . . . . . . . . . .
5.5.1. Vertex distance . . . . . . . . . . . . . . . . .
5.5.2. All-pairs vertex distance . . . . . . . . . . . .
5.5.3. Diameter of a graph . . . . . . . . . . . . . .
5.5.4. Girth of a graph . . . . . . . . . . . . . . . . .
5.6. Acyclic graphs . . . . . . . . . . . . . . . . . . . . .
5.6.1. Checking if a graph is acyclic . . . . . . . .
5.6.2. Topological sorting . . . . . . . . . . . . . . .
5.6.3. st ordering . . . . . . . . . . . . . . . . . . . .
5.7. Vertex matching . . . . . . . . . . . . . . . . . . . .
5.7.1. Maximum matching . . . . . . . . . . . . . .
5.7.2. Maximum matching in bipartite graphs . .
5.8. Cliques . . . . . . . . . . . . . . . . . . . . . . . . . .
5.8.1. Clique graphs . . . . . . . . . . . . . . . . . .
5.8.2. Triangle-free graphs . . . . . . . . . . . . . .
5.8.3. Maximal cliques . . . . . . . . . . . . . . . . .
5.8.4. Maximum clique . . . . . . . . . . . . . . . . .
5.8.5. Minimum clique cover . . . . . . . . . . . . .
5.9. Vertex coloring . . . . . . . . . . . . . . . . . . . . .
5.9.1. Greedy coloring . . . . . . . . . . . . . . . . .
5.9.2. Minimal coloring . . . . . . . . . . . . . . . .
5.9.3. Chromatic number . . . . . . . . . . . . . . .
5.9.4. k-coloring . . . . . . . . . . . . . . . . . . . . .
5.10. Edge coloring . . . . . . . . . . . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

54
54
55
56
56
56
57
57
57
58
58
58
59
59
59
59
59
60
60
60
61
61
61
62
63
63
63
63
64
65
66
66
66
68
69
70

6. Traversing graphs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

71

6.1. Walks and tours . . . . . . . . . . . . . . . .
6.1.1. Eulerian graphs . . . . . . . . . . . . .
6.1.2. Hamiltonian graphs . . . . . . . . . . .
6.2. Optimal routing . . . . . . . . . . . . . . . .
6.2.1. Shortest paths in unweighted graphs
6.2.2. Cheapest paths in weighted graphs .
6.2.3. Traveling salesman problem . . . . .
6.3. Spanning trees . . . . . . . . . . . . . . . . .
6.3.1. Constructing a spanning tree . . . . .
6.3.2. Minimal spanning tree . . . . . . . . .
6.3.3. Counting all spanning trees . . . . . .

.
.
.
.
.
.
.
.
.
.
.

71
71
71
71
71
72
72
72
72
72
72

7. Visualizing graphs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

75

7.1. Drawing graphs by using various methods
7.1.1. Overview . . . . . . . . . . . . . . . . .
7.1.2. Drawing disconnected graphs . . . .
7.1.3. Spring method . . . . . . . . . . . . . .
7.1.4. Drawing trees . . . . . . . . . . . . . .

75
75
75
76
78

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

6

7.1.5. Drawing planar graphs . . . .
7.1.6. Circular graph drawings . . .
7.2. Custom vertex positions . . . . . .
7.2.1. Setting vertex positions . . .
7.2.2. Generating vertex positions .
7.3. Highlighting parts of a graph . . .
7.3.1. Highlighting vertices . . . . .
7.3.2. Highlighting edges and trails
7.3.3. Highlighting subgraphs . . .

Table of contents

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

79
80
81
81
81
82
82
83
84

Bibliography . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

85

Command Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

87

Chapter 1
Introduction
1.1. Overview
This document contains an overview of the graph theory commands built in the Giac/Xcas software, including the syntax, the detailed description and practical examples for each command.

1.2. Notations used in this manual

7

Chapter 2
Constructing graphs
2.1. General graphs
The commands graph and digraph are used for constructing general graphs.

2.1.1. Creating undirected graphs
The command graph accepts between one and three mandatory arguments, each of them being
one of the following structural elements of the resulting graph:
¡

the number or list of vertices (a vertex may be any atomic object, such as an integer, a
symbol or a string); it must be the rst argument if used,

¡

the set of edges (each edge is a list containing two vertices), a permutation, a trail of edges
or a sequence of trails; it can be either the rst or the second argument if used,

¡

the adjacency or weight matrix.

Additionally, some of the following options may be appended to the sequence of arguments:


directed = true or false,



weighted = true or false,



color = an integer or a list of integers representing color(s) of the vertices,



coordinates = a list of vertex 2D or 3D coordinates.

The graph command may also be called by passing a string, representing the name of a special
graph, as its only argument. In that case the corresponding graph will be constructed and returned.
The supported graphs and their names are listed below.
1. Clebsch graph: clebsch
2. Coxeter graph: coxeter
3. Desargues graph: desargues
4. Dodecahedral graph: dodecahedron
5. Dürer graph: durer
6. Dyck graph: dyck
7. Grinberg graph: grinberg
8. Grotzsch graph: grotzsch
9. Harries graph: harries
10. HarriesWong graph: harries-wong
11. Heawood graph: heawood
9

10

Constructing graphs

12. Herschel graph: herschel
13. Icosahedral graph: icosahedron
14. Levi graph: levi
15. Ljubljana graph: ljubljana
16. McGee graph: mcgee
17. MöbiusKantor graph: mobius-kantor
18. Nauru graph: nauru
19. Octahedral graph: octahedron
20. Pappus graph: pappus
21. Petersen graph: petersen
22. Robertson graph: robertson
23. Truncated icosahedral graph: soccerball
24. Shrikhande graph: shrikhande
25. Tetrahedral graph: tehtrahedron

2.1.2. Creating directed graphs
The digraph command is used for creating directed graphs, although it is also possible with the
graph command by specifying the option directed=true. Actually, calling digraph is the same as
calling graph with that option appended to the sequence of arguments. However, creating special
graphs is not supported by digraph since they are all undirected. Edges in directed graphs are
called arcs. Edges and arcs are dierent structures: an edge is represented by a two-element set
containing its endpoints, while an arc is represented by the ordered pairs of its endpoints.
The following series of examples demonstrates the various possibilities when using graph and
digraph commands.

2.1.3. Creating vertices
A graph consisting only of vertices and no edges can be created simply by providing the number
of vertices or the list of vertex labels.
> graph(5)
an undirected unweighted graph with 5 vertices and 0 edges
> graph([a,b,c])
an undirected unweighted graph with 3 vertices and 0 edges

2.1.4. Creating edges and arcs
Edges/arcs must be specied inside a set so that it can be distinguished from a (adjacency or
weight) matrix. If only a set of edges/arcs is specied, the vertices needed to establish these will
be created automatically. Note that, when constructing a directed graph, the order of the vertices
in an arc matters; in undirected graphs it is not meaningful.

2.1 General graphs

11

> graph(%{[a,b],[b,c],[a,c]%})
an undirected unweighted graph with 3 vertices and 3 edges
Edge weights may also be specied.
> graph(%{[[a,b],2],[[b,c],2.3],[[c,a],3/2]%})
an undirected weighted graph with 3 vertices and 3 edges
If the graph contains isolated vertices (not connected to any other vertex) or a particular order
of vertices is desired, the list of vertices has to be specied rst.
> graph([d,b,c,a],%{[a,b],[b,c],[a,c]%})
an undirected unweighted graph with 4 vertices and 3 edges

2.1.5. Creating paths and trails
A directed graph can also be created from a list of n vertices and a permutation of order n.
The resulting graph consists of a single directed path with the vertices ordered according to the
permutation.
> graph([a,b,c,d],[1,2,3,0])
a directed unweighted graph with 4 vertices and 3 arcs
Alternatively, one may specify edges as a trail.
> digraph([a,b,c,d],trail(b,c,d,a))
a directed unweighted graph with 4 vertices and 3 arcs
Using trails is also possible when creating undirected graphs. Also, some vertices in a trail may
be repeated, which is not allowed in a path.
> graph([a,b,c,d],trail(b,c,d,a,c))
an undirected unweighted graph with 4 vertices and 4 edges
There is also the possibility of specifying several trails in a sequence, which is useful for designing
more complex graphs.
> graph(trail(1,2,3,4,2),trail(3,5,6,7,5,4))
an undirected unweighted graph with 7 vertices and 9 edges

2.1.6. Specifying adjacency or weight matrix
A graph can be created from a single square matrix A = [aij ]n of order n. If it contains only ones
and zeros and has zeros on its diagonal, it is assumed to be the adjacency matrix for the desired
graph. Otherwise, if an element outside the set f0; 1g is encountered, it is assumed that the matrix
of edge weights is passed as input, causing the resulting graph to be weighted accordingly. In each
case, exactly n vertices will be created and i-th and j-th vertex will be connected i aij =
/ 0. If the
matrix is symmetric, the resulting graph will be undirected, otherwise it will be directed.
> graph([[0,1,1,0],[1,0,0,1],[1,0,0,0],[0,1,0,0]])
an undirected unweighted graph with 4 vertices and 3 edges
> graph([[0,1.0,2.3,0],[4,0,0,3.1],[0,0,0,0],[0,0,0,0]])
a directed weighted graph with 4 vertices and 4 arcs

12

Constructing graphs

List of vertex labels can be specied before the matrix.
> graph([a,b,c,d],[[0,1,1,0],[1,0,0,1],[1,0,0,0],[0,1,0,0]])
an undirected unweighted graph with 4 vertices and 3 edges
When creating a weighted graph, one can rst specify the list of n vertices and the set of edges,
followed by a square matrix A of order n. Then for every edge fi; j g or arc (i; j) the element
aij of A is assigned as its weight. Other elements of A are ignored.
> digraph([a,b,c],%{[a,b],[b,c],[a,c]%}, [[0,1,2],[3,0,4],[5,6,0]])
a directed weighted graph with 3 vertices and 3 arcs
When a special graph is desired, one just needs to pass its name to the graph command. An
undirected unweighted graph will be returned.
> graph("petersen")
an undirected unweighted graph with 10 vertices and 15 edges

2.2. Promoting to directed and undirected graphs
2.2.1. Converting edges to pairs of arcs
To promote an existing undirected graph to a directed one or an unweighted graph to a weighted
one, use the commands make_directed and make_weighted, respectively.
The command make_directed is called with one or two arguments, an undirected graph G(V ;
E) and optionally a square matrix of order jV j. Every edge fi; j g 2 E is replaced with the pair
of arcs (i; j) and (j ; i). If matrix A is specied, aij and a ji are assigned as weights of these arcs,
respectively. Thus a directed (and possibly weighted) graph is created and returned.
> make_directed(cycle_graph(4))
C4: a directed unweighted graph with 4 vertices and 8 arcs
> make_directed(cycle_graph(4), [[0,0,0,1],[2,0,1,3],[0,1,0,4],[5,0,4,0]])
C4: a directed weighted graph with 4 vertices and 8 arcs

2.2.2. Assigning weight matrix to an unweighted graph
The command make_weighted accepts one or two arguments, an unweighted graph G(V ; E) and
optionally a square matrix A of order jV j. If the matrix specication is omitted, a square matrix
of ones is assumed. Then a copy of G is returned where each edge/arc (i; j) 2 E gets aij assigned
as its weight. If G is an undirected graph, it is assumed that A is symmetric.
> make_weighted(graph(%{[1,2],[2,3],[3,1]%}), [[0,2,3],[2,0,1],[3,1,0]])
an undirected weighted graph with 3 vertices and 3 edges

2.3. Cycle and path graphs
2.3.1. Cycle graphs
The command cycle_graph is used for constructing a cycle graph of arbitrary order.

2.4 Complete graphs

13

cycle_graph accepts a positive integer n or a list of distinct vertices as its only argument and
returns the graph consisting of a single cycle through the specied vertices in the given order. If n
is specied it is assumed to be the desired number of vertices, in which case they will be created
and labeled with the rst n integers (starting from 0 in Xcas mode and from 1 in Maple mode).
The resulting graph will be given the name Cn, for example C4 for n = 4.
> C5:=cycle_graph(5)
C5: an undirected unweighted graph with 5 vertices and 5 edges
> draw_graph(C5)
0

4

1

3

2

> cycle_graph(["a","b","c","d","e"])
C5: an undirected unweighted graph with 5 vertices and 5 edges

2.3.2. Path graphs
The command path_graph is used for constructing a path graph of arbitrary length.
path_graph accepts a positive integer n or a list of distinct vertices as its only argument and
returns a graph consisting of a single path through the specied vertices in the given order. If n
is specied it is assumed to be the desired number of vertices, in which case they will be created
and labeled with the rst n integers (starting from 0 in Xcas mode resp. from 1 in Maple mode).
Note that a path cannot intersect itself. Paths that are allowed to cross themselves are called trails
(see the command trail).
> path_graph(5)
an undirected unweighted graph with 5 vertices and 4 edges
> path_graph(["a","b","c","d","e"])
an undirected unweighted graph with 5 vertices and 4 edges

2.3.3. Trails of edges
If the dummy command trail is called with a sequence of vertices as arguments, it returns the
symbolic expression representing the trail of edges through the specied vertices. The resulting
symbolic object is recognizable by graph and digraph commands. Note that a trail may cross
itself (some vertices may be repeated in the given sequence).
> T:=trail(1,2,3,4,2):; graph(T)
Done; an undirected unweighted graph with 4 vertices and 4 edges

2.4. Complete graphs
2.4.1. Complete graphs with multiple vertex partitions
The command complete_graph is used for construction of complete (multipartite) graphs.

14

Constructing graphs

If complete_graph is called with a single argument, a positive integer n or a list of distinct vertices,
it returns the complete graph with the specied vertices. If integer n is specied, it is assumed that
it is the desired number of vertices and they will be created and labeled with the rst n integers
(starting from 0 in Xcas mode and from 1 in Maple mode).
If a sequence of positive integers n1; n2; :::; nk is passed as argument, complete_graph returns the
complete multipartite graph with partitions of size n1; n2; :::; nk.
> K5:=complete_graph(5)
an undirected unweighted graph with 5 vertices and 10 edges
> draw_graph(K5)
0

4

1

3

2

> K3:=complete_graph([a,b,c])
an undirected unweighted graph with 3 vertices and 3 edges
> edges(K3)
f[a; b]; [a; c]; [b; c]g
> K33:=complete_graph(3,3)
an undirected unweighted graph with 6 vertices and 9 edges
> draw_graph(K33)
0

3

1

4

2

5

2.4.2. Complete trees
To construct the complete binary tree of depth n, use the command complete_binary_tree which
accepts n (a positive integer) as its only argument.
> complete_binary_tree(2)
an undirected unweighted graph with 7 vertices and 6 edges
To construct the complete k-ary tree of the specied depth use the command complete_kary_tree.
complete_kary_tree accepts k and n (positive integers) as its arguments and returns the complete
k-ary tree of depth n. For example, to get a ternary tree with two levels, input:
> complete_kary_tree(3,2)
an undirected unweighted graph with 13 vertices and 12 edges

2.6 Intersection graphs

15

2.5. Sequence graphs
2.5.1. Creating graphs from degree sequences
The command sequence_graph is used for constructing the graph from its degree sequence.
sequence_graph accepts a list L of positive integers as its only argument and, if L represents a
graphic sequence, the corresponding graph G with jLj vertices is returned. If the argument is not
a graphic sequence, an error is returned.
> sequence_graph([3,2,4,2,3,4,5,7])
an undirected unweighted graph with 8 vertices and 15 edges
The graph G is constructed in O(jLj2 log jLj) time by using the algorithm of Havel and Hakimi.

2.5.2. Validating graphic sequences
The command is_graphic_sequence is used to check whether a list of integers represents the
degree sequence of some graph or not.
is_graphic_sequence accepts a list L of positive integers as its only argument and returns true if
there exists a graph G(V ; E) with degree sequence fdeg v: v 2 V g equal to L and false otherwise.
The algorithm, which has the complexity O(jLj2), is based on the theorem of Erd®s and Gallai.
> is_graphic_sequence([3,2,4,2,3,4,5,7])
true

2.6. Intersection graphs
2.6.1. Interval graphs
The command interval_graph is used for construction of interval graphs.
interval_graph accepts a sequence or list of real-line intervals as its argument and returns an
undirected unweighted graph with these intervals as vertices (the string representations of the
intervals are used as labels), each two of them being connected with an edge if and only if the
corresponding intervals intersect.
> G:=interval_graph(0..8,1..pi,exp(1)..20,7..18,11..14,17..24,23..25)
an undirected unweighted graph with 7 vertices and 10 edges
> draw_graph(G)

2.6.2. Kneser graphs
The commands kneser_graph and odd_graph are used for construction of Kneser graphs.

16

Constructing graphs

kneser_graph accepts two positive integers n  20 and k as its arguments and returns the Kneser
graph K(n; k). The latter is obtained by setting all k-subsets of a set of n elements as vertices
and connecting each two of them if and only if the corresponding sets are disjoint. Therefore each
Kneser graph is the complement of a certain intersection graph.
Kneser graphs can get exceedingly complex even
for relatively small values of n and k. Note that
 
the number of vertices in K(n; k) is equal to nk .
> kneser_graph(5,2)
an undirected unweighted graph with 10 vertices and 15 edges
> G:=kneser_graph(8,1)
an undirected unweighted graph with 8 vertices and 28 edges
> draw_graph(G,spring,labels=false)

The command odd_graph is used for creating so-called odd graphs, which are Kneser graphs with
parameters n = 2 d + 1 and k = d for d > 1.
odd_graph accepts a positive integer d  8 as its only argument and returns d-th odd graph
K(2 d + 1; d). Note that the odd graphs with d > 8 will not be constructed as they are too big to
handle.
> odd_graph(3)
an undirected unweighted graph with 10 vertices and 15 edges

2.7. Special graphs
2.7.1. Hypercube graphs
The command hypercube_graph is used for creating hypercube graphs.
hypercube_graph accepts a positive integer n as its only argument and returns the hypercube
graph of dimension n on 2n vertices. The vertex labels are strings of binary digits of length n.
Two vertices are joined by an edge if and only if their labels dier in exactly one character. The
hypercube graph for n = 2 is a square and for n = 3 it is a cube.
> H:=hypercube_graph(3)
an undirected unweighted graph with 8 vertices and 12 edges
> draw_graph(H,planar)

2.7 Special graphs

17

> H:=hypercube_graph(5)
an undirected unweighted graph with 32 vertices and 80 edges

2.7.2. Star graphs
The command star_graph is used for creating star graphs.
star_graph accepts a positive integer n as its only argument and returns the star graph with n + 1
vertices, which is equal to the complete bipartite graph complete_graph(1,n) i.e. a n-ary tree
with one level.
> G:=star_graph(5)
an undirected unweighted graph with 6 vertices and 5 edges
> draw_graph(G)

2.7.3. Wheel graphs
The command wheel_graph is used for creating wheel graphs.
wheel_graph accepts a positive integer n as its only argument and returns the wheel graph with
n + 1 vertices.
> G:=wheel_graph(5)
an undirected unweighted graph with 6 vertices and 10 edges
> draw_graph(G)

2.7.4. Web graphs
The command web_graph is used for creating web graphs.
web_graph accepts two positive integers a and b as its arguments and returns the web graph with
parameters a and b, namely the Cartesian product of cycle_graph(a) and path_graph(b).
> G:=web_graph(7,3)
an undirected unweighted graph with 21 vertices and 35 edges

18

Constructing graphs

> draw_graph(G,labels=false)

2.7.5. Prism graphs
The command prism_graph is used for creating prism graphs.
prism_graph accepts a positive integer n as its only argument and returns the prism graph with
parameter n, namely petersen_graph(n,1).
> G:=prism_graph(5)
an undirected unweighted graph with 10 vertices and 15 edges
> draw_graph(G)

2.7.6. Antiprism graphs
The command antiprism_graph is used for creating antiprism graphs.
antiprism_graph accepts a positive integer n as its only argument and returns the antiprism
graph with parameter n, which is constructed from two concentric cycles of n vertices by joining
each vertex of the inner to two adjacent nodes of the outer cycle.
> G:=antiprism_graph(7)
an undirected unweighted graph with 14 vertices and 28 edges
> draw_graph(G)

2.7.7. Grid graphs
The command grid_graph resp. torus_grid_graph is used for creating rectangular resp. torus
grid graphs.

2.7 Special graphs

19

grid_graph accepts two positive integers m and n as its arguments and returns the m by n grid
on m  n vertices, namely the Cartesian product of path_graph(m) and path_graph(n).
> G:=grid_graph(15,20)
an undirected unweighted graph with 300 vertices and 565 edges
> draw_graph(G,spring)

Connecting vertices in the opposite corners of the generated grid yields an interesting new graph.
> G:=add_edge(G,[["14:0","0:19"],["0:0","14:19"]])
an undirected unweighted graph with 300 vertices and 567 edges
> draw_graph(G,plot3d)

In the following example, the Möbius strip is constructed by connecting the vertices in the oppposite sides of a narrow grid graph.
> G:=grid_graph(20,3)
an undirected unweighted graph with 60 vertices and 97 edges
> G:=add_edge(G,[["0:0","19:2"],["0:1","19:1"],["0:2","19:0"]])
an undirected unweighted graph with 60 vertices and 100 edges
> draw_graph(G,plot3d,labels=false)

torus_grid_graph accepts two positive integers m and n as its arguments and returns the m by n
torus grid on m n vertices, namely the Cartesian product of cycle_graph(m) and cycle_graph(n).
> G:=torus_grid_graph(8,3)
an undirected unweighted graph with 24 vertices and 48 edges
> draw_graph(G,spring,labels=false)

20

Constructing graphs

2.7.8. Sierpi«ski graphs
The command sierpinski_graph is used for creating Sierpi«ski-type graphs Skn and STkn [9].
sierpinski_graph accepts two positive integers n and k as its arguments (and optionally the
symbol triangle as the third argument) and returns the Sierpi«ski (triangle) graph with parameters n and k.
The Sierpi«ski triangle graph STkn is obtained by contracting all non-clique edges in Skn. To detect
such edges the variant of the algorithm by Bron and Kerbosch, developed by Tomita et al. in
[20], is used, which can be time consuming for n > 6.
In particular, ST3n is the well-known Sierpi«ski sieve2.1 graph of order n.
> S:=sierpinski_graph(4,3)
an undirected unweighted graph with 81 vertices and 120 edges
> draw_graph(S,spring)

> sierpinski_graph(4,3,triangle)
an undirected unweighted graph with 42 vertices and 81 edges
> sierpinski_graph(5,3,triangle)
an undirected unweighted graph with 123 vertices and 243 edges
A drawing of the graph produced by the last command line is shown in Figure 4.1.

2.7.9. Generalized Petersen graphs
The command petersen_graph is used for creating generalized Petersen graphs P (n; k).
petersen_graph accepts two arguments, n and k (positive integers). The second argument may
be omitted, in which case k = 2 is assumed. The graph P (n; k), which is returned, is a connected
cubic graph consisting ofin Schläi notationan inner star polygon fn; kg and an outer regular
polygon fng such that the n pairs of corresponding vertices in inner and outer polygons are
connected with edges. For k = 1 the prism graph of order n is obtained.
The well-known Petersen graph is equal to the generalized Petersen graph P (5; 2). It can also be
constructed by calling graph("petersen").
2.1. https://en.wikipedia.org/wiki/Sierpinski_triangle

2.7 Special graphs

21

> draw_graph(graph("petersen"))

To obtain the dodecahedral graph P (10; 2), input:
> petersen_graph(10)
an undirected unweighted graph with 20 vertices and 30 edges
To obtain MöbiusKantor graph P (8; 3), input:
> G:=petersen_graph(8,3)
an undirected unweighted graph with 16 vertices and 24 edges
> draw_graph(G)
0

1
8 9

7

2

15

10

14

11

6

3

1312
5

4

Note that Desargues, Dürer and Nauru graphs are also generalized Petersen graphs P (10; 3), P (6;
2) and P (12; 5), respectively.

2.7.10. LCF graphs
The command lcf_graph is used for constructing a cubic Hamiltonian graph from its LCF notation2.2.
lcf_graph takes one or two arguments, a list L of nonzero integers, called jumps, and optionally
a positive integer n, called exponent (by default, n = 1). The command returns the graph on n jLj
vertices obtained by iterating the sequence of jumps n times.
For example, the following command line creates the Frucht graph.
> F:=lcf_graph([-5,-2,-4,2,5,-2,2,5,-2,-5,4,2])
an undirected unweighted graph with 12 vertices and 18 edges
> draw_graph(F,planar)

2.2. For the details about LCF notation, see https://en.wikipedia.org/wiki/LCF_notation.

22

Constructing graphs

The following command line constructs the truncated octahedral graph.
> G:=lcf_graph([3,-7,7,-3],6)
an undirected unweighted graph with 24 vertices and 36 edges
> draw_graph(G,planar,labels=false)

2.8. Isomorphic copies of graphs
The commands isomorphic_copy, permute_vertices and relabel_vertices are used for constructing isomorphic copies of existing graphs.

2.8.1. Creating an isomorphic copy of a graph
The command isomorphic_copy accepts two arguments, a graph G(V ; E) and a permutation 
of order jV j, and returns the copy of graph G with vertices rearranged according to .
> G:=isomorphic_copy(path_graph([1,2,3,4,5]),randperm(5))
an undirected unweighted graph with 5 vertices and 4 edges
> vertices(G)
[2; 5; 3; 4; 1]

2.8.2. Permuting graph vertices
The command permute_vertices accepts two arguments, a graph G(V ; E) and a list L of length
jV j containing all vertices from V in a certain order, and returns a copy of G with vertices
rearranged as specied by L.
> G:=permute_vertices(path_graph([a,b,c,d]),[b,d,a,c])
an undirected unweighted graph with 4 vertices and 3 edges
> vertices(G)
[b; d; a; c]

2.8.3. Relabeling graph vertices
The command relabel_vertices accepts two arguments, a graph G(V ; E) and a list L of vertex
labels, and returns the copy of G with vertices relabeled with labels from L.
> P:=path_graph([1,2,3,4])
an undirected unweighted graph with 4 vertices and 3 edges
> edges(P)

2.9 Subgraphs

23

f[1; 2]; [2; 3]; [3; 4]g
> G:=relabel_vertices(P,[a,b,c,d])
an undirected unweighted graph with 4 vertices and 3 edges
> edges(G)
f[a; b]; [b; c]; [c; d]g

2.9. Subgraphs
2.9.1. Extracting subgraphs
To extract the subgraph of G(V ; E) formed by edges from L  E, use the command subgraph
which accepts two arguments: G and L.
> K5:=complete_graph(5)
an undirected unweighted graph with 5 vertices and 10 edges
> S:=subgraph(K5,[[1,2],[2,3],[3,4],[4,1]])
an undirected unweighted graph with 4 vertices and 4 edges
> draw_graph(highlight_subgraph(K5,S))

2.9.2. Induced subgraphs
To obtain the subgraph of G induced by set of vertices L  V , use the command induced_subgraph.
induced_subgraph accepts two arguments G and L and returns the subgraph of G formed by all
edges in E which have endpoints in L.
> G:=graph("petersen")
an undirected unweighted graph with 10 vertices and 15 edges
> S:=induced_subgraph(G,[5,6,7,8,9])
an undirected unweighted graph with 5 vertices and 5 edges
> draw_graph(highlight_subgraph(G,S))

24

Constructing graphs

2.9.3. Underlying graphs
For every graph G(V ; E) there is an undirected and unweighted graph U (V ; E 0), called the
underlying graph of G, where E 0 is obtained from E by dropping edge directions.
To construct U use the command underlying_graph which accepts G as its only argument. The
result is obtained by copying G and forgetting the directions of edges as well as their weights.
> G:=digraph(%{[[1,2],6],[[2,3],4],[[3,1],5],[[3,2],7]%})
a directed weighted graph with 3 vertices and 4 arcs
> U:=underlying_graph(G)
an undirected unweighted graph with 3 vertices and 3 edges
> edges(U)
f[1; 2]; [1; 3]; [2; 3]g

2.10. Operations on graphs
2.10.1. Graph complement
The command graph_complement is used for constructing complements of graphs.
graph_complement accepts a graph G(V ; E) as its only argument and returns the complement
Gc(V ; E c) of G, where E c is the largest set containing only edges/arcs not present in G.
> C5:=cycle_graph(5)
C5: an undirected unweighted graph with 5 vertices and 5 edges
> draw_graph(C5)
0

4

1

3

2

> G:=graph_complement(C5)
an undirected unweighted graph with 5 vertices and 5 edges
> draw_graph(G)
0

4

1

3

2

2.10.2. Seidel switching
The command seidel_switch is used for Seidel switching in graphs.

2.10 Operations on graphs

25

seidel_switch accepts two arguments, an undirected and unweighted graph G(V ; E) and a list
of vertices L  V . The result is a copy of G in which, for each vertex v 2 L, its neighbors become
its non-neighbors and vice versa.
> S:=seidel_switch(cycle_graph(5),[1,2])
an undirected unweighted graph with 5 vertices and 7 edges
> draw_graph(S)
0

4

1

3

2

2.10.3. Transposing graphs
The command reverse_graph is used for reversing arc directions in digraphs.
reverse_graph accepts a graph G(V ; E) as its only argument and returns the reverse graph GT (V ;
E 0) of G where E 0 = f(j ; i): (i; j) 2 E g, i.e. returns the copy of G with the directions of all edges
reversed.
Note that reverse_graph is dened for both directed and undirected graphs, but gives meaningful
results only for directed graphs.
GT is also called the transpose graph of G because adjacency matrices of G and GT are transposes
of each other (hence the notation).
> G:=digraph(6, %{[1,2],[2,3],[2,4],[4,5]%})
a directed unweighted graph with 6 vertices and 4 arcs
> GT:=reverse_graph(G)
a directed unweighted graph with 6 vertices and 4 arcs
> edges(GT)
f[2; 1]; [3; 2]; [4; 2]; [5; 4]g

2.10.4. Union of graphs
The command graph_union is used for constructing union of two or more graphs.
graph_union accepts a sequence of graphs Gk(Vk ; Ek) for k = 1; 2; :::; n as its argument and returns
the graph G(V ; E) where V = V1 [ V2 [  [ Vk and E = E1 [ E2 [  [ Ek.
> G1:=graph([1,2,3],%{[1,2],[2,3]%})
an undirected unweighted graph with 3 vertices and 2 edges
> G2:=graph([1,2,3],%{[3,1],[2,3]%})
an undirected unweighted graph with 3 vertices and 2 edges
> G:=graph_union(G1,G2)
an undirected unweighted graph with 3 vertices and 3 edges
> edges(G)

26

Constructing graphs

f[1; 2]; [1; 3]; [2; 3]g

2.10.5. Disjoint union of graphs
To construct disjoint union of graphs use the command disjoint_union.
disjoint_union accepts a sequence of graphs Gk(Vk ; Ek) for k = 1; 2; :::; n as its argument and
returns the graph obtained by labeling all vertices with strings k:v where v 2 Vk and all edges with
strings k:e where e 2 Ek and calling the graph_union
command subsequently.
As all vertices and
P
P
edges are labeled dierently, it follows jV j = nk=1 jVk j and jE j = nk=1 jEk j.
> G:=disjoint_union(cycle_graph([1,2,3]),path_graph([1,2,3]))

an undirected unweighted graph with 6 vertices and 5 edges
> draw_graph(G)

2.10.6. Joining two graphs
The command graph_join is used for joining graphs.
graph_join accepts two graphs G and H as its arguments and returns the graph which is obtained
by connecting all the vertices of G to all vertices of H. The vertex labels in the resulting graph
are strings of the form 1:u and 2:v where u is a vertex in G and v is a vertex in H.
> G:=graph_join(path_graph(2),graph(3))
an undirected unweighted graph with 5 vertices and 7 edges
> draw_graph(G,spring)
2:0

1:1

1:0

2:1

2:2

2.10.7. Power graphs
The command graph_power is used for constructing the powers of a graph.
graph_power accepts two arguments, a graph G(V ; E) and a positive integer k, and returns the
k-th power Gk of G with vertices V such that v; w 2 V are connected with an edge if and only if
there exists a path of length at most k in G.
The graph Gk is constructed from its adjacency matrix Ak which is obtained by adding powers of
the adjacency matrix A of G:
Ak =

k
X
i=1

Ak:

2.10 Operations on graphs

The above sum is obtained by assigning Ak A and repeating the instruction Ak
k ¡ 1 times, so exactly k matrix multiplications are required.

27

(Ak + I) A for

> G:=graph(trail(1,2,3,4,5))
an undirected unweighted graph with 5 vertices and 4 edges
> draw_graph(G,circle)

> P2:=graph_power(G,2)
an undirected unweighted graph with 5 vertices and 7 edges
> draw_graph(P2,circle)

> P3:=graph_power(G,3)
an undirected unweighted graph with 5 vertices and 9 edges
> draw_graph(P3,circle)

2.10.8. Graph products
There are two distinct operations for computing the product of two graphs: Cartesian product and
tensor product. These operations are available in Giac as the commands cartesian_product and
tensor_product, respectively.
The command cartesian_product accepts a sequence of graphs Gk(Vk ; Ek) for k = 1; 2; :::; n as its
argument and returns the Cartesian product G1  G2    Gn of the input graphs. The Cartesian
product G(V ; E) = G1  G2 is the graph with list of vertices V = V1  V2, labeled with strings v1:v2
where v1 2 V1 and v2 2 V2, such that (u1:v1,u2:v2)2E if and only if u1 is adjacent to u2 and v1 = v2
or u1 = u2 and v1 is adjacent to v2.
> G1:=graph(trail(1,2,3,4,1,5))
an undirected unweighted graph with 5 vertices and 5 edges
> draw_graph(G1,circle)

28

Constructing graphs

> G2:=star_graph(3)
an undirected unweighted graph with 4 vertices and 3 edges
> draw_graph(G2,circle=[1,2,3])

> G:=cartesian_product(G1,G2)
an undirected unweighted graph with 20 vertices and 35 edges
> draw_graph(G)

The command tensor_product accepts a sequence of graphs Gk(Vk ; Ek) for k = 1; 2; :::; n as its
argument and returns the tensor product G1  G2    Gn of the input graphs. The tensor product
G(V ; E) = G1  G2 is the graph with list of vertices V = V1  V2, labeled with strings v1:v2 where
v1 2 V1 and v2 2 V2, such that (u1:v1,u2:v2)2E if and only if u1 is adjacent to u2 and v1 is adjacent
to v2.
> T:=tensor_product(G1,G2)
an undirected unweighted graph with 20 vertices and 30 edges
> draw_graph(T)

2.10.9. Transitive closure graph
The command transitive_closure is used for constructing the transitive closure graph of the
given graph. Transitive closure of a (directed) graph G(V ; E) is the graph T (V ; E 0) in which two
vertices v; w 2 V are connected by an edge (arc) e = vw 2 E 0 if and only if there exists a (directed)
path from v to w in G.

2.10 Operations on graphs

29

transitive_closure accepts one or two arguments, the input graph G and optionally the option
weighted=true (or simply weighted) or the option weighted=false (which is the default). The
command returns the transitive closure T of the input graph G. If G is a digraph, then T is also a
digraph. When weighted=true is specied, the graph T is weighted such that the weight of edge
v w 2 E 0 is equal to the length (or weight, if G is weighted) of the shortest path from v to w in G.
The lengths/weights of the shortest paths are obtained by the command allpairs_distance if G
is weighted resp. the command vertex_distance if G is unweighted. Therefore T is constructed
in at most O(jV j3) time if weighted=true resp. O(jV j jE j) time if weighted=false.
> G:=digraph([1,2,3,4,5,6],%{[1,2],[2,3],[2,4],[4,5],[3,5]%})
a directed unweighted graph with 6 vertices and 5 arcs
> draw_graph(G)

> T:=transitive_closure(G,weighted)
a directed weighted graph with 6 vertices and 9 arcs
> draw_graph(T)

> G:=assign_edge_weights(G,1,99)
a directed weighted graph with 6 vertices and 5 arcs
> draw_graph(G)

> draw_graph(transitive_closure(G,weighted=true))

30

Constructing graphs

2.10.10. Line graph
The command line_graph is used for constructing the line graph of an undirected graph G(V ; E).
line_graph accepts the input graph G as its only argument and returns the line graph L(G) with
jE j distinct vertices, one vertex for each edge in E. Two vertices v1 and v2 in L(G) are adjacent if
and only if the corresponding edges e1; e2 2 E have a common endpoint. The vertices in L(G) are
labeled with strings in form v-w, where e = vw 2 E.
> K4:=complete_graph([1,2,3,4])
an undirected unweighted graph with 4 vertices and 6 edges
> L:=line_graph(K4)
an undirected unweighted graph with 6 vertices and 12 edges
> draw_graph(L,spring)

2.10.11. Plane dual graph
The command plane_dual is used for constructing the plane dual graph of an undirected biconnected planar graph.
plane_dual accepts one argument, the input graph G(V ; E) or the list F of faces of a planar
embedding of G, and returns the graph H with faces of G as its vertices in which two vertices are
adjacent if and only if they share an edge as faces of G.
Note that the concept of dual graph is usually dened for multigraphs2.3. By the strict denition,
every planar multigraph has the corresponding dual multigraph; moreover, the dual of the latter
is equal to the former. Since Giac does not support multigraphs, a simplied denition suitable
for simple graphs is used.
The algorithm runs in O(jV j2) time.
> H:=hypercube_graph(3)
an undirected unweighted graph with 8 vertices and 12 edges
> draw_graph(H,spring)

The cube has six faces, hence its plane dual graph D has six vertices. Also, every face obviously
shares an edge with exactly four other faces, so the degree of each vertex in D is equal to 4.
> D:=plane_dual(H)
2.3. See https://en.wikipedia.org/wiki/Dual_graph for the strict denition of plane dual graph.

2.11 Random graphs

31

an undirected unweighted graph with 6 vertices and 12 edges
> draw_graph(D,spring)

A graph isomorphic to D is obtained when passing a list of faces of H to the plane_dual command.
The order of vertices is determined by the order of faces.
> is_planar(H,F)
Done; true
> plane_dual(F)
an undirected unweighted graph with 6 vertices and 12 edges

2.11. Random graphs
2.11.1. Random general graphs
The commands random_graph and random_digraph are used for generating general graphs at
random.
random_graph and random_digraph both accept two arguments. The rst argument is a positive
integer n or a list of labels L of length n. The second argument is a positive real number p < 1 or
a positive integer m. The command returns a random (di)graph on n vertices (using elements of
L as vertex labels) in which each edge/arc is inserted with probability p or which contains exactly
m edges/arcs chosen at random.
> G:=random_digraph(10,0.2)
a directed unweighted graph with 10 vertices and 15 arcs
> draw_graph(G,spring,labels=false)

> G:=random_graph(1000,0.01)
an undirected unweighted graph with 1000 vertices and 4922 edges
> is_connected(G)
true
> is_biconnected(G)

32

Constructing graphs

false
> G:=random_graph(100,99)
an undirected unweighted graph with 100 vertices and 99 edges
> is_tree(G)
false
> draw_graph(G,spring)

2.11.2. Random bipartite graphs
The command random_bipartite_graph is used for generating bipartite graphs at random.
random_bipartite_graph accepts two arguments. The rst argument is either a positive integer
n or a list of two positive integers a and b. The second argument is either a positive real number
p < 1 or a positive integer m. The command returns a random bipartite graph on n vertices (or
with two partitions of sizes a and b) in which each possible edge is present with probability p (or
m edges are inserted at random).
> G:=random_bipartite_graph([3,4],0.5)
an undirected unweighted graph with 7 vertices and 8 edges
> draw_graph(G)

> G:=random_bipartite_graph(30,60)
an undirected unweighted graph with 30 vertices and 60 edges

2.11.3. Random trees
The command random_tree is used for generating tree graphs uniformly at random.
random_tree accepts a positive integer n as its only argument and returns a random tree generated
on n nodes (i.e. inserts n ¡ 1 edges in the initially empty graph).
> T:=random_tree(30)
an undirected unweighted graph with 30 vertices and 29 edges

2.11 Random graphs

33

> draw_graph(T,labels=false)

2.11.4. Random planar graphs
The command random_planar_graph is used for generating random planar graphs, controlling
edge density and vertex connectivity.
random_planar_graph accepts two or three arguments, a positive integer n (or a list L of length
n), a positive real number p < 1 and optionally an integer k 2 f0; 1; 2; 3g (by default, k = 1). The
command returns a random k-connected planar graph on n vertices (using elements of L as vertex
labels).
The result is obtained by rst generating a random maximal planar graph and then attempting
to remove each edge with probability p, maintaining the k-connectivity of the graph (if k = 0, the
graph may be disconnected). The running time is O(jV j) if k = 0, O(jV j2) if k 2 f1; 2g and O(jV j3)
if k = 3.
The following command line generates a biconnected planar graph.
> G:=random_planar_graph(20,0.8,2)
an undirected unweighted graph with 20 vertices and 25 edges
> draw_graph(G,planar,labels=false)

The command line below generates a triconnected planar graph.
> G:=random_planar_graph(15,0.9,3)
an undirected unweighted graph with 15 vertices and 25 edges
> draw_graph(G,planar,labels=false)

The next command line generates a disconnected planar graph with high probability.
> G:=random_planar_graph(30,0.9,0)
an undirected unweighted graph with 30 vertices and 23 edges
> is_forest(G)

34

Constructing graphs

true
> draw_graph(G,spring,labels=false)

By default, a connected planar graph is generated, like in the following example.
> G:=random_planar_graph(15,0.618)
an undirected unweighted graph with 15 vertices and 19 edges
> is_connected(G)
true
> is_biconnected(G)
false
> articulation_points(G)
[1; 2; 4; 10; 11]
> draw_graph(G,planar)

2.11.5. Random regular graphs
The command random_regular_graph is used for generating random d-regular graphs on a certain
set of vertices, using the algorithm presented in [17]2.4.
random_regular_graph accepts two mandatory arguments, a positive integer n (or a list L of
length n) and a nonnegative integer d. Optionally, the option connected may be specied as the
third argument, indicating that the generated graph must be 1-connected (by default no restriction
is made). The command creates n vertices (using elements of L as vertex labels) and returns a
random d-regular (connected) graph on these vertices.
Note that a d-regular graph on n vertices exists if and only if n > d + 1 and n d is even. If these
conditions are not met, random_regular_graph returns an error.
This algorithm generates regular graphs with approximately uniform probability. It means that
for n! 1 and d not growing so quickly with n the probability distribution converges to uniformity.
The runtime of the algorithm is negligible for n 6 100. For n > 200 the algorithm is considerably
slower.
> G:=random_regular_graph(16,3)
an undirected unweighted graph with 16 vertices and 24 edges
2.4. See Algorithm 2 on page 2.

2.11 Random graphs

35

> is_regular(G)
true
> degree_sequence(G)
[3; 3; 3; 3; 3; 3; 3; 3; 3; 3; 3; 3; 3; 3; 3; 3]
> draw_graph(G,spring)
15

11
9
13

2

14 0

4
7

12
10

6

8

5

1

3

2.11.6. Random tournaments
The command random_tournament is used for generating random tournaments. A tournament of
order n is a graph obtained by assigning a direction to each edge in a complete graph Kn (for each
edge there are two possible directions).
random_tournament accepts a positive integer n (or a list L of length n) as its only argument and
returns a random tournament on n vertices. If L is specied, its elements are used to label the
vertices.
> G:=random_tournament([1,2,3,4])
a directed unweighted graph with 4 vertices and 6 arcs
> is_tournament(G)
true
> draw_graph(G)

2.11.7. Random ow networks
Giac]

2.11.8. Randomizing edge weights
The command assign_edge_weights is used for assigning weights to edges of a graph at random.
assign_edge_weights accepts two or three arguments. The rst argument is always the input
graph G(V ; E). If only two arguments are given, the second one is an interval a..b of real numbers.
Otherwise, if three arguments are given, the second resp. the third argument is a positive integer
m resp. n. The command operates such that for each edge e 2 E, its weight is chosen uniformly
from the real interval [a; b) or from the set of integers lying between m and n, including both m
and n. After assigning weights to all edges, the modied copy of G is returned.

36

Constructing graphs

> G:=assign_edge_weights(grid_graph(5,3),1,99)
an undirected weighted graph with 15 vertices and 22 edges
> draw_graph(G,spring)

> G:=assign_edge_weights(graph_complement(complete_graph(2,3,4)),e..pi)
an undirected weighted graph with 9 vertices and 10 edges
> draw_graph(G)

Chapter 3
Modifying graphs
3.1. Modifying vertices of a graph
3.1.1. Adding and removing single vertices
For adding and removing vertices to/from graphs use the commands add_vertex and
delete_vertex, respectively.
The command add_vertex accepts two arguments, a graph G(V ; E) and a single label v or a list
of labels L, and returns the graph G 0 (V [ fvg; E) or G 00 (V [ L; E) if a list L is given.
> K5:=complete_graph([1,2,3,4,5])
an undirected unweighted graph with 5 vertices and 10 edges
> add_vertex(K5,6)
an undirected unweighted graph with 6 vertices and 10 edges
> add_vertex(K5,[a,b,c])
an undirected unweighted graph with 8 vertices and 10 edges
Note that vertices already present in G won't be added. For example:
> add_vertex(K5,[4,5,6])
an undirected unweighted graph with 6 vertices and 10 edges
The command delete_vertex accepts two arguments, a graph G(V ; E) and a single label v or a
list of labels L, and returns the graph
G 0 (V n fv g; fe 2 E: e is not incident to v g)
or, if L is given,
G 00 (V n L; fe 2 E: e is not incident to any v 2 Lg):
If any of the specied vertices does not belong to G, an error is returned.
> delete_vertex(K5,2)
an undirected unweighted graph with 4 vertices and 6 edges
> delete_vertex(K5,[2,3])
an undirected unweighted graph with 3 vertices and 3 edges

3.2. Modifying edges of a graph
3.2.1. Adding and removing single edges
For adding and removing edges or arcs to/from graphs use the commands add_edge or add_arc
and delete_edge and delete_arc, respectively.
37

38

Modifying graphs

The command add_edge accepts two arguments, an undirected graph G(V ; E) and an edge or a list
of edges or a trail of edges (entered as a list of vertices), and returns the copy of G with the specied
edges inserted. Edge insertion implies creation of its endpoints if they are not already present.
> C4:=cycle_graph(4)
C4: an undirected unweighted graph with 4 vertices and 4 edges
> add_edge(C4,[1,3])
C4: an undirected unweighted graph with 4 vertices and 5 edges
> add_edge(C4,[1,3,5,7])
C4: an undirected unweighted graph with 6 vertices and 7 edges
The command add_arc works similarly to add_edge but applies only to directed graphs. Note that
the order of endpoints in an arc matters.
> add_arc(digraph(trail(a,b,c,d,a)),[[a,c],[b,d]])
a directed unweighted graph with 4 vertices and 6 arcs
When adding edge/arc to a weighted graph, its weight should be specied alongside its endpoints,
or it will be assumed that it equals to 1.
> add_edge(graph(%{[[1,2],5],[[3,4],6]%}),[[2,3],7])
an undirected weighted graph with 4 vertices and 3 edges

3.2.2. Accessing and modifying edge weights
The commands get_edge_weight and set_edge_weight are used to access and modify the weight
of an edge/arc in a weighted graph, respectively.
set_edge_weight accepts three arguments: a weighted graph G(V ; E), edge/arc e 2 E and the
new weight w, which may be any number. It returns the modied copy of G.
The command get_edge_weight accepts two arguments, a weighted graph G(V ; E) and an edge
or arc e 2 E. It returns the weight of e.
> G:=set_edge_weight(graph(%{[[1,2],4],[[2,3],5]%}),[1,2],6)
an undirected weighted graph with 3 vertices and 2 edges
> get_edge_weight(G,[1,2])
6

3.2.3. Contracting edges
The command contract_edge is used for contracting (collapsing) edges in a graph.
contract_edge accepts two arguments, a graph G(V ; E) and an edge/arc e = (v; w) 2 E, and
merges w and v into a single vertex, deleting the edge e. The resulting vertex inherits the label of
v. The command returns the modied graph G 0 (V n fwg; E 0).
> K5:=complete_graph(5)
an undirected unweighted graph with 5 vertices and 10 edges
> contract_edge(K5,[1,2])

3.2 Modifying edges of a graph

39

an undirected unweighted graph with 4 vertices and 6 edges
To contract a set fe1; e2; :::; ek g  E of edges in G, none two of which are incident (i.e. when the
given set is a matching in G), one can use the foldl command. In the following example, the
complete graph K5 is obtained from Petersen graph by edge contraction.
> P:=graph("petersen")
an undirected unweighted graph with 10 vertices and 15 edges
> G:=foldl(contract_edge,P,[0,5],[1,6],[2,7],[3,8],[4,9])
an undirected unweighted graph with 5 vertices and 10 edges
> draw_graph(G)
0

4

1

3

2

3.2.4. Subdividing edges
The command subdivide_edges is used for subdividing edges of a graph.
subdivide_edges accepts two or three arguments, a graph G(V ; E), a single edge/arc or a list
of edges/arcs in E and optionally a positive integer r (which defaults to 1). Each of the specied
edges/arcs will be subdivided with exactly r new vertices, labeled with the smallest available
integers. The resulting graph, which is homeomorphic to G, is returned.
If the endpoints of the edge being subdivided have valid coordinates, the coordinates of the inserted
vertices will be computed accordingly.
> G:=graph("petersen")
an undirected unweighted graph with 10 vertices and 15 edges
> G:=subdivide_edges(G,[2,3])
an undirected unweighted graph with 11 vertices and 16 edges
> G:=subdivide_edges(G,[[1,2],[3,4]])
an undirected unweighted graph with 13 vertices and 18 edges
> G:=subdivide_edges(G,[0,1],2)
an undirected unweighted graph with 15 vertices and 20 edges
> draw_graph(G)
0
13
5
14
4

1
9

6
11

12
8
3

7
10

2

40

Modifying graphs

3.3. Using attributes
3.3.1. Graph attributes
The graph structure maintains a set of attributes as tag-value pairs which can be accessed and
modied by the user.
The command set_graph_attribute is used for modifying the existing graph attributes or adding
new ones. It accepts two arguments, a graph G and a sequence or list of graph attributes in form
tag=value where tag is any string. Alternatively, attributes may be specied as a sequence of two
lists [tag1,tag2,...] and [value1,value2,...]. The command sets the specied values to the
indicated attribute slots, which are meant to represent some global properties of the graph G, and
returns the modied copy of G.
The previously set graph attribute values can be fetched with the command get_graph_attribute
which accepts two arguments: a graph G and a sequence or list of tags. The corresponding values
will be returned in a sequence or list, respectively. If some attribute is not set, undef is returned
as its value.
To list all graph attributes of G for which the values are set, use the list_graph_attributes
command which takes G as its only argument.
To discard a graph attribute, use the discard_graph_attribute command. It accepts two arguments: a graph G and a sequence or list of tags to be cleared, and returns the modied copy of G.
Two tags are normally being used by the CAS commands: directed and weighted, so it is not advisable to overwrite their values using this command (instead, use make_directed, make_weighted
and underlying_graph commands). Another attribute used internally is name, which holds the
name of the respective graph (as a string).
> G:=digraph(trail(1,2,3,1))
a directed unweighted graph with 3 vertices and 3 arcs
> G:=set_graph_attribute(G,"name"="C3","message"="this is some text")
C3: a directed unweighted graph with 3 vertices and 3 arcs
> get_graph_attribute(G,"message")
this is some text
> list_graph_attributes(G)
[directed = true; weighted = false; name = C3; message = this is some text]
> G:=discard_graph_attribute(G,"message")
C3: a directed unweighted graph with 3 vertices and 3 arcs
> list_graph_attributes(G)
[directed = true; weighted = false; name = C3]

3.3.2. Vertex attributes
For every vertex of a graph, the list of attributes in form of tag-value pairs is maintained, which
can be accessed and modied by the user.
The command set_vertex_attribute is used for modifying the existing vertex attributes or
adding new ones. It accepts three arguments, a graph G(V ; E), a vertex v 2 V and a sequence or list
of attributes in form tag=value where tag is any string. Alternatively, attributes may be specied
as a sequence of two lists [tag1,tag2,...] and [value1,value2,...]. The command sets the
specied values to the indicated attributes of the vertex v and returns the modied copy of G.

3.3 Using attributes

41

The previously set attribute values for v can be fetched with the command get_vertex_attribute
which accepts three arguments: G, v and a sequence or list of tags. The corresponding values will
be returned in a sequence or list, respectively. If some attribute is not set, undef is returned as
its value.
To list all attributes of v for which the values are set, use the list_vertex_attributes command
which takes two arguments, G and v.
The discard_vertex_attribute command is used for discarding attribute(s) assigned to some
vertex v 2 V . It accepts three arguments: G, v and a sequence or list of tags to be cleared, and
returns the modied copy of G.
The attributes label, color, shape and pos are also used internally. These hold the vertex label, color,
shape and coordinates in a drawing, respectively. If the color is not set for a vertex, the latter is
drawn in yellow. The shape attribute may have one of the following values: square, triangle, diamond,
star or plus. If the shape attribute is not set or has a dierent value, the circled shape is applied
when drawing the vertex.
The following example shows how to change individual labels and colors.
> T:=complete_binary_tree(3)
an undirected unweighted graph with 15 vertices and 14 edges
> T:=set_vertex_attribute(T,5,"label"="root","color"=red)
an undirected unweighted graph with 15 vertices and 14 edges
> draw_graph(T,tree="root")
root
2

11

0
1
3
7

12

6
13

14
4

8

9

10

A vertex may also hold custom attributes.
> T:=set_vertex_attribute(T,"root","depth"=3,"shape"="square")
an undirected unweighted graph with 15 vertices and 14 edges
> list_vertex_attributes(T,"root")
[label = root; color = r e d; shape = square; depth = 3]
> T:=discard_vertex_attribute(T,"root","color")
an undirected unweighted graph with 15 vertices and 14 edges
> list_vertex_attributes(T,"root")
[label = root; shape = square; depth = 3]

3.3.3. Edge attributes
For every edge of a graph, the list of attributes in form of key-value pairs is maintained, which can
be accessed and modied by the user.
The command set_edge_attribute is used for modifying the existing edge attributes or adding
new ones. It accepts three arguments, a graph G(V ; E), an edge/arc e 2 E and a sequence or list
of attributes in form tag=value where tag is any string. Alternatively, attributes may be specied
as a sequence of two lists [tag1,tag2,...] and [value1,value2,...]. The command sets the
specied values to the indicated attributes of the edge/arc e and returns the modied copy of G.

42

Modifying graphs

The previously set attribute values for e can be fetched with the command get_edge_attribute
which accepts three arguments: G, e and a sequence or list of tags. The corresponding values will
be returned in a sequence or list, respectively. If some attribute is not set, undef is returned as
its value.
To list all attributes of e for which the values are set, use the list_edge_attributes command
which takes two arguments, G and e.
To discard attribute(s) assigned to e call the discard_edge_attribute command, which accepts
three arguments: G, e and a sequence or list of tags to be cleared, and returns the modied copy
of G.
The attributes weight, color, style, pos and temp are also used internally. They hold the edge weight,
color, line style, the coordinates of the weight label anchor (and also the coordinates of the arrow)
and true if the edge is temporary. If the color attribute is not set for an edge, the latter is drawn
in blue, unless it is a temporary edge, in which case it is drawn in light grey. The style attribute
may have one of the following values: dashed, dotted or bold. If the style attribute is not set or has
a dierent value, the solid line style is applied when drawing the edge.
The following example illustrates the possibilities of using edge attributes.
> T:=complete_binary_tree(3)
an undirected unweighted graph with 15 vertices and 14 edges
> T:=set_edge_attribute(T,[1,4],"cost"=12.8,"message"="this is some text")
an undirected unweighted graph with 15 vertices and 14 edges
> list_edge_attributes(T,[1,4])
[cost = 12.8; message = this is some text]
> T:=discard_edge_attribute(T,[1,4],"message")
an undirected unweighted graph with 15 vertices and 14 edges
> T:=set_edge_attribute(T,[1,4],"style"="dotted","color"=magenta)
an undirected unweighted graph with 15 vertices and 14 edges
> list_edge_attributes(T,[1,4])
[color = m a g e n t a; style = dotted; cost = 12.8]
> T:=set_edge_attribute(T,[5,11],"temp"=true)
an undirected unweighted graph with 15 vertices and 14 edges
> draw_graph(T)
0
1

2

3

7

4

8

9

5

10 11

6

12 13

14

Chapter 4
Import and export
4.1. Importing graphs
4.1.1. Loading graphs from dot les
The command import_graph is used for importing a graph from text le in dot format4.1.
import_graph accepts a string filename as its only argument and returns the graph constructed
from instructions written in the le filename or undef on failure. The passed string should contain
the path to a le in dot format. The le extension .dot may be omitted in the filename since dot
is the only supported format. The alternative extension is .gv,4.2 which must be explicitly specied.
If a relative path to the le is specied, i.e. if it does not contain a leading forward slash, the
current working directory (which can be obtained by calling the pwd command) will be used as the
reference. The working directory can be changed by using the command cd.
For example, assume that the le example.dot is saved in the directory Documents/dot/ with the
following contents:
graph "Example graph" {
a [label="Foo"];
b [shape=diamond,color=red];
a -- b [style=bold];
b -- c [color=green];
b -- d [style=dotted];
}
To import the graph, input:
> G:=import_graph("Documents/dot/example.dot")
Example graph: an undirected unweighted graph with 4 vertices and 3 edges
> draw_graph(G)
Foo

b

c

d

4.1.2. The dot le format overview
Giac has some basic support for dot language4.3. Each dot le is used to hold exactly one graph
and should consist of a single instance of the following environment:
strict? (graph | digraph) name? {
...
}
4.1. https://en.wikipedia.org/wiki/DOT_(graph_description_language)
4.2. Although it is recommended to use .gv as the extension for dot les to avoid a certain confusion between dierent
le types, Giac uses the .dot extension because it coincides with the format name. This may change in the future.
4.3. For the complete syntax denition see https://www.graphviz.org/doc/info/lang.html.

43

44

Import and export

The keyword strict may be omitted, as well as the name of the graph, as indicated by the question
marks. The former is used to dierentiate between simple graphs (strict) and multigraphs (nonstrict). Since Giac supports only simple graphs, strict is redundant.
For specifying undirected graphs the keyword graph is used, while the digraph keyword is used
for undirected graphs.
The graph/digraph environment contains a series of instructions describing how the graph should
be built. Each instruction ends with the semicolon (;) and has one of the following forms.
syntax
creates
vertex_name [attributes]?
isolated vertices
V1  V2  :::  Vk [attributes]? edges and trails
graph [attributes]
graph attributes
Here, attributes is a comma-separated list of tag-value pairs in form tag=value,  is
-- for undirected and -> for directed graphs. Each of V1, V2 etc. is either a vertex name or a set
of vertex names in form {vertex_name1 vertex_name2 ...}. In the case a set is specied, each
vertex from that set is connected to the neighbor operands. Every specied vertex will be created
if it does not exist yet.
Any line beginning with # is ignored. C-like line and block comments are recognized and skipped
as well.
Using the dot syntax it is easy to specify a graph with adjacency lists. For example, the following
is the contents of a le which denes the octahedral graph with 6 vertices and 12 edges.
# octahedral graph
graph "octahedron" {
1 -- {3 6 5 4};
2 -- {3 4 5 6};
3 -- {5 6};
4 -- {5 6};
}

4.2. Exporting graphs
The command export_graph is used for saving graphs to disk in dot or LATEX format.

4.2.1. Saving graphs in dot format
export_graph accepts two mandatory arguments, a graph G and a string filename, and writes G
to the le specied by filename, which must be a path to the le, either relative or absolute; in
the former case the current working directory will be used as the reference. If only two arguments
are given the graph is saved in dot format. The le name may be entered with or without .dot
extension. The command returns 1 on success and 0 on failure.
> export_graph(G,"Documents/dot/copy_of_philosophers")
1

4.2.2. Saving graph drawings in LATEX format
When calling the export_graph command, an optional third argument in form latex[=]
may be given. In that case the drawing of G (obtained by calling the draw_graph command) will
be saved to the LATEX le indicated by filename (the extension .tex may be omitted). Optionally,
one can specify a parameter or list of parameters params which will be passed to the draw_graph
command.

4.2 Exporting graphs

45

For example, let us create a picture of the Sierpi«ski sieve graph of order n = 5, i.e. the graph ST35.
> G:=sierpinski_graph(5,3,triangle)
an undirected unweighted graph with 123 vertices and 243 edges
> export_graph(G,"Documents/st53.tex",latex=[spring,labels=false])
1
The LATEX le obtained by exporting a graph is easily converted into an EPS le, which can
subsequently be inserted4.4 in a paper, report or some other document. A Linux user simply needs
to launch a terminal emulator, navigate to the directory in which the exported le, in this case
st53.tex, is stored and enter the following command:
latex st53.tex && dvips st53.dvi && ps2eps st53.ps
This will produce the (properly cropped) st53.eps le in the same directory. Afterwards, it is
recommended to enter
rm st53.tex st53.aux st53.log st53.dvi st53.ps
to delete the intermediate les. The above two commands can be combined in a simple shell script
which takes the name of the exported le (without the extension) as its input argument:
#!/bin/bash
# convert LaTeX to EPS
latex $1.tex
dvips $1.dvi
ps2eps $1.ps
rm $1.tex $1.aux $1.log $1.dvi $1.ps
Assuming that the script is stored under the name latex2eps in the same directory as st53.tex,
to do the conversion it is enough to input:
bash latex2eps st53
The drawing produced in our example is shown in Figure 4.1.
b
b

b
b
b

b

b
b
b

b

b
b

b

b
b

b
b

b
b

b
b

b
b

b

b

b
b

b

b

b

b
b
b

b
b

b
b

b
b
b

b
b

b

b
b

b

b
b

b

b
b

b

b
b

b
b

b

b
b

b
b

b
b

b

b
b

b
b
b
b

b
b

b
b

b
b

b

b
b

b
b

b
b

b
b

b
b

b
b

b

b
b

b

b

b

b
b

b
b

b

b
b
b

b

b
b

b

Fig. 4.1. drawing of the Sierpi«ski graph

b

b

b
b

b

b

ST35

b

b
b

b
b

b
b

b
b

b

using LATEX and PSTricks

4.4. Alternatively, a PSTricks picture from the body of the .tex le can be copied to some other LATEX document.

Chapter 5
Graph properties
5.1. Basic properties
5.1.1. Listing vertices and edges
The command vertices or graph_vertices resp. edges is used for extracting set of vertices
resp. set of edges from a graph.
vertices or graph_vertices accepts a graph G(V ; E) as its only argument and returns the set
of vertices V in the same order in which they were created.
edges accepts one or two arguments, a graph G(V ; E) and optionally the identier weights. The
command returns the set of edges E (in a non-meaningful order). If weights is specied, each edge
is paired with the corresponding weight (in this case G must be a weighted graph).
> G:=hypercube_graph(2)
an undirected unweighted graph with 4 vertices and 4 edges
> vertices(G)
[00; 01; 10; 11]
> C:=graph("coxeter")
an undirected unweighted graph with 28 vertices and 42 edges
> vertices(C)
[a1; a2; a7; z1; a3; z2; a4; z3; a5; z4; a6; z5; z6; z7; b1; b3; b6; b2; b4; b7; b5; c1; c4; c5; c2; c6; c3; c7]
> H:=digraph([[0,2.32,0,0.25],[0,0,0,1.32],[0,0.50,0,0],[0.75,0,3.34,0]])
a directed weighted graph with 4 vertices and 6 arcs
> edges(H)
f[0; 1]; [0; 3]; [1; 3]; [2; 1]; [3; 0]; [3; 2]g
> edges(H,weights)
f[[0; 1]; 2.32]; [[0; 3]; 0.25]; [[1; 3]; 1.32]; [[2; 1]; 0.5]; [[3; 0]; 0.75]; [[3; 2]; 3.34]g

5.1.2. Vertex degrees
The command vertex_degree is used for computing the degree of a vertex, i.e. counting the
vertices adjacent to it.
vertex_degree accepts two arguments, a graph G(V ; E) and a vertex v 2 V , and returns the
cardinality of the set fw 2 V : (v; w) 2 E g, i.e. the number of vertices in V which are adjacent to v.

When dealing with directed graphs, one can also use the specialized command vertex_in_degree
resp. vertex_out_degree which accepts the same arguments as vertex_degree but returns the
number of arcs (w; v) 2 E resp. the number of arcs (v; w) 2 E, where w 2 V .
> G:=graph(trail(1,2,3,4,1,5,6,7,1,8,9,4))
47

48

Graph properties

an undirected unweighted graph with 9 vertices and 11 edges
> draw_graph(G)

> vertex_degree(G,1)
5
> T:=random_tournament([1,2,3,4,5])
a directed unweighted graph with 5 vertices and 10 arcs
> draw_graph(T)

> vertex_out_degree(T,1)
3
> vertex_in_degree(T,5)
2
To obtain the list of degrees of all vertices v 2 V , use the degree_sequence command.

degree_sequence accepts a graph G(V ; E) as its only argument and returns the list of degrees of
vertices from V in the same order as returned by the command vertices. If G is a digraph, arc
directions are ignored.
> degree_sequence(G)
[5; 2; 2; 3; 2; 2; 2; 2; 2]

5.1.3. Vertex adjacency
The command has_edge is used for checking if two vertices in an undirected graph are adjacent
or not.
has_edge accepts two arguments, the input graph G(V ; E) and a list [u,v] where u; v 2 V . The
command returns true if uv 2 E and false otherwise.

For digraphs, there is the similar command has_arc with the same input syntax. Note, however,
that the order of vertices u and v matters this time.
> G:=graph(trail(1,2,3,4,5,2))
an undirected unweighted graph with 5 vertices and 5 edges
> has_edge(G,[1,2])
true

5.1 Basic properties

49

> has_edge(G,[2,1])
true
> has_edge(G,[1,3])
false
> D:=digraph(trail(1,2,3,4,5,2))
a directed unweighted graph with 5 vertices and 5 arcs
> has_arc(D,[1,2])
true
> has_arc(D,[2,1])
false
The command neighbors is used for obtaining the list of vertices in a graph that are adjacent to
the particular vertex or the complete adjacency structure of the graph, in sparse form.
neighbors accepts one or two arguments. The rst, mandatory argument is the input graph
G(V ; E). The second, optional argument is a vertex v 2 V . The command returns the list of
neighbors of v in G if v is given and the list of lists of neighbors for all vertices in V , in order of
vertices(G), otherwise.
Note that neighbors works for undirected as well as for directed graphs, but ignores edge directions
in the latter case.
> neighbors(G,3)
[2; 4]
> neighbors(G)
f[2]; [1; 3; 5]; [2; 4]; [3; 5]; [2; 4]g
The command departures resp. arrivals is used for determining all neighbors of a vertex v in a
digraph which are the heads resp. the tails of the corresponding arcs.
departures resp. arrivals accepts one or two arguments, the input digraph G(V ; E) and optionally a vertex v 2 V , and returns the list Lv containing all vertices w 2 V for which v w 2 E
resp. wv 2 E. If v is omitted, the list of lists Lv for every v 2 V is returned.
> G:=digraph(trail(1,2,3,4,2,5,1,6,7,8,4))
a directed unweighted graph with 8 vertices and 10 arcs
> draw_graph(G,spring)
7
8

6

4

1

2
3

5

> departures(G,2); arrivals(G,2); departures(G,1); arrivals(G,1)
[3; 5]; [1; 4]; [2; 6]; [5]

5.1.4. Edge incidence
The command incident_edges is used for obtaining edges incident to the given vertex in a graph.

50

Graph properties

incident_edges accepts two argument, the input graph G(V ; E) and a vertex v 2 V or a list of
vertices L  V . The command returns the list of edges e1; e2; :::; ek 2 E which have v as one of its
endpoints.
Note that edge directions are ignored when G is a digraph. To obtain only outgoing or incoming
edges, use the commands departures and arrivals, respectively.
> G:=cycle_graph([1,2,3,4,5])
C5: an undirected unweighted graph with 5 vertices and 5 edges
> incident_edges(G,1)
f[1; 2]; [1; 5]g
> incident_edges(G,[2,4,5])
f[1; 2]; [1; 5]; [2; 3]; [3; 4]; [4; 5]g
> G:=random_tournament([1,2,3,4,5])
a directed unweighted graph with 5 vertices and 10 arcs
> incident_edges(G,2)
f[2; 1]; [2; 3]; [2; 5]; [4; 2]g

5.2. Algebraic properties
5.2.1. Adjacency matrix
The command adjacency_matrix is used for obtaining the adjacency matrix of a graph G(V ; E)
where V = fv1; v2; :::; vn g.

adjacency_matrix accepts the input graph G as its only argument and returns the square matrix
A = [ai j ] of order n such that, for i; j = 1; 2; :::; n,
ai j =



1, if the set E contains edge/arc vi v j ,
0; otherwise:

Note that tr (A) = 0. Also, the adjacency matrix of an undirected graph is always symmetrical.
> G:=graph("octahedron")
an undirected unweighted graph with 6 vertices and 12 edges
> A:=adjacency_matrix(G)
0

> transpose(A)==A

B
B
B
B
B
B
@

0
1
1
1
1
0

1
0
1
1
0
1

1
1
0
0
1
1

1
1
0
0
1
1

1
0
1
1
0
1

0
1
1
1
1
0

1
C
C
C
C
C
C
A

true
> D:=digraph(trail(1,2,3,4,5,2,6,7,3,8,1))
a directed unweighted graph with 8 vertices and 10 arcs

5.2 Algebraic properties

51

> draw_graph(D)
1

3

5

6

2

4

7

8

> A:=adjacency_matrix(D)
0

> transpose(A)==A

B
B
B
B
B
B
B
B
B
B
@

0
0
0
0
0
0
0
1

1
0
0
0
1
0
0
0

0
1
0
0
0
0
1
0

0
0
1
0
0
0
0
0

0
0
0
1
0
0
0
0

0
1
0
0
0
0
0
0

0
0
0
0
0
1
0
0

0
0
1
0
0
0
0
0

1
C
C
C
C
C
C
C
C
C
C
A

false

5.2.2. Weight matrix
The command weight_matrix is used for obtaining the weight matrix of a weighted graph G(V ; E)
where V = fv1; v2; :::; vn g.
weight_matrix accepts the input graph G as its only argument and returns the square matrix
M = [mi j] of order n such that mij equals zero if vi and v j are not adjacent and the weight of the
edge/arc vi v j otherwise, for all i; j = 1; 2; :::; n (note that the weight of an edge/arc may be any
real number).
Note that tr (M ) = 0. Also, the weight matrix of an undirected graph is always symmetrical.
> G:=graph(%{[[1,2],1],[[2,3],2],[[4,5],3],[[5,2],4]%})
an undirected weighted graph with 5 vertices and 4 edges
> weight_matrix(G)
0
B
B
B
B
@

0
1
0
0
0

1
0
2
0
4

0
2
0
0
0

0
0
0
0
3

0
4
0
3
0

1
C
C
C
C
A

5.2.3. Incidence matrix
The command incidence_matrix is used for obtaining the incidence matrix of a graph.
incidence_matrix accepts the input graph G(V ; E), where V = fv1; v2; :::; vn g and E = fe1; e2; :::;
em g, as its only argument and returns the n  m matrix B = [bi j ] such that, for all i = 1; 2; :::; n
and j = 1; 2; :::; m,

1; if the vertex vi is incident to the edge e j ,
bij =
0; otherwise

52

Graph properties

if G is undirected resp.
bij =
if G is directed.

8
<

1; if the vertex vi is the head of the arc e j ,
¡1; if the vertex vi is the tail of the arc e j ,
:
0; otherwise

> K4:=complete_graph([1,2,3,4])
an undirected unweighted graph with 4 vertices and 6 edges
> edges(K4)
f[1; 2]; [1; 3]; [1; 4]; [2; 3]; [2; 4]; [3; 4]g
> incidence_matrix(K4)
0

1
B 1
B
@ 0
0

1
0
1
0

1
0
0
1

0
1
1
0

0
1
0
1

1
0
0 C
C
1 A
1

> DG:=digraph(trail(1,2,3,4,5,3),trail(1,5,2,4,1))
a directed unweighted graph with 5 vertices and 9 arcs
> draw_graph(DG)
1

5

2

4

3

> edges(DG)
f[1; 2]; [1; 5]; [2; 3]; [2; 4]; [3; 4]; [4; 1]; [4; 5]; [5; 2]; [5; 3]g
> incidence_matrix(DG)
0
B
B
B
B
@

¡1 ¡1 0 0 0 1 0 0 0
1 0 ¡1 ¡1 0 0 0 1 0
0 0 1 0 ¡1 0 0 0 1
0 0 0 1 1 ¡1 ¡1 0 0
0 1 0 0 0 0 1 ¡1 ¡1

1
C
C
C
C
A

5.2.4. Characteristic polynomial
The command graph_charpoly or charpoly is used for obtaining the characteristic polynomial
of an undirected graph.
graph_charpoly or charpoly accepts one or two arguments, the input graph G(V ; E) and optionally a value or symbol x. The command returns p(x), where p is the characteristic polynomial of
the adjacency matrix of G.
> G:=graph(%{[1,2],[2,3]%})
an undirected unweighted graph with 3 vertices and 2 edges
> charpoly(G,x)

5.2 Algebraic properties

53

x3 ¡ 2 x

> charpoly(G,3)

21
> G:=graph("shrikhande")
an undirected unweighted graph with 16 vertices and 48 edges
> charpoly(G,x)
x16 ¡ 48 x14 ¡ 64 x13 + 768 x12 + 1536 x11 ¡ 5888 x10 ¡ 15360 x9 + 23040 x8 + 81920 x7 ¡
36864 x6 ¡ 245760 x5 ¡ 32768 x4 + 393216 x3 + 196608 x2 ¡ 262144 x ¡ 196608

5.2.5. Graph spectrum
The command graph_spectrum is used for obtaining the spectrum of eigenvalues of a graph.
graph_spectrum accepts the input graph G as its only argument and returns the list in which
every element is an eigenvalue of the adjacency matrix of G paired with its multiplicity.
> C5:=cycle_graph(5)
C5: an undirected unweighted graph with 5 vertices and 5 edges
> gs:=graph_spectrum(C5)
0

> p:=charpoly(C5,x)

> expand(roots(p))==expand(gs)

1
2
1
p
B
C
5 ¡1
B
2 C
B
C
B p2
C
@ ¡ 5¡1
A
2
2
x5 ¡ 5 x3 + 5 x ¡ 2
true

The last result indicates that gs and roots(p) are equal.

5.2.6. Seidel spectrum
The command seidel_spectrum is used for obtaining the Seidel spectrum of a graph.
seidel_spectrum accepts the input graph G(V ; E) as its only argument and returns the list in
which every element is an eigenvalue of the matrix J ¡ I ¡ 2 A paired with its multiplicity. Here J is
all-one n  n matrix, I is the identity matrix of order n, A is the adjacency matrix of G and n = jV j.
> G:=graph("clebsch")
an undirected unweighted graph with 16 vertices and 40 edges
> seidel_spectrum(G)


¡3 10
5 6



> P:=graph("petersen")
an undirected unweighted graph with 10 vertices and 15 edges

54

Graph properties

> seidel_spectrum(P)


¡3 5
3 5



5.2.7. Integer graphs
The command is_integer_graph is used for determining if a graph is an integer graph, i.e. if its
spectrum consists only of integers.
is_integer_graph accepts the input graph G as its only argument. The return value is true if
G is an integer graph and false otherwise.
> G:=graph("levi")
an undirected unweighted graph with 30 vertices and 45 edges
> is_integer_graph(G)
true
> factor(charpoly(G,x))
x10 (x ¡ 3) (x ¡ 2)9 (x + 2)9 (x + 3)

5.3. Connectivity
5.3.1. Vertex connectivity
The commands is_connected, is_biconnected and is_triconnected are used for determining
if a graph is connected, biconnected or triconnected, respectively.
All three commands accept only one argument, the input graph G(V ; E). They return true if G
possesses the required type of connectivity and false otherwise.
G is connected or 1-connected if for every pair v; w 2 V there exists a path with endpoints u and
v in G or in the underlying graph of G if the latter is directed.
G is biconnected or 2-connected if it remains connected after removing a vertex from G.
G is triconnected or 3-connected if it remains connected after removing a pair of distinct vertices
from G.
The strategy for checking 1- and 2-connectivity is to use depth-rst search (see [7] and [18]). Both
algorithms run in O(jV j + jE j) time. The algorithm for checking 3-connectivity is quite simple but
less ecient: it works by choosing a vertex v 2 V and checking if the subgraph induced by V n fv g
is biconnected, moving on to the next vertex if so, and repeating the process until all vertices are
visited exactly once or a non-biconnected subgraph is found for some v. In the latter case the input
graph is not triconnected. The complexity of this algorithm is O(jV j jE j).
> G:=graph_complement(complete_graph(2,3,4))
an undirected unweighted graph with 9 vertices and 10 edges
> is_connected(G)
false
> C:=connected_components(G)
f[0; 1]; [2; 3; 4]; [5; 6; 7; 8]g
> H:=induced_subgraph(G,C[2])

5.3 Connectivity

55

an undirected unweighted graph with 4 vertices and 6 edges
> is_connected(H)
true
> is_biconnected(path_graph(5))
false
> is_biconnected(cycle_graph(5))
true
> is_triconnected(graph("petersen"))
true
> is_triconnected(cycle_graph(5))
false

5.3.2. Connected and biconnected components
The command connected_components resp. biconnected_components is used for decomposing
a graph into connected resp. biconnected components.
connected_components resp. biconnected_components accept the input graph G(V ; E) as its
only argument and returns the minimal partition fV1; V2; :::; Vk g of V such that the subgraph Gi  G
induced by Vi is connected resp. biconnected for each i = 1; 2; :::; k. The partition is returned as a
list of lists V1; V2; :::; Vk.
The connected components of G are easily obtained by depth-rst search in O(jV j + jE j) time. To
nd the biconnected components of G, Tarjan's algorithm is used [18], which also runs in linear
time.
> G:=graph_complement(complete_graph(3,5,7))
an undirected unweighted graph with 15 vertices and 34 edges
> is_connected(G)
false
> C:=connected_components(G)
f[0; 1; 2]; [3; 4; 5; 6; 7]; [8; 9; 10; 11; 12; 13; 14]g
> G:=highlight_subgraph(G,induced_subgraph(G,C[1]))
an undirected unweighted graph with 15 vertices and 34 edges
> G:=highlight_subgraph(G,induced_subgraph(G,C[2]),magenta,cyan)
an undirected unweighted graph with 15 vertices and 34 edges
> draw_graph(G)
8
14

3

9
7

13

0

4

10

12

11

6

5

2

1

> H:=graph(trail(1,2,3,4,2),trail(4,5,6,7,5))
an undirected unweighted graph with 7 vertices and 8 edges

56

Graph properties

> draw_graph(H)
1
7

2

6

3

5

4

> is_biconnected(H)
false
> biconnected_components(H)
f[1; 2]; [2; 3; 4]; [4; 5]; [5; 6; 7]g

5.3.3. Graph rank
The command graph_rank is used for computing the rank of a graph.
graph_rank accepts one or two arguments, the input graph G(V ; E) and optionally a set of edges
S  E (by default S = E), and returns jV j ¡ k where k is the number of connected components of
the spanning subgraph of G with edge set S.
> G:=graph(%{[1,2],[3,4],[4,5]%})
an undirected unweighted graph with 5 vertices and 3 edges
> graph_rank(G)
3
> graph_rank(G,[[1,2],[3,4]])
2

5.3.4. Articulation points
The command articulation_points is used for obtaining the articulation points of a graph,
i.e. cut vertices, if any.
articulation_points accepts the input graph G(V ; E) as its only argument and returns the list
of articulation points of G. A vertex v 2 V is an articulation point of G if the subgraph H  G
induced by V n fvg is disconnected.
The articulation points of G are found by depth-rst serach in O(jV j + jE j) time [7].
> articulation_points(path_graph([1,2,3,4]))
[2; 3]
> articulation_points(cycle_graph(1,2,3,4))
[]

5.3.5. Strongly connected components
The command strongly_connected_components is used for decomposing a graph into strongly
connected components. A (di)graph H is strongly connected if for each pair (v; w) of distinct
vertices in H there is a (directed) path from v to w in H.

5.4 Trees

57

strongly_connected_components accepts the input graph G(V ; E) as its only argument and
returns the minimal partition fV1; V2; :::; Vk g of V such that the subgraph Gi  G induced by Vi is
strongly connected for each i = 1; 2; :::; k. The result is returned as a list of lists V1; V2; :::; Vk.
The strategy is to use Tarjan's algorithm for strongly connected components [18], which runs in
O(jV j + jE j) time.
Note that an undirected graph is strongly connected if and only if it is connected.

The command is_strongly_connected can be used to determine if the given graph G is strongly
connected. It accepts G as its only argument and returns true if G has exactly one strongly
connected component and false otherwise.
> G:=digraph([1,2,3],%{[1,2],[1,3],[2,3],[3,2]%})
a directed unweighted graph with 3 vertices and 4 arcs
> draw_graph(G)
1

3

2

> is_connected(G)
true
> is_strongly_connected(G)
false
> strongly_connected_components(G)
f[1]; [2; 3]g

5.3.6. Edge connectivity

5.4. Trees
5.4.1. Tree graphs
The command is_tree is used for determining if the particular graph is a tree. An undirected
graph G(V ; E) is a tree if jV j = jE j + 1 and G is connected.

is_tree accepts the input graph G as its only argument and returns true if G is a tree and false
otherwise.
The only expensive step in the algorithm is determining whether G is connected. The condition
jV j = jE j + 1 is checked rst, hence the algorithm runs in O(jV j) time.
> is_tree(complete_binary_tree(3))
true
> is_tree(cycle_graph(5))
false

58

Graph properties

5.4.2. Forest graphs
The command is_forest is used for determining if the particular graph is a forest, i.e. if its
connected components are all trees.
is_forest accepts the input graph G as its only argument and returns true if G is a forest and
false otherwise.
The only expensive step in the algorithm is the decomposition of G to connected components.
Therefore the algorithm runs in O(jV j + jE j) time.
> L:=[]:; for k from 10 to 30 do L.append(random_tree(k)); od:;
Done; Done
> G:=disjoint_union(op(L))
an undirected unweighted graph with 420 vertices and 399 edges
> is_connected(G)
false
> is_forest(G)
true

5.4.3. Height of a tree
The command tree_height is used for determining the height of a tree with respect to the specied
root node. The height of a tree is the length of the longest path in that tree that has the root node
as one of its endpoints.
tree_height accepts two arguments, the input tree graph G(V ; E) and a vertex r 2 V , which is
used as the root node. The command returns the height of G with respect to r.
The strategy is to start a depth-rst search from the root node and look for the deepest node.
Therefore the algorithm runs in O(jV j) time.
> G:=random_tree(1000)
an undirected unweighted graph with 1000 vertices and 999 edges
> r:=rand(1000)
296
> tree_height(G,r)
20

5.4.4. Lowest common ancestor of a pair of nodes
The command lowest_common_ancestor determines the lowest common ancestor (LCA) of a pair
of nodes in a tree, or for every element of a list of such pairs.
lowest_common_ancestor accepts two mandatory arguments, the input tree graph G(V ; E) and
the root node r 2 V . There are two possibilities for specifying the nodes to operate on: either the
nodes u; v 2 V are given as the third and the fourth argument, or a list of pairs of nodes in form
[[u1,v1],[u2,v2],...,[uk,vk]], where ui ; vi 2 V and ui =
/ vi for i = 1; 2; :::; k, is given as the
third argument. The command returns the LCA of u and v or the list containing LCA of every
pair of nodes ui ; vi for i = 1; 2; :::; k.
The strategy is to use Tarjan's oine LCA algorithm [19]. The implementation is simple and
uses the disjoint-set (union-nd) data structure. It runs in nearly linear time.

5.5 Distance

59

In the following example, the algorithm eciency is tested on a large random tree with 10000 nodes.
The lowest common ancestors for the list L cotaining 100 pairs of vertices, chosen at random, need
to be determined.
> G:=random_tree(10000)
an undirected unweighted graph with 10000 vertices and 9999 edges
3.562 sec

> V:=vertices(G):; L:=[]:; for k from 1 to 100 do L.append(rand(2,V)); od:;
Done; Done; Done
> lowest_common_ancestor(G,0,L):;
9.409 sec

5.5. Distance
5.5.1. Vertex distance
The command vertex_distance is used for computing the length of the shortest path between
two vertices of a graph.
vertex_distance accepts three arguments, the input graph G(V ; E), a vertex v 2 V called the
source and a vertex w 2 V called the target, or a list L  V of target vertices. The command returns
the distance between v and w as the number of edges in a shortest path from v to w, or the list
of distances if a list of target vertices is given.
> G:=graph("petersen") // Xcas mode
an undirected unweighted graph with 10 vertices and 15 edges
> vertex_distance(G,1,3)
2
> vertex_distance(G,1,[3,6,9])
[2; 1; 2]

5.5.2. All-pairs vertex distance
5.5.3. Diameter of a graph
5.5.4. Girth of a graph
The commands girth and odd_girth are used for computing the (odd) girth of an undirected
unweighted graph.
girth resp. odd_girth accepts the input graph G(V ; E) as its only argument and returns the girth
resp. odd girth of G. The (odd) girth of G is dened to be the length of the shortest (odd) cycle
in G. If there is no (odd) cycle in G, the command returns +1.
The strategy is to apply breadth-rst search from each vertex of the input graph. The runtime is
therefore O(jV jjE j).
> G:=graph("petersen")
an undirected unweighted graph with 10 vertices and 15 edges
> girth(G)

60

Graph properties

5
> G:=hypercube_graph(3)
an undirected unweighted graph with 8 vertices and 12 edges
> G:=subdivide_edges(G,["000","001"])
an undirected unweighted graph with 9 vertices and 13 edges
> girth(G)
4
> odd_girth(G)
5
> G:=complete_binary_tree(2)
an undirected unweighted graph with 7 vertices and 6 edges
> girth(G)
+1

5.6. Acyclic graphs
5.6.1. Checking if a graph is acyclic
The command is_acyclic is used for checking that the given digraph has no directed cycle. A
directed graph with no directed cycle is said to be acyclic.
is_acyclic accepts the input digraph G(V ; E) as its only argument and returns true if G is
acyclic and false otherwise.
The algorithm attempts to nd topological order for its vertices. If that succeeds, the graph is
acyclic, otherwise not. The algorithm runs in O(jV j + jE j) time.
> is_acyclic(digraph(trail(1,2,3,4,5)))
true
> is_acyclic(digraph(trail(1,2,3,4,5,2)))
false

5.6.2. Topological sorting
The command topologic_sort or topological_sort is used for nding a linear ordering of
vertices of an acyclic digraph which is consistent with the arcs of the digraph.
topologic_sort accepts the input graph G(V ; E) as its only argument and returns the list of
vertices of G in a particular order: a vertex u precedes a vertex v if u v 2 E, i.e. if there is an arc
from u to v.
Note that topological sorting is possible only if the input graph is acyclic. If this condition is not
met, topologic_sort returns an error. Otherwise, it nds the required ordering by applying
Kahn's algorithm [13], which runs in O(jV j + jE j) time.
> G:=digraph(%{[c,a],[c,b],[c,d],[a,d],[b,d],[a,b]%})
a directed unweighted graph with 4 vertices and 6 arcs
> is_acyclic(G)

5.7 Vertex matching

61

true
> topologic_sort(G)
[c; a; b; d]

5.6.3. st ordering
The command st_ordering is used for nding a st-orientation in an undirected biconnected graph
with respect to the given source and sink nodes.
st_ordering accepts three or four arguments: the input graph G(V ; E), a vertex s 2 V called
the source, a vertex t 2 V called the target or sink such that st 2 E and optionally an unassigned
identier D. The command returns the permutation  which denes a particular order of vertices
in V . That ordering denes the orientation for each edge e 2 E, which causes G to become acyclic
with a single source s and sink t. The ordering dened by  is the topological ordering of the
resulting digraph. If the optional argument D is given, the digraph is stored to it.
The orientation of e = u v 2 E is determined by the ordinals n and m of its endpoints u and v,
respectively, which are assigned by the permutation . If n < m, then u is the head and v is the
tail of the corresponding arc, and vice versa otherwise.
Note that the input graph G has a st-orientation if and only if G is biconnected. Furthermore, if
the latter is true, a st-orientation can be computed for any pair s; t 2 V such that st 2 E.
If the input graph is not biconnected, st_ordering returns an error. Otherwise, it applies the
algorithm of Even and Tarjan [5], which runs in O(jV j + jE j) time, to nd st-ordering for the
given pair of vertices.
> G:=graph(%{[a,b],[a,c],[a,d],[b,c],[b,d],[c,d]%})
an undirected unweighted graph with 4 vertices and 6 edges
> vertices(G)
[a; b; c; d]
> st_ordering(G,a,d,D)
[0; 2; 1; 3]
> draw_graph(D)
a

b

d

c

5.7. Vertex matching
5.7.1. Maximum matching
The command maximum_matching is used for nding maximum matching in undirected graphs.
maximum_matching accepts the input graph G(V ; E) as its only argument and returns a list of
edges e1; e2; :::; em 2 E such that ei and ej are not adjacent (i.e. have no common endpoints) for all
1 6 i < j 6 m, under condition that m is maximal. Edges ek for k = 1; :::; m represent the matched
pairs of vertices in G.

62

Graph properties

The command applies Edmonds' blossom algorithm5.1 [4], which nds maximum matching in
O(jV j2 jE j) time.
> G:=graph("octahedron")
an undirected unweighted graph with 6 vertices and 12 edges
> maximum_matching(G)
f[1; 3]; [6; 4]; [5; 2]g
> G:=graph("soccerball")
an undirected unweighted graph with 60 vertices and 90 edges
> draw_graph(highlight_edges(G,maximum_matching(G)),labels=false)

5.7.2. Maximum matching in bipartite graphs
If the input graph is bipartite, maximum matching can be found much faster by using the
bipartite_matching command which applies the algorithm of Hopcroft and Karp [10].
bipartite_matching accepts an undirected, unweighted bipartite graph G as its only argument
and returns a sequence containing two elements: the size of the maximum matching and the list
¡p

of edges connecting matched pairs of vertices. The algorithm runs in O
jV j jE j time.
> G:=graph("desargues")

an undirected unweighted graph with 20 vertices and 30 edges
> is_bipartite(G)
true
> n,M:=bipartite_matching(G)
10; f[0; 1]; [2; 3]; [4; 5]; [6; 7]; [8; 9]; [10; 13]; [11; 18]; [12; 15]; [14; 17]; [16; 19]g
> draw_graph(highlight_edges(G,M))

5.1. For a good description of the blossom algorithm, see https://en.wikipedia.org/wiki/Blossom_algorithm.

5.8 Cliques

63

5.8. Cliques
5.8.1. Clique graphs
The graph is a clique if it is complete, i.e. if each two of its vertices are adjacent to each other. To
check if a graph is a clique one can use the is_clique command.
is_clique accepts a graph G(V ; E) as its only argument and returns true if G is a complete
graph; else the returned value is false.
> K5:=complete_graph(5)
an undirected unweighted graph with 5 vertices and 10 edges
> is_clique(K5)
true
> G:=delete_edge(K5,[1,2])
an undirected unweighted graph with 5 vertices and 9 edges
> is_clique(G)
false

5.8.2. Triangle-free graphs
The command is_triangle_free is used for determining is the particular graph triangle-free. A
graph is triangle-free if it contains no clique of cardinality equal to 3, and hence no cliques with
cardinality greater than two.
triangle_free accepts the input graph G as its only argument and returns true if G is trianglefree and false otherwise.
The strategy is to check whether tr (A3) = 0, where A is the adjacency matrix of G. If the last
equality holds, the graph is triangle-free. This method is very fast as just one matrix multiplication
needs to be carried out completely. Additionally, the matrix A is sparse, so a large number of
vertices usually does not cause memory problems.
> is_triangle_free(graph("soccerball"))
true
> is_triangle_free(graph("tetrahedron"))
false

5.8.3. Maximal cliques
Each subgraph of a graph G(V ; E) which is itself a complete graph is called a clique in G. A clique
is maximal if it cannot be extended by adding more vertices from V to it. To count all maximal
cliques in a graph one can use the clique_stats command.
clique_stats accepts G as the only mandatory argument. If it is the only argument given, the
command returns a list of pairs, each pair consisting of two integers: clique cardinality k (rst) and
the number nk > 0 of k-cliques in G (second). Therefore, the sum of second members of all returned
pairs is equal to the total count of all maximal cliques in G. As an optional second argument one
may give a positive integer k or an interval m .. n with integer bounds. In the rst case only the
number of k-cliques for the given k is returned; in the second case, only cliques with cardinality
between m and n (inclusive) are counted.

64

Graph properties

The strategy used to nd all maximal cliques is a variant of the algorithm of Bron and Kerbosch
as described in [20]. Its worst-case running time is O(3jV j/3). However, the performance is usually
almost instantaneous for graphs with 100 vertices or less.
> G:=random_graph(50,0.5)
an undirected unweighted graph with 50 vertices and 588 edges
> clique_stats(G)
0

> G:=random_graph(100,0.5)

B
B
B
B
B
B
@

3
4
5
6
7
8

14
185
370
201
47
5

1
C
C
C
C
C
C
A

an undirected unweighted graph with 100 vertices and 2461 edges
> clique_stats(G,5)
3124
> G:=random_graph(500,0.25)
an undirected unweighted graph with 500 vertices and 31257 edges
> clique_stats(G,5..7)
0

1
5 153444
@ 6 18486 A
7 355

1.218 sec

5.8.4. Maximum clique
The largest maximal clique in the graph G(V ; E) is called maximum clique. The command maximum_clique can be used to nd one in the given graph.
maximum_clique accepts the graph G as its only argument and returns maximum clique in G
as a list of vertices. The clique may subsequently be extracted from G using the command
induced_subgraph.
The strategy used to nd maximum clique is an improved variant of the classical algorithm by
Carraghan and Pardalos developed by Östergård in [15].
In the following examples, the maximum cliques were obtained almost instantly.
> G:=sierpinski_graph(5,5)
an undirected unweighted graph with 3125 vertices and 7810 edges
> maximum_clique(G)
[1560; 1561; 1562; 1563; 1564]
> G:=random_graph(300,0.3)
an undirected unweighted graph with 300 vertices and 13380 edges
> maximum_clique(G)
[46; 64; 144; 183; 208; 241; 244; 261]
> G:=graph_complement(complete_graph(4,3))

5.8 Cliques

65

an undirected unweighted graph with 7 vertices and 9 edges
> cliq:=maximum_clique(G)
[0; 1; 2; 3]
> draw_graph(highlight_subgraph(G,induced_subgraph(G,cliq)))

5.8.5. Minimum clique cover
The minimum clique cover for the graph G(V ; E) is the smallest set S = fC1; C2; :::; Ck g of cliques in
G such that for every v 2 V there exists i 6 k such that v 2 Ci. In Giac, such cover can be obtained
by calling the clique_cover command.
clique_cover accepts graph G as its mandatory argument and returns the smallest possible cover.
Optionally, a positive integer may be passed as the second argument. In that case the requirement
that k is less or equal to the given integer is set. If no such cover is found, clique_cover returns
empty list.
The strategy is to nd the minimal vertex coloring in the complement Gc of G (note that these
two graphs share the same set of vertices). Each set of equally colored vertices in Gc corresponds
to a clique in G. Therefore, the color classes of Gc map to the elements C1; :::; Ck of the minimal
clique cover in G.
There is a special case in which G is triangle-free, which is treated separately. Such a graph G
contains only 1- and 2-cliques; in fact, every clique cover in G consists of a matching M together
with the singleton cliques (i.e. the isolated vertices which remain unmatched). The total number
of cliques in the cover is equal to jV j ¡ jM j, hence to nd the minimal cover one just needs to nd
maximum matching in G, which can be done in polynomial time.
> G:=random_graph(30,0.2)
an undirected unweighted graph with 30 vertices and 88 edges
> clique_cover(G)
f[0; 2; 7]; [1; 3]; [4; 10; 13; 14]; [5; 6]; [8; 15; 26]; [9; 22; 25]; [11; 16]; [12; 17; 23]; [18; 20; 24]; [19; 28];
[21; 27; 29]g

To nd minimal clique cover in the truncated icosahedral graph it suces to nd maximum
matching, since it is triangle-free.
> clique_cover(graph("soccerball"))
f[1; 2]; [3; 16]; [4; 5]; [6; 7]; [8; 49]; [9; 10]; [11; 12]; [13]; [14; 15]; [17; 18]; [19; 20]; [21; 22]; [23]; [24; 25];
[26; 30]; [27; 28]; [29; 48]; [31; 32]; [33; 46]; [34; 35]; [36; 37]; [38; 39]; [40]; [41; 42]; [43; 44]; [45; 47];
[50]; [51; 52]; [53; 54]; [55; 57]; [56; 60]; [58; 59]g
The vertices of Petersen graph can be covered with ve, but not with three cliques.
> clique_cover(graph("petersen"),3)
[]
> clique_cover(graph("petersen"),5)

66

Graph properties

f[0; 1]; [2; 3]; [4; 9]; [5; 7]; [6; 8]g

5.9. Vertex coloring
To color vertices of a graph G(V ; E) means to assign to each vertex v 2 V a positive integer.
Each integer represents a distinct color. The key property of a graph coloring is that the colors
of adjacent vertices must dier from one another. Two dierent colorings of G may use dierent
number of colors.

5.9.1. Greedy coloring
The command greedy_color is used for coloring vertices of a graph in a greedy fashion.
greedy_color accepts one mandatory argument, the input graph G. Optionally, a permutation p
of order jV j may be passed as the second argument. Vertices are colored one by one in the order
specied by p (or in the default order if p is not given) such that each vertex gets the smallest
available color. The list of vertex colors is returned in the order of vertices(G).
Generally, dierent choices of permutation p produce dierent colorings. The total number of
dierent colors may not be the same each time. The complexity of the algorithm is O(jV j + jE j).
> G:=graph("petersen")
an undirected unweighted graph with 10 vertices and 15 edges
> greedy_color(G)
[1; 2; 1; 2; 3; 2; 1; 3; 3; 2]
> L:=greedy_color(G,randperm(10))
[1; 2; 1; 4; 3; 4; 1; 3; 2; 2]
Observe that a dierent number of colors is obtained by executing the last command line. To
display the colored graph, input:
> draw_graph(highlight_vertex(G,vertices(G),L),labels=false)

The rst six positive integers are always mapped to the standard Xcas colors, as indicated in
Table 5.1. Note that the color 0 (black) and color 7 (white) are swapped; a vertex with color 0 is
uncolored or white, and vertex with color 7 is black. Also note that Xcas will map the numbers
greater than 7 to colors too, but the number of available colors is limited.

5.9.2. Minimal coloring
The vertex coloring of G is minimal (or optimal) if the smallest possible number of colors is used.
To obtain such a coloring use the command minimal_vertex_coloring.
minimal_vertex_coloring accepts one mandatory argument, the graph G. Optionally, a symbol
sto may be passed as the second argument. The command returns the vertex colors in order of
vertices(G) or, if the second argument is given, stores the colors as vertex attributes and returns
the modied copy of G.

5.9 Vertex coloring

67

value
1
2
3
4
5
6
7

color
red
green
yellow
blue
magenta
cyan
black

Table 5.1. interpretation of abstract vertex/edge colors in Xcas

Giac requires the GLPK library5.2 to solve the minimal vertex coloring problem (MVCP), which is
converted to the equivalent integer linear programming problem and solved by using the branchand-bound method with specic branch/backtrack techniques [3]. Lower and upper bounds for the
number of colors n are obtained by nding a maximal clique (n cannot be lower than its cardinality)
and by using the heuristic proposed by Brélaz in [1] (which will use at least n colors), respectively.
The algorithm is usually fast for graphs up to 40 vertices and for sparse graphs in general. For
larger, denser graphs (e.g. with edge density around 0.5, which are the most dicult ones) one may
have to wait for several minutes, even hours, and sometimes for a practically innite time. Note that
MVCP is a NP-hard problem, which means that no polynomial (i.e. ecient) algorithm is known.
In the following example, the Grotzsch graph is colored with minimal number of colors by rst
nding the coloring and then assigning it to the graph by using the highlight_vertex command.
> G:=graph("grotzsch")
an undirected unweighted graph with 11 vertices and 20 edges
> coloring:=minimal_vertex_coloring(G)
[4; 2; 3; 1; 1; 4; 1; 3; 2; 1; 2]
> draw_graph(highlight_vertex(G,vertices(G),coloring),labels=false)

To illustrate the combinatorial explosion which characterizes MVCP one can use the following
example. Note that nding an optimal coloring in G is equivalent to nding the minimal clique
cover in its complement Gc.
First, a random graph G with 40 vertices and edge density 0.5 is generated. Such a graph is
considered to be relatively small.
> G:=random_graph(40,0.5)
an undirected unweighted graph with 40 vertices and 393 edges
The chromatic number is computed by solving MVCP via minimal_vertex_coloring in less than
a second.
> chromatic_number(G)
8
273 msec
5.2. GNU Linear Programming Kit, https://www.gnu.org/software/glpk/

68

Graph properties

Next, all maximal cliques in Gc are counted using the clique_stats command.
> S:=clique_stats(graph_complement(G))
0
1
3 5
B 4 66 C
B
C
B 5 238 C
B
C
@ 6 89 A
7 3
> n:=sum(col(S,1))

401
To obtain the minimal coloring, a naive algorithm must check P
if a combination
of 2; 3; :::; 8 maximal
 
8
cliques forms a cover in Gc. In the worst case it will check k=2 nk combinations, the number
which is computed by the next command line.
> sum(comb(n,k),k=2..8)
15776262844602110
The magnitude of the above result (1.6  1017) indicates that the algorithm would run practically
forever. (In particular, assuming that the algorithm requires 1 s to test one combination of
cliques, the runtime is about 5070 years.) The fact that chromatic_number required only quarter
of a second to obtain minimal coloring indicates that the implemented algorithm is far more
sophisticated than a simple brute-force approach.
Note that solving MVCP for dierent graphs of exactly the same size (but which do not share the
same edge structure) may take quite dierent time in each instance. For example, the time required
to color a graph with 50 vertices and edge density 0.5 may take any value between six seconds and
six minutes. Also note that some graphs will take exponential time (that is, forever) to obtain
the coloring. Table 5.2 shows the runtimes (in seconds) of solving MVCP for random graphs with
d
10 k vertices and edge density 10 for k = 1; 2; :::; 7 and d = 1; 2; :::; 5, using Intel i3-7130U processor
at 2.70 GHz. For each pair (k; d), ten graphs were generated and the average runtime was recorded
in the table.

5.9.3. Chromatic number
The command chromatic_number is used for exact computation and approximation of the chromatic number of a graph.
chromatic_number accepts one mandatory argument, the input graph G(V ; E), and optionally a
second argument. To obtain only upper and lower bound for the chromatic number (which is much
faster than computing exactly) the option approx or interval should be passed as the second
argument. Alternatively, an unassigned identier is passed as the second argument; in that case
the corresponding coloring will be stored to it in form of a list of colors of the individual vertices,
ordered as in vertices(G).
The command returns the chromatic number G of the graph G in the case of exact computation.
If the option approx or interval is given, an interval lb..ub is returned, where lb is the best
lower bound and ub the best upper bound for G found by the algorithm.
The strategy is call minimal_vertex_coloring in the case of exact computation. When approximating the chromatic number, the algorithm will establish the lower bound by searching for
maximum clique. The timeout for this operation is set to 5 seconds as it can be time consuming. If
the maximum clique is not found after that time, the largest clique found is used. Then, an upper
bound is established by by using the heuristic proposed by Brélaz in [1]. Obtaining the bounds
for G is usually very fast, but the dierence between the bounds grows with jV j.
Unless the input graph is sparse enough, the algorithm slows down considerably for jV j > 40.

5.9 Vertex coloring

number of vertices
10
20
30
40
50

69

0.1
0.0008892
0.0014682
0.0021163
0.0252134
0.130089

0.2
0.0010818
0.00378
0.0173315
0.177707
1.83819

edge density
0.3
0.4
0.0006116
0.0005825
0.0038329
0.0077918
0.0372468
0.111016
0.626175
1.67746
17.3564
120.181

0.5
0.0006331
0.0067932
0.143657
2.31473
246.161

Table 5.2. average runtime of the algorithm for minimal coloring (in seconds)

> chromatic_number(graph("grotzsch"),cols)
4
> cols
[4; 2; 3; 1; 1; 4; 1; 3; 2; 1; 2]
> G:=random_graph(30,0.75)
an undirected unweighted graph with 30 vertices and 313 edges
> chromatic_number(G)
10
> G:=random_graph(300,0.05)
an undirected unweighted graph with 300 vertices and 2196 edges
> chromatic_number(G,approx)
4..7

5.9.4. k-coloring
The command is_vertex_colorable is used for determining whether the vertices of a graph can
be colored with at most k colors.
is_vertex_colorable accepts two or three arguments: the input graph G(V ; E), a positive integer
k and optionally an unassigned identier. The command returns true if G can be colored using
at most k colors and false otherwise. If an identier is given, a coloring using at most k colors is
stored to it as a list of vertex colors, in the order of vertices(G).
The strategy is to rst apply a simple greedy coloring procedure which runs in linear time. If
the number of required colors is greater than k, the heuristic proposed by Brélaz in [1] is used,
which runs in quadratic time. If the number of required colors is still larger than k, the algorithm
attempts to nd the chromatic number G using k as the upper bound in the process.
> G:=graph("grotzsch")
an undirected unweighted graph with 11 vertices and 20 edges
> is_vertex_colorable(G,3)
false
> is_vertex_colorable(G,4)
true
> G:=random_graph(70,0.2)
an undirected unweighted graph with 70 vertices and 469 edges
> chromatic_number(G,approx)

70

Graph properties

5..6
> is_vertex_colorable(G,5)
false
818 msec

From the results of the last two command lines it follows that G = 6. Finding G by utilizing the
next command line is simpler, but requires much more time.
> chromatic_number(G)
6
92.7 sec

5.10. Edge coloring

Chapter 6
Traversing graphs
6.1. Walks and tours
6.1.1. Eulerian graphs
The command is_eulerian is used for determining whether the given graph is an Eulerian graph
and for nding Eulerian trails in such graphs.
is_eulerian accepts one or two arguments, the input graph G(V ; E) and optionally an unassigned
identier T , and returns true if G is Eulerian and false otherwise. If T is given, the corresponding
Eulerian trail is stored to it.
The graph G is Eulerian if it has a trail covering all its edges. Such a trail is called Eulerian trail .
An Eulerian trail may be closed, in which case it is called Eulerian cycle. Note that every edge
e 2 E must be visited, i.e. strolled through, exactly once. However, the edge endpoints (i.e. the
vertices in G) may be visited more than once.
The strategy is to apply Hierholzer's algorithm for nding an Eulerian path [8]. It works by
covering one cycle at a time in the input graph. The required time is O(jE j).
> is_eulerian(complete_graph(4))
false
> purge(T):; is_eulerian(complete_graph([1,2,3,4,5]),T); T
Done; true; [1; 2; 3; 4; 1; 5; 2; 4; 5; 3; 1]

6.1.2. Hamiltonian graphs

6.2. Optimal routing
6.2.1. Shortest paths in unweighted graphs
The command shortest_path is used to nd the shortest path between two vertices in an undirected unweighted graph.
shortest_path accepts three arguments: a graph G(V ; E), the source vertex s 2 V and the target
vertex t 2 V or a list T of target vertices. The shortest path from source to target is returned. If more
targets are specied, the list of shortest paths from the source to each of these vertices is returned.
The strategy is to run breadth-rst traversal on the graph G starting from the source vertex s.
The complexity of the algorithm is therefore O (jV j + jE j).
> G:=graph("dodecahedron")
an undirected unweighted graph with 20 vertices and 30 edges
> shortest_path(G,1,16)
[1; 6; 11; 16]

71

72

Traversing graphs

> paths:=shortest_path(G,1,[16,19])
f[1; 6; 11; 16]; [1; 5; 10; 14; 19]g
> H:=highlight_trail(G,paths,[red,green])
an undirected unweighted graph with 20 vertices and 30 edges
> draw_graph(H)
1
6
15

11

5

2

16
20

10

7
17

19
14

12
18
13
9

4

8
3

6.2.2. Cheapest paths in weighted graphs
The command dijkstra is used to nd the cheapest path between two vertices of an undirected
weighted graph.
dijkstra accepts two or three arguments: a weighted graph G(V ; E) with nonnegative weights, a
vertex s 2 V and optionally a vertex t 2 V or list T of vertices in V . It returns the cheapest path
from s to t or, if more target vertices are given, the list of such paths to each target vertex t 2 T ,
computed by Dijkstra's algorithm in O(jV j2) time. If no target vertex is specied, all vertices in
V n fsg are assumed to be targets.
A cheapest path from s to t is represented with a list [[v1,v2,...,vk],c] where the rst element
consists of path vertices with v1 = s and vk = t, while the second element c is the weight (cost) of
that path, equal to the sum of weights of its edges.
>

6.2.3. Traveling salesman problem

6.3. Spanning trees
6.3.1. Constructing a spanning tree
The command spanning_tree accepts one or two arguments, an undirected graph G and optionally
a vertex r 2 V . It returns the spanning tree T of G rooted in r or, if none is given, in the rst
vertex in the list V , obtained by depth-rst traversal in O(jV j + jE j) time.

6.3.2. Minimal spanning tree
The command minimal_spanning_tree accepts an undirected graph G(V ; E) as its only argument
and returns its minimal spanning tree obtained by Kruskal's algorithm in O(jE j log jV j) time.

6.3.3. Counting all spanning trees
The command number_of_spanning_trees is used for counting all spanning trees in a graph.
number_of_spanning_trees accepts the input graph G(V ; E) as its only argument and returns
the total number n of mutually dierent spanning trees in G.

6.3 Spanning trees

73

The strategy is based on Theorem 2.2.12 (Matrix Tree Theorem) in [24], page 86. First the adjacency matrix A and the degree sequence  of G are obtained. Then the matrix B =  ¡ A is
computed, where  is the diagonal matrix of order jV j corresponding to . The last row and the
last column of B are popped out, yielding the matrix C of order jV j ¡ 1. Now n = det C.
> number_of_spanning_trees(graph("octahedron"))
384
> number_of_spanning_trees(graph("dodecahedron"))
5184000
> number_of_spanning_trees(hypercube_graph(4))
42467328
> number_of_spanning_trees(graph("soccerball"))
375291866372898816000

Chapter 7
Visualizing graphs
7.1. Drawing graphs by using various methods
To visualize a graph use the draw_graph command. It is capable to produce a drawing of the given
graph using one of the several built-in methods.

7.1.1. Overview
draw_graph accepts one or two arguments, the mandatory rst one being the graph G(V ; E). This
command assigns 2D or 3D coordinates to each vertex v 2 V and produces a visual representation
of G based on these coordinates. The second (optional) argument is a sequence of options. Each
option is one of the following:


labels=true or false: controls the visibility of vertex labels and edge weights (by default
true, i.e. the labels and weights are displayed)



spring: draw the graph G using a multilevel force-directed algorithm



tree[=r or [r1,r2,...]]: draw the tree or forest G, optionally specifying root nodes for
each tree



bipartite: draw the bipartite graph G keeping the vertex partitions separated



circle[=L] or convexhull[=L]: draw the graph G by setting the hull vertices from list
L  V (assuming L = V by default) on the unit circle and all other vertices in origin,
subsequently applying a force-directed vertex placement algorithm to generate the layout
while keeping the hull vertices xed



planar or plane: draw the planar graph G using a force-directed algorithm



plot3d: draw the connected graph G as if the spring option was enabled, but with vertex
positions in 3D instead of 2D



any unassigned identier P : when given, the vertex coordinates will be stored to it in form
of a list

The style options spring, tree, circle, planar and plot3d cannot be mixed, i.e. at most one can
be specied. The option labels may be combined with any of the style options. Note that edge
weights will not be displayed when using plot3d option when drawing a weighted graph.
When no style option is specied, the algorithm rst checks if the graph G is a tree or if it is
bipartite, in which cases it is drawn accordingly. Otherwise, the graph is drawn as if the option
circle was specied.
Tree, circle and bipartite drawings can be obtained in linear time with a very small overhead,
allowing graphs to be drawn quickly no matter the size. The force-directed algorithms are more
expensive and operating in the time which is quadratic in the number of vertices. Their performance
is, nevertheless, practically instantaneous for graphs with several hundreds of vertices (or less).

7.1.2. Drawing disconnected graphs
When the input graph has two or more connected components, each component is drawn separately
and the drawings are subsequently arranged such that the bounding box of the whole drawing has
the smallest perimeter under condition that as little space as possible is wasted inside the box.
75

76

Visualizing graphs

For example, the command lines below draw a sparse random planar graph.
> G:=random_planar_graph(100,0.9,0)
an undirected unweighted graph with 100 vertices and 74 edges
> draw_graph(G,planar)

7.1.3. Spring method
When the option spring is specied, the input graph is drawn using the force-directed algorithm
described in [11] (for an example of such a drawing see Figure 4.1). The idea, originally due
to Fruchterman and Reingold [6], is to simulate physical forces in a spring-electrical model
where the vertices and edges represent equally charged particles and springs connecting them,
respectively.
In a spring-electrical model, each vertex is being repulsed by every other vertex with a force
inversely proportional to the distance between them. At the same time, it is attracted to each of its
neighbors with a force proportional to the square of the distance. Assuming that xv is the vector
representing the position of the vertex v 2 V , the total force Fv applied to v is equal to
Fv =

X

w2V nfvg

¡

X
C K2
(xv ¡ xw) +
2
kxv ¡ xw k

w2N (v)

kxv ¡ xw k
(xv ¡ xw);
K

where N (v) is the set of neighbors of v and C, K are certain positive real constants (actually, K
may be any positive number, it aects only the scaling of the entire layout). Applying the forces
iteratively and updating vertex positions in each iteration (starting from a random layout) leads the
system to the state of minimal energy. By applying a certain cooling scheme to the model which
cuts down the force magnitude in each iteration. the layout freezes after a number of iterations
large enough to achieve the minimal energy state.
The force-directed method is computationally expensive and for larger graphs the pleasing layout
cannot be obtained most of the time since the algorithm, starting with a random initial layout,
gets easily stuck in the local energy minimum (ideally, the vertex positions should settle in the
global minimal energy constellation). To avoid this a multilevel scheme is applied. The input graph
is iteratively coarsened, either by removing the vertices from a maximal independent vertex set
or contracting the edges of a maximal matching in each iteration. Each coarsening level is then
processed by the force-directed algorithm, starting from the deepest (coarsest) one and lifting the
obtained layout to the rst upper level, using it as the initial layout for that level. The lifting is
achieved by using the prolongation matrix technique described in [12]. To support drawing of large
graphs (with 1000 vertices or more), the matrices used in the lifting process are stored as sparse
matrices. The multilevel algorithm is signicantly faster than the original, single-level one and
usually produces better results.
Graph layouts obtained by using force-directed method have a unique property of reecting symmetries in the design of the input graph, if any. Thus the drawings become more appealing and
illustrate the certain properties of the input graph better. To make the symmetry more prominent,
the drawing is rotated such that the axis, with respect to which the layout exhibits the largest
symmetry score, becomes vertical. As the symmetry detection is in general very computationally
expensiveup to O(jV j7) when using the symmetry measure of Purchase [23], for examplethe
algorithm deals only with the convex hull and the barycenter of the layout, which may not always
be enough to produce the optimal result. Nevertheless, this approach is very fast and seems to
work most of the time for graphs with a high level of symmetry (for example the octahedral graph).

7.1 Drawing graphs by using various methods

77

For example, the following command lines produce a drawing of the tensor product of two graphs
using the force-directed algorithm.
> G1:=graph(trail(1,2,3,4,5,2))
an undirected unweighted graph with 5 vertices and 5 edges
> G2:=star_graph(3)
an undirected unweighted graph with 4 vertices and 3 edges
> G:=tensor_product(G1,G2)
an undirected unweighted graph with 20 vertices and 30 edges
> draw_graph(G,spring,labels=false)

The following command lines demonstrate drawing of a much larger graph.
> S:=sierpinski_graph(5,4)
an undirected unweighted graph with 1024 vertices and 2046 edges
> draw_graph(S,spring)

Note that vertex labels are automatically suppressed because of the large number of vertices. On
our system, the algorithm took less than 2 seconds to produce the layout.
The spring method is also used for creating 3D graph layouts, which are obtained by passing the
option plot3d to the draw_graph command.
> draw_graph(graph("soccerball"),plot3d,labels=false)

> G1:=graph("icosahedron"):; G2:=graph("dodecahedron"):;
Done; Done

78

Visualizing graphs

> G1:=highlight_edges(G1,edges(G1),red)
an undirected unweighted graph with 12 vertices and 30 edges
> G2:=highlight_edges(G2,edges(G2),magenta)
an undirected unweighted graph with 20 vertices and 30 edges
> G:=disjoint_union(G1,G2)
an undirected unweighted graph with 32 vertices and 60 edges
> draw_graph(G,plot3d,labels=false)
z
x

y

7.1.4. Drawing trees
When the tree[=r] option is specied and the input graph G is a tree (and r 2 V ), it is drawn using
a fast but simple node positioning algorithm inspired by the well-known algorithm of Walker [22],
using the rst vertex (or the vertex r) as the root node. When drawing a rooted tree, one usually
requires the following aesthetic properties [2].
A1. The layout displays the hierarchical structure of the tree, i.e. the y-coordinate of a node is
given by its level.
A2. The edges do not cross each other.
A3. The drawing of a sub-tree does not depend on its position in the tree, i.e. isomorphic subtrees are drawn identically up to translation.
A4. The order of the children of a node is displayed in the drawing.
A5. The algorithm works symmetrically, i.e. the drawing of the reection of a tree is the reected
drawing of the original tree.
The algorithm implemented in Giac generally satises all the above properties but A3. Instead,
it tries to spread the inner sub-trees evenly across the available horizontal space. It works by
organizing the structure of the input tree into levels by using depth-rst search and laying out
each level subsequently, starting from the deepest one and climbing up to the root node. In the
end, another depth-rst traversal is made, shifting the sub-trees horizontally to avoid intersections
between their edges. The algorithm runs in O(jV j) time and uses the minimum of horizontal space
to draw the tree with respect to the specied root node r.
For example, the following command line produces the drawing of a random tree on 100 nodes.
> draw_graph(random_tree(100))

7.1 Drawing graphs by using various methods

79

7.1.5. Drawing planar graphs
The algorithm implemented in Giac which draws planar graphs uses augmentation techniques
to extend the input graph G to a graph G 0, which is homeomorphic to some triconnected graph,
by adding temporary edges. The augmented graph G 0 is then drawn using Tutte's barycentric
method [21], a force-directed algorithm which puts each vertex in the barycenter of its neighbors.
It is guaranteed that a (non-strict) convex drawing will be produced, without edge crossings. In
the end, the duplicate of the outer face and the temporary edges inserted during the augmentation
stage are removed.
Tutte's algorithm requires that the vertices of the chosen outer face are initially xed somewhere
the boundary of a convex polygon. In addition, to produce a more exible layout, the outer face is
duplicated such that the subgraph induced by the vertices on both the outer face and its duplicate
is a prism graph. Then only the duplicates of the outer face vertices are xed, allowing the outer
face itself to take a more natural shape. The duplicate of the outer face is removed after a layout
is produced.
The augmentation process consists of two parts. Firstly, the input graph G is decomposed into
biconnected components called blocks using the depth-rst search (see [7], page 25). Each block is
then decomposed into faces (represented by cycles of vertices) using Demoucron's algorithm (see
[7], page 88, with a correction proposed in [14]). Embeddings obtained for each blocks are then
combined by adding one temporary edge for each articulation point, joining the two corresponding
blocks. Figure 7.1 shows the outer faces of two blocks B1 and B2, connected by an articulation
point (cut vertex). The temporary edge (shown in blue) is added to join B1 and B2 into a single
block. After folding up the tree of blocks, the algorithm picks the largest face in the resulting
biconnected graph to be the outer face of the planar embedding.
The second part of the augmentation process consists of recursively decomposing each non-convex
inner face into several convex polygons by adding temporary edges. An inner face f = (v1; :::; vn)
is non-convex if there exist k and l such that 1 6 k < l ¡ 1 < n and either vk vl 2 E, in which case
the edge vk vl is a chord (see Figure 7.2 for an example) or there exists a face g = (w1; w2; :::; vk ; :::;
vl ; :::; wm¡1; wm) such that the vertices vk+1; :::; vl¡1 are not contained in g (see Figure 7.3 for an
example). In Figures 7.1, 7.2 and 7.3, the temporary edges added by the algorithm are drawn in
green.

temp. edge
B1

chord

f
vl
vk

B2

Fig. 7.1. joining two blocks

f

Fig. 7.2. a chorded face

g

Fig. 7.3. two adjacent faces

This method of drawing planar graphs operates in O(jV j2) time. Nevertheless, it is quite fast
for graphs up to 1000 vertices, usually producing results in less than a second. The drawback of
this method is that it sometimes creates clusters of vertices which are very close to each other,
resulting in a very high ratio of the area of the largest inner face to the area of the smallest inner
face. However, if the result is not satisfactory, one should simply redraw the graph and repeat the
process until a better layout is found. The planar embedding will in general be dierent each time.
Another drawback of this method is that sparse planar graphs are sometimes drawn poorly.
The following example shows that the above described improvement of the barycentric method
handles non-triconnected graphs well.

80

Visualizing graphs

> G:=graph(trail(1,2,3,4,5,6,7,8,9,10,1),trail(11,12,6,11,1,12))
an undirected unweighted graph with 12 vertices and 15 edges
> draw_graph(G,planar)

Note that the inner diamond-like shape in the above drawing would end up attenedmaking the
two triangular faces invisibleif the input graph was not augmented. It is so because the vertices
with labels 11 and 12 are attracted to each other (namely, the two large faces are inating
themselves to become convex), causing them to merge eventually.
In the following example the input graph G is connected but not biconnected (it has two articulation points). It is obtained by removing a vertex from the Sierpi«ski triangle graph ST33. Note
that the syntax mode is set to Xcas in this example, so the rst vertex label is zero.
> G:=sierpinski_graph(3,3,triangle)
an undirected unweighted graph with 15 vertices and 27 edges
> G:=delete_vertex(G,3)
an undirected unweighted graph with 14 vertices and 23 edges
> draw_graph(G,planar,labels=false)

In the above example, several redraws were required to obtain a good planar embedding.

7.1.6. Circular graph drawings
The drawing method selected by specifying the option circle=L or convexhull=L when calling
draw_graph on a triconnected graph G(V ; E), where L  V is a set of vertices in G, uses the
following strategy. First, positions of the vertices from L are xed so that they form a regular
polygon on the unit circle. Other vertices, i.e. all vertices from V n L, are placed in origin. Then
an iterative force-directed algorithm [16], similar to Tutte's barycentric method, is applied to
obtain the nal layout.
This approach gives best results for symmetrical graphs such as generalized Petersen graphs. In
addition, if the input graph is planar, the drawing will also be planar (there is a possibility, however,
that some very short edges may cross each other as the number of force update iterations is limited).
In the following example the Sierpi«ski graph S42 is drawn using the above method. Note that the
command lines below are executed in Xcas mode.
> G:=sierpinski_graph(2,4)
an undirected unweighted graph with 16 vertices and 30 edges
> draw_graph(G,circle=[0,1,4,5,7,13,15,14,11,10,8,2])

7.2 Custom vertex positions

81

7.2. Custom vertex positions
7.2.1. Setting vertex positions
The command set_vertex_positions is used to assign custom coordinates to vertices of a graph
to be used when drawing the graph.
set_vertex_positions accepts two arguments, the graph G(V ; E) and the list L of positions to be
assigned to vertices in order of vertices(G). The positions may be complex numbers, lists of coordinates or points (geometrical objects created with the command point). set_vertex_positions
returns the copy G 0 of G with the given layout stored in it.
Any subsequent call to draw_graph with G 0 as an argument and without specifying the drawing
style will result in displaying vertices at the stored coordinates. However, if a drawing style is
specied, the stored layout is ignored (although it stays stored in G 0).
> G:=digraph([1,2,3,4,5],%{[1,2],[2,3],[3,4],[2,5]%})
a directed unweighted graph with 5 vertices and 4 arcs
> draw_graph(G,circle)

> H:=set_vertex_positions(G,[[0,0],[0.5,0],[1.0,0],[1.5,0],[0.5,1]])
a directed unweighted graph with 5 vertices and 4 arcs
> draw_graph(H)

7.2.2. Generating vertex positions
Vertex positions can be generated for a particular graph G by using the draw_graph command with
the additional argument P which should be an unassigned identier. After the layout is obtained,
it will be stored to P as a list of positions (complex numbers for 2D drawings or points for 3D
drawings) for each vertex in order of vertices(G).

82

Visualizing graphs

This feature combines well with the set_vertex_positions command, as when one obtains the
desired drawing of the graph G by calling draw_graph, the layout coordinates can be easily stored
to the graph for future reference. In particular, each subsequent call of draw_graph with G as an
argument will display the stored layout. The example below illustrates this property by setting a
custom layout to the octahedral graph.
> G:=graph("octahedron")
an undirected unweighted graph with 6 vertices and 12 edges
> draw_graph(G)

> draw_graph(G,P,spring):;
Now P contains vertex coordinates, which can be permanently stored to G:
> G:=set_vertex_positions(G,P)
an undirected unweighted graph with 6 vertices and 12 edges
> draw_graph(G)

It should be noted that, after a particular layout is xed, it stays valid when some edges or vertices
are removed or when an edge is contracted. The stored layout becomes invalid only if a new vertex
is added to the graph (unless its position is specied by set_vertex_attribute upon the creation)
or if the position attribute of an existing vertex is discarded.

7.3. Highlighting parts of a graph
7.3.1. Highlighting vertices
The command highlight_vertex is used for changing color of one or more vertices in a graph.
highlight_vertex accepts two or three arguments: the graph G(V ; E), a vertex v 2 V or a list
L  V of vertices and optionally the new color (or a list of colors) for the selected vertices (the
default color is green). It returns a modied copy of G in which the specied vertices are colored
with the specied color.
> G:=graph("dodecahedron")
an undirected unweighted graph with 20 vertices and 30 edges
> L:=maximum_independent_set(G)

7.3 Highlighting parts of a graph

83

[2; 4; 6; 12; 13; 10; 16; 19]
> draw_graph(highlight_vertex(G,L))

7.3.2. Highlighting edges and trails
To highlight an edge or a set of edges in a graph, use the highlight_edges command. If the edges
form a trail, it is usually more convenient to use the highlight_trail command (see below).
highlight_edges accepts two or three arguments: the graph G(V ; E), an edge e or a list of edges
L and optionally the new color (or a list of colors) for the selected edges (the default color is red).
It returns a modied copy of G in which the specied edges are colored with the specied color.
> M:=maximum_matching(G)
f[1; 2]; [5; 4]; [6; 11]; [3; 8]; [7; 12]; [9; 13]; [10; 15]; [14; 19]; [16; 17]g
> draw_graph(highlight_edges(G,M))

> S:=spanning_tree(G)
an undirected unweighted graph with 20 vertices and 19 edges
> draw_graph(highlight_edges(G,edges(S),magenta))

highlight_trail accepts two or three arguments: the input graph G(V ; E), a list L  V or a
list [L1,L2,...,Lk] of such lists (each list represents the vertices of the corresponding trail) and
optionally a positive integer c or a list of positive integers [c1,c2,...,ck]. The command returns
the copy of G in which edges between consecutive vertices in L are highlighted with color c (by
default red) or the trail represented by Li is highlighted with color ci for i = 1; 2; :::; k.
Note that a trail can cross itself, which means that the elements of L are not required to be unique.
> draw_graph(highlight_trail(G,[6,15,20,19,18,17,16,11,7,2,3,8,13,9,14,10]))

84

Visualizing graphs

1
6
15
5

11
2

20
16

10
19

7
17

14

12
18
13
9

8

4

3

7.3.3. Highlighting subgraphs
The command highlight_subgraph is used for highlighting subgraph(s) of the given graph.
highlight_subgraph accepts two or four arguments: the graph G(V ; E), a subgraph S of G
or a list of subgraphs of G and optionally the new colors for edges and vertices of the selected
subgraph(s), respectively. It returns a modied copy of G with the selected subgraph(s) colored
as specied.
> G:=graph(%{[1,2],[2,3],[3,1],[3,4],[4,5],[5,6],[6,4]%})
an undirected unweighted graph with 6 vertices and 7 edges
> A:=articulation_points(G)
[3; 4]
> B:=biconnected_components(G)
[[4; 6; 5]; [3; 4]; [1; 3; 2]]
> H:=highlight_vertex(G,A,magenta)
an undirected unweighted graph with 6 vertices and 7 edges
> draw_graph(H)

> S:=induced_subgraph(G,B[0])
an undirected unweighted graph with 3 vertices and 3 edges
> H:=highlight_subgraph(G,S)
an undirected unweighted graph with 6 vertices and 7 edges
> draw_graph(H,spring)

Bibliography
[1] Daniel Brélaz. New Methods to Color the Vertices of a Graph. Communications of the ACM, 22:251256, 1979.
[2] Cristoph Buchheim, Michael Jünger, and Sebastian Leipert. Improving Walker's Algorithm to Run in Linear
Time. In M. T. Goodrich and S. G. Kobourov, editors, Graph Drawing 2002, Lecture Notes in Computer
Science vol 2528, pages 344353. Springer-Verlag Berlin Heidelberg, 2002.
[3] Isabel M. Díaz and Paula Zabala. A Branch-and-Cut Algorithm for Graph Coloring. Discrete Applied Mathematics, 154:826847, 2006.
[4] Jack Edmonds. Paths, Trees, and Flowers. In Gessel I. and GC. Rota, editors, Classic Papers in Combinatorics,
pages 361379. Birkhäuser Boston, 2009. Modern Birkhäuser Classics.
[5] Shimon Even and Robert E. Tarjan. Computing an st-numbering. Theoretical Computer Science, 2:339344,
1976.
[6] T. M. J. Fruchterman and E. M. Reingold. Graph Drawing by Force-Directed Placement. Software: Practice
and Experience, 21:11291164, 1991.
[7] Alan Gibbons. Algorithmic graph theory. Cambridge University Press, 1985.
[8] Carl Hierholzer. Ueber die möglichkeit, einen Linienzug ohne Wiederholung und ohne Unterbrechung zu
umfahren. Mathematische Annalen, 6:3032, 1873.
[9] Andreas M. Hinz, Sandi Klavºar, and Sara S. Zemlji£. A survey and classication of Sierpi«ski-type graphs.
Discrete Applied Mathematics, 217:565600, 2017.
[10] John E. Hopcroft and Richard M. Karp. An n5/2 algorithm for maximum matchings in bipartite graphs.
SIAM Journal on Computing, 2:225231, 1973.
[11] Yifan Hu. Ecient and High Quality Force-Directed Graph Drawing. Mathematica Journal, 10:3771, 2005.
[12] Yifan Hu and Jennifer Scott. A Multilevel Algorithm for Wavefront Reduction. SIAM Journal on Scientic
Computing, 23:13521375, 2001.
[13] Arthur B. Kahn. Topological sorting of large networks. Communications of the ACM, 5:558562, 1962.
[14] Wendy Myrwold and Willian Kocay. Errors in graph embedding algorithms. Journal of Computer and System
Sciences, 77:430438, 2011.
[15] Patric R. J. Östergård. A fast algorithm for the maximum clique problem. Discrete Applied Mathematics,
120:197207, 2002.
[16] Bor Plestenjak. An Algorithm for Drawing Planar Graphs. Software: Practice and Experience, 29:973984,
1999.
[17] Angelika Steger and Nicholas C. Wormald. Generating random regular graphs quickly. Combinatorics Probability and Computing, 8:377396, 1999.
[18] Robert E. Tarjan. Depth-First Search and Linear Graph Algorithms. SIAM Journal on Computing, 1:146160,
1972.
[19] Robert E. Tarjan. Applications of path compression on balanced trees. Journal of the ACM, 26:690715, 1979.
[20] Etsuji Tomita, Akira Tanaka, and Haruhisa Takahashi. The worst-case time complexity for generating all
maximal cliques and computational experiments. Theoretical Computer Science, 363:2842, 2006.
[21] W. T. Tutte. How to draw a graph. Proceedings of the London Mathematical Society, s3-13:743767, 1963.
[22] John Q. Walker II. A nodepositioning algorithm for general trees. Software: Practice and Experience,
20:685705, 1990.
[23] E. Welch and S. Kobourov. Measuring Symmetry in Drawings of Graphs. Computer Graphics Forum,
36:341351, 2017.
[24] Douglas B. West. Introduction to Graph Theory. Pearson Education, 2002.

85

Command Index

antiprism_graph . . .
complete_binary_tree
complete_graph . . .
complete_kary_tree .
cycle_graph . . . . .
digraph . . . . . . . .
graph . . . . . . . . .
grid_graph . . . . . .
hypercube_graph . . .
interval_graph . . .
is_graphic_sequence
kneser_graph . . . . .

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

18
14
13
14
12
10
. 9
18
16
15
15
15

lcf_graph . . . .
odd_graph . . . .
path_graph . . . .
petersen_graph .
prism_graph . . .
sequence_graph .
sierpinski_graph
star_graph . . . .
torus_grid_graph
trail . . . . . . .
web_graph . . . .
wheel_graph . . .

87

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

21
15
13
20
18
15
20
17
18
13
17
17



Source Exif Data:
File Type                       : PDF
File Type Extension             : pdf
MIME Type                       : application/pdf
PDF Version                     : 1.4
Linearized                      : No
Page Count                      : 87
Title                           : Graph theory package for Giac/Xcas
Creator                         : TeXmacs 1.99.6
Producer                        : TeXmacs 1.99.6 + Hummus 3.9
EXIF Metadata provided by EXIF.tools

Navigation menu