graph theory

86
Graph Theory Author: chuong3a, nick yahoo: chuong3a Undirected Graph........................................2 Directed Graph..........................................4 Minimal Spanning Tree...................................6 Weight Matrix..........................................10 The types of Graph.....................................10 Prims Algorithm........................................17 Prim Algorithm 2 with Notation.........................19 Code Maple Prims.......................................20 Kruskal Algorithm Code C++ 1...........................23 Kruskal Algorithm Code C++ 2...........................25 Code Maple Kruskal.....................................27 Depth First Search.....................................29 Code Maple DFS.........................................30 Depth First Search Algorithm...........................31 Breadth First Search Algorithm.........................33 BFS Code Maple.........................................34 BFS Code C++...........................................35 Dijkstra Algorithm.....................................37 Code Dijkstra Algorithm................................37 Code Maple Dijsktra....................................40 Dijkstra Algorithm run by hand.........................41 Bellman-Ford Algorithm.................................45 BellmanFord Code 2.....................................47 Bellman-Ford run by hand...............................48 1

Upload: tri-phuc-nguyen

Post on 24-Oct-2014

202 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Graph Theory

Graph Theory

Author: chuong3a, nick yahoo: chuong3a

Undirected Graph..........................................................................................................2

Directed Graph..............................................................................................................4

Minimal Spanning Tree.................................................................................................6

Weight Matrix.............................................................................................................10

The types of Graph......................................................................................................10

Prims Algorithm..........................................................................................................17

Prim Algorithm 2 with Notation..................................................................................19

Code Maple Prims.......................................................................................................20

Kruskal Algorithm Code C++ 1..................................................................................23

Kruskal Algorithm Code C++ 2..................................................................................25

Code Maple Kruskal....................................................................................................27

Depth First Search.......................................................................................................29

Code Maple DFS.........................................................................................................30

Depth First Search Algorithm.....................................................................................31

Breadth First Search Algorithm...................................................................................33

BFS Code Maple.........................................................................................................34

BFS Code C++............................................................................................................35

Dijkstra Algorithm.......................................................................................................37

Code Dijkstra Algorithm.............................................................................................37

Code Maple Dijsktra....................................................................................................40

Dijkstra Algorithm run by hand..................................................................................41

Bellman-Ford Algorithm.............................................................................................45

BellmanFord Code 2....................................................................................................47

Bellman-Ford run by hand...........................................................................................48

Floyd Code..................................................................................................................50

Code Maple Floyd 1....................................................................................................52

Code Maple Floyd 2....................................................................................................52

Chu trình Euler............................................................................................................53

Euler Cycle Maple Code 1..........................................................................................54

1

Page 2: Graph Theory

Euler Cycle Maple Code 2..........................................................................................55

Stack:...........................................................................................................................56

Euler Cycle C++ Code................................................................................................57

Chu trình Hamilton......................................................................................................59

Hamilton Maple Code.................................................................................................60

Code Hamilton C++....................................................................................................62

Dijsktra 2.....................................................................................................................68

1/ 4 người bất kì trong số n > 3 người đều quen với 3 người còn lại. CM rằng luôn có 1 người quen với n – 1 người còn lại.

Solution:- Giả sử bài toán đúng với n = k, nghĩa là có 1 đỉnh A nối với k – 1 đỉnh còn lại. Ta

cm bài toán đúng với n = k + 1. - Giả sử đỉnh mới thêm vào là đỉnh B. Xét tập hợp 4 đỉnh A, B và 2 đỉnh C, D từ

đồ thị.A đã nối với C và D, nếu A nối với B thì A nối với k đỉnh. Bài toán giải quyết xong.

- Nếu A ko nối với B thì C sẽ nối với A, B, D. Cố định C và thay D bằng các đỉnh D1, D2, D3 trong đồ thị. Vì trong tập 4 đỉnh bất kì luôn có 1 đỉnh nối với 3 đỉnh còn lại nên C sẽ nối với các đỉnh A, B, D1, D2,... vậy C là đỉnh nối với k đỉnh còn lại.

2/ Trong giải cờ tướng quốc gia (có 20 kì thủ) hiện đã có 21 trận đấu được tiến hành. CMR có một kì thủ đã thi đấu ít nhất 3 trận.

Solution:- Cho số kì thủ là là số đỉnh của 1 đồ thị, số trận đấu là số cạnh của đồ thị = m.- Tổng số bậc của các đỉnh = 2*m = 42. Vì có 20 kì thủ nên nếu ko có đỉnh nào có

bậc 3 thì chỉ có 2*20 = 40 cạnh (trái giả thiết). Vậy phải có 2 đỉnh bậc 3 có ít nhất 2 kì thủ đã thi đấu 3 trận.

Undirected Graph - The AddEdge command adds one or more edges to an undirected graph. By

default, the original graph is changed to a graph containing the specified set of edge(s). Theo default, đồ thị ban đầu sẽ thay đổi thành đồ thị mới chứa tập các cạnh thêm vào. By setting inplace = false the original graph remains unchanged. Bằng thiết lập inplace = false, đồ thị ban đầu sẽ ko thay đổi.

- If the graph is weighted, then a weighted edge can be added by calling AddEdge with one or more edges in the form [edge, weight], where the edge is just the set of two vertices (đỉnh), and the weight represents (đại diện) the value of the edge weight.

2

Page 3: Graph Theory

> with( GraphTheory):G := CycleGraph(5):AddEdge( G, {{1, 3}, {2, 4}}, inplace = true);DrawGraph(G);

Graph G: an undirected unweighted graph with 5 vertices and 7 edge(s)

> with( GraphTheory):G := Graph( Matrix( [ [0, 1, 1, 0], [1, 0, 0, 1], [1, 0, 0, 0], [0, 1, 0, 0] ] ), 'weighted');Edges( G, weights);DrawGraph(G);

0, 1, 1, 01, 0, 0, 11, 0, 0, 00, 1, 0, 0

Graph G: an undirected weighted graph with 4 vertices and 3 edge(s)[{1, 2}, 1], [{1, 3}, 1], [{2, 4}, 1]

3

Page 4: Graph Theory

> AddEdge( G, [{1, 4}, 2]);Edges( G, weights);DrawGraph(G);

> G := Graph( [a, b, c, d] );AddEdge( G, Trail( a, b, c, d, a ) );DrawGraph(G);

AdjacencyMatrix(G);

Directed Graph

1/ > with( GraphTheory):G := Digraph( [a, b, c, d, e], {[a, b], [b, c], [c, d], [d, e]} );

4

Page 5: Graph Theory

DrawGraph(G);

AddArc( G, {[a, c], [b, d]} );DrawGraph(G);

2/ > with( GraphTheory):G := Graph( Matrix( [ [0, 1, 1, 0], [1, 0, 0, 3], [0$4] $2] ), 'weighted', 'directed');DrawGraph(G);

4/ > with( GraphTheory):G := Digraph( [1, 2, 3, 4], Trail( 1, 2, 3, 4, 1) );DrawGraph(G);AdjacencyMatrix(G);

5

Page 6: Graph Theory

Minimal Spanning TreeGraphTheory [KruskalsAlgorithm]GraphTheory [PrimsAlgorithm]

- Calling Sequence:MinimalSpanningTree(G)MinimalSpanningTree(G, w, animate)KruskalsAlgorithm(G, w, animate)PrimsAlgorithm(G, w, animate)Parameters:G: an undirected graph, weighted or unweightedw: (optional) nameanimate: (optional) literal animate (theo nghĩa của ảnh động) indicating (cho biết) that an animation of the algorithm should be returned instead of the tree.

Description- MinimalSpanningTree, KruskalsAlgorithm, and PrimsAlgorithm all return a

spanning tree of the undirected graph G with minimum possible weight. If the graph G is unweighted, each edge is considered to have weight 1.

- If the optional parameter w is given, it is assigned (được gán cho) the weight of the minimal spanning tree.

- If the literal animate, or animate = true is given, an animation of the application of the algorithm will be returned instead of the minimal spanning tree. Nếu có chữ animate or animate = true, 1 ảnh động của thuật toán sẽ cho kết quả thay cho cây khung tối thiểu.

> with( GraphTheory ):with( RandomGraphs ):A := Matrix( [ [0, 1, 0, 4, 0, 0], [1, 0, 1, 0, 4, 0], [0, 1, 0, 3, 0, 1], [4, 0, 3, 0, 1, 0], [0, 4, 0, 1, 0, 4], [0, 0, 1, 0, 4, 0] ]):G := Graph(A):DrawGraph(G);

6

Page 7: Graph Theory

1 2 3 4 5 61 0 1 0 4 0 02 1 0 1 0 4 03 0 1 0 3 0 14 4 0 3 0 1 05 0 4 0 1 0 46 0 0 1 0 4 0

T := MinimalSpanningTree(G);DrawGraph(T);

1 – 2; 2 – 3; 3 – 4; 3 – 6; 4 – 5;Edges(T, weights);

{ [{1, 2}, 1], [{2, 3}, 1], [{3, 4}, 3], [{3, 6}, 1], [{4, 5}, 1] }

PrimsAlgorithm( G, 'w', animate);w;

7

Page 8: Graph Theory

KruskalsAlgorithm( G, 'w', animate);w;

Dijkstras AlgorithmCalling Sequence

DijkstrasAlgorithm(G, s, t)DijkstrasAlgorithm(G, s, T)DijkstrasAlgorithm(G, s)

Parameters- G: a graph with nonnegative edge weights or no weights- s, t: vertices of the graph G- T: list of vertices of the graph G

Description- If G is an unweighted graph, the edges are assumed all to have weight 1.- If G is a weighted graph, DijkstrasAlgorithm(G, s, t) returns the cheapest

weighted path from vertex s to vertex t in the graph G. If a path from s to t exists, the output is a list of the form [[s,...,t], w] where [s,...,t] is the path and w is the weight of that path. If no such path exists the output is .

- In the second calling sequence where T is a list of vertices of G, this is short for [seq(DijkstrasAlgorithm(G, s, t), t = T)], save that the algorithm does not need to recompute cheapest paths.

- In the third calling sequence where no destination vertices (điểm đích) are given, this is short for DijkstrasAlgorithm(G, s, Vertices(G)), i.e. the cheapest path from s to every vertex in G is output.

- To compute distances between all pairs of vertices simultaneously (đồng thời), use the AllPairsDistance command. To ignore edge weights (and use a faster breadth-first search) use the ShortestPath command.

- If some edge weights are negative, the BellmanFordAlgorithm command can be used to compute the shortest path.

8

Page 9: Graph Theory

> with( GraphTheory ): G := Graph( { [{1, 2}, 1], [{2, 3}, 3], [{3, 4}, 7], [{4, 5}, 8], [{5, 6}, 15], [{1, 6}, 11] } );DijkstrasAlgorithm( G, 1, 4);DrawGraph(G);

WeightMatrix(G)

> G := Graph( { [{1, 2}, 1], [{2, 3}, 3], [{3, 4}, 7], [{2, 4}, 2], [{4, 1}, 15] } );DijkstrasAlgorithm( G, 1, 4);DrawGraph(G);

[ [1, 2, 4], 3 ]

> WeightMatrix(G)

0 1 0 151 0 3 20 3 0 7

9

Page 10: Graph Theory

15 2 7 0

x1[16] = { 0, 1, 0, 15, 1, 0, 3, 2, 0, 3, 0, 7, 15, 2, 7, 0 };

Weight MatrixCalling SequenceWeightMatrix(G, cp)Parameters

G: weighted graphcp: (optional) symbol or equation

Description- WeightMatrix returns the matrix of edge weights of a weighted graph. The

optional argument cp is used to control whether the weight matrix of the graph or a copy of it should be returned. The argument cp can be either the symbol copy or an equation of the form copy=true or copy=false. If the argument is missing the command returns a copy of the weight matrix of the graph by default.

The types of GraphCho G = (X, E) là đồ thị ko hướng.

a/ G gọi là k-đều nếu d(i) = k, với mọi I thuộc X.b/ G gọi là lưỡng phân nếu X có thể phân hoạch thành X1, X2 sao cho mọi cạnh

của G đều nối 1 đỉnh trong X1 với 1 đỉnh trong X2 và viết là G = (X1, X2, E)- Nếu G đơn và mỗi đỉnh trong X1 đều nối với tất cả các đỉnh trong X2 thì G gọi là

đồ thị lưỡng phân đủ, kí hiệu là K(r, s), với r = số đỉnh của X1 = |X1|, s = số đỉnh của X2 = |X2|. Đặc biệt, K(1, s) gọi là đồ thị 1 ngôi sao.

c/ G gọi là 1 bánh xe nếu G có n – 1 đỉnh và n – 1 cạnh tạo thành 1 đa giác đều, và tất cả các đỉnh đều nối với tâm của đa giác. Kí hiệu Wn.

> with(GraphTheory):with(SpecialGraphs):G := GeneralizedPetersenGraph(5, 2);DrawGraph(G);

10

Page 11: Graph Theory

> DegreeSequence(G);with(networks)

Vẽ đồ thị K5.> G := CycleGraph(5);DrawGraph(G);

AddEdge( G, { {1, 3}, {1, 4}, {2, 4}, {2, 5}, {3, 1}, {3, 5}, {4, 1}, {4, 5} } );DrawGraph(G);

> with(GraphTheory):G := Graph( [1, 2, 3, 4, 5]);for i from 1 to 5 do

for j from 1 to 5 doif (i != j) then

AddEdge( G, {i, j});end if;

end do;

11

Page 12: Graph Theory

end do;DrawGraph(G);

Đồ thị K5.AdjacencyMatrix(G);

1 2 3 4 51 0 1 1 1 12 1 0 1 1 13 1 1 0 1 14 1 1 1 0 15 1 1 1 1 0

DijkstrasAlgorithm( G, 1 );

Vẽ đồ thị K6G := Graph( [1, 2, 3, 4, 5, 6]);DrawGraph(G);for i from 1 to 6 do

for j from 1 to 6 doif (i != j) then

AddEdge( G, {i, j});end if;

end do;end do;DrawGraph(G);

12

Page 13: Graph Theory

G := Graph( [1, 2, 3, 4, 5, 6]);for i from 1 to 6 do

for j from 1 to 6 doif (i != j and j != i+3) then

AddEdge( G, {i, j});end if;

end do;end do;DeleteEdge( G, { {1, 4}, {2, 5}, {3, 6} });DrawGraph(G);

AdjacencyMatrix(G);

1 2 3 4 5 61 0 1 1 0 1 12 1 0 1 1 0 13 1 1 0 1 1 04 0 1 1 0 1 1

13

Page 14: Graph Theory

5 1 0 1 1 0 16 1 1 0 1 1 0

int *x, n, i, j; n = 6; x = new int [37];for (i = 1; i <= n; i++)

for (j = 1; j <= n; i++)x[i][j] = 1;

for (i = 1; i <= 3; i++)for (j = 4; j <= 6; j++)

if (j == i+3)x[i][j] = 0;

Vẽ đồ thị K(3, 4)G := Graph( [1, 2, 3, 4, 5, 6, 7]);for i from 1 to 3 do

for j from 4 to 7 doif (i != j) then

AddEdge( G, {i, j});end if;

end do;end do;DrawGraph(G);

Vẽ đồ thị W6G := Graph( [1, 2, 3, 4, 5, 6], Trail(1, 2, 3, 4, 5, 1) );for i from 1 to 5 do

AddEdge( G, {i, 6});end do;

14

Page 15: Graph Theory

DrawGraph(G);

DijkstrasAlgorithm( G, 1 );

> with(GraphTheory):with(SpecialGraphs):G := GeneralizedPetersenGraph(5, 2);DrawGraph(G);

> with(GraphTheory):with(SpecialGraphs):G := GeneralizedPetersenGraph(6, 2);DrawGraph(G);

15

Page 16: Graph Theory

> with(GraphTheory):with(SpecialGraphs):G := GeneralizedPetersenGraph(7, 2);DrawGraph(G);

> with(GraphTheory):with(SpecialGraphs):G := WheelGraph(6);DrawGraph(G);

16

Page 17: Graph Theory

Prims Algorithm Tìm cây khung có trọng số nhỏ nhất.

> with(GraphTheory):G := Graph( { [{1, 2}, 1], [{1, 3}, 1], [{1, 4}, 1], [{1, 5}, 1], [{2, 3}, 1], [{2, 4}, 1], [{2, 5}, 1], [{3, 4}, 1], [{3, 5}, 1], [{4, 5}, 1] } );DrawGraph(G);

PrimsAlgorithm(G);

> with(GraphTheory):

17

Page 18: Graph Theory

G := Graph( { [{1, 2}, 3], [{1, 3}, 24], [{1, 4}, 35], [{1, 5}, 16], [{2, 3}, 5], [{2, 4}, 6], [{2, 5}, 17], [{3, 4}, 7], [{3, 5}, 38], [{4, 5}, 19] } );DrawGraph(G);

PrimsAlgorithm(G, 'w', animate);

Edge (1, 2): 3Edge (2, 3): 5Edge (2, 4): 6Edge (1, 5): 16

KruskalsAlgorithm(G, 'w', animate);WeightMatrix(G);

1 2 3 4 51 0 3 24 35 162 3 0 5 6 173 24 5 0 7 384 35 6 7 0 19

18

Page 19: Graph Theory

5 16 17 38 19 0

x1[] = { 3, 24, 35, 16, 5, 6, 17, 7, 38, 19 }x1[] = { 0, 3, 24, 35, 16, 3, 0, 5, 6, 17, 24, 5, 0, 7, 38, 35, 6, 7, 0, 19, 16, 17, 38, 19, 0 };x1[] = { 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0 };

Prim Algorithm code C++ with Notation #include <iostream.h>#include <stdio.h> class Prim { int n, k; int visited[10], min, minicost, A[10][10]; public: Prim() { k = 1; // Number of Edges minicost = 0; } void Read(); void Prims1 (int cost[][10], int n);};void Prim :: Read() { n = 5; int i, j, k1; k1 = 0; int x1[] = { 3, 24, 35, 16, 5, 6, 17, 7, 38, 19 };

for (i = 1; i <= n; i++) { for (j = i+1; j <= n; j++) { A[i][j] = x1[k1]; k1++; printf ("A[%d][%d] = %d ", i, j, A[i][j]); } printf ("\n"); } Prims1 (A, n);}void Prim :: Prims1 (int A[][10], int n) { int i, j, a, b, b1[n], b2[n], b3[n], k1; k1 = 0;

for (i = 2; i <= n; i++) visited[i] = 0; cout << "\n Edges in the spanning tree are: \n"; visited[1] = 1; while (k < n) { printf ("k = %d \n", k); for (i = 1, min = 999; i <= n; i++) for (j = i+1; j <= n; j++) //printf ("\n i = %d, j = %d \n", i, j); if (A[i][j] > min) { printf ("if A[%d][%d] = %d > min = %d continue \n", i, j, A[i][j], min); }

19

Page 20: Graph Theory

else if (A[i][j] < min) { printf ("if A[%d][%d] = %d < min = %d \n", i, j, A[i][j], min); if (visited[i] == 0) { printf ("if (visited[%d] == %d) continue \n", i, visited[i]); continue; }

else {min = A[i][j]; a = i; b = j; printf ("min = A[%d][%d] = %d \n", i, j, min); //printf ("a = i = %d, b = j = %d \n", i, j);

} } if (visited[a] == 0 || visited[b] == 0) { printf ("\n if (visited[a] = visited[%d] == %d) \n", a, visited[a]); printf ("or if (visited[b] = visited[%d] == %d) \n", b, visited[b]); k++; printf ("k++ = %d \n", k); printf ("Edge(%d, %d): %d \n", a, b, min); b1[k1] = a; b2[k1] = b; b3[k1] = min; k1++; minicost += min; visited[b] = 1; printf ("visited[b] = visited[%d] = 1 \n", b); } A[a][b] = A[b][a] = 999; printf ("A[%d][%d] = A[%d][%d] = 999 \n", a, b, b, a); printf ("min = %d \n", min); } cout << "\n Minimum cost spanning tree is:" << minicost; printf ("The Spanning Tree \n");

for (i = 0; i < n-1; i++) printf ("Edge (%d, %d): %d \n", b1[i], b2[i], b3[i]);}int main() { cout << "\n Prim's algorithm \n"; Prim p; p.Read(); }

Code Maple PrimsPrims := proc(G::Graph, x0) local n, A, Kt, i, j, t, min, a, b, T; min := 999; A := WeightMatrix(G); n := NumberOfVertices(G); Kt := {x0}; T := Graph(n);

if not IsConnected(G) thenreturn ("Do thi nay ko lien thong");

end if;for t from 1 to n-1 do

min := 999; for i in Kt do

for j from 1 to n do if 0 < A(i, j) < min and j ∉ Kt then

20

Page 21: Graph Theory

min := A(i, j); a := i; b := j; end if; end do; end do; Kt := Kt union {b}; T := AddEdge(T, {a, b}); end do; return T;end proc:

with(GraphTheory):with(RandomGraphs):G := RandomGraph( 8, 10, connected, weights = 1..10);T := Prims(G, 1);HighlightEdges(G, T, red);DrawGraph(G);

with(GraphTheory):G := Graph( { [{1, 2}, 3], [{1, 3}, 24], [{1, 4}, 35], [{1, 5}, 16], [{2, 3}, 5], [{2, 4}, 6], [{2, 5}, 17], [{3, 4}, 7], [{3, 5}, 38], [{4, 5}, 19] } );DrawGraph(G);

C := Edges( G, weights);C = { [{1, 2}, 3], [{1, 3}, 24], [{1, 4}, 35], [{1, 5}, 16], [{2, 3}, 5], [{2, 4}, 6], [{2,

5}, 17], [{3, 4}, 7], [{3, 5}, 38], [{4, 5}, 19] }

for y in C doprint( y[1][1], y[1][2], y[1], y[2]);

end do; y[1][1] = 1; y[1][2] = 2; y[1] = {1, 2}; y[2] = 3; y[1][1] = 1; y[1][2] = 3; y[1] = {1, 3}; y[2] = 24;

for y in C doif y[1] = {1, 3} then

print(y[2]); end if; end do;

y[2] = 24.

if (i[1][1]=x1 and i[1][12] = x2) or (i[1][2]=x1 and i[1][1]=x2)

for i in Edges(G,weights)if( y[1] = {x1, x2} or y[1] = {x2, x1} )y[1][2] lúc đó chính là trọng lượng

21

Page 22: Graph Theory

Giải thuật: - Step 1: Chọn tùy ý đỉnh và khởi tạo , V là tập đỉnh, T

là tập cạnh.- Step 2: Trong số những cạnh nối đỉnh x0 với y mà , ta chọn

cạnh e có trọng số nhỏ nhất. Nếu ko có cạnh e: Dừng (1). - Step 3: Gán V := V {y}, and T := T {e}. - Step 4: Nếu T đủ n-1 phần tử thì Dừng (2), ngược lại làm tiếp bước 2.

Ghi chú: Khi thuật toán dừng theo trường hợp 1 (Tìm ko có cạnh từ x đi ra) thì đồ thị ko liên thông nên ko có cây khung.

> with(GraphTheory):G := Graph( { [{1, 2}, 3], [{1, 3}, 24], [{1, 4}, 35], [{1, 5}, 16], [{2, 3}, 5], [{2, 4}, 6], [{2, 5}, 17], [{3, 4}, 7], [{3, 5}, 38], [{4, 5}, 19] } );DrawGraph(G);

Prim Algorithm- Step 1: chọn đỉnh 1, trong số những cạnh kề với đỉnh 1, chọn cạnh {1, 2} có

trọng số min là 3.- Step 2: chọn đỉnh 2, trong số những cạnh kề với đỉnh 1, 2, chọn cạnh {2, 3} có

trọng số min là 5.- Step 3: trong số những cạnh kề với đỉnh 1, 2, 3 chọn cạnh {2, 4} có trọng số min

là 6.- Step 4: trong số những cạnh kề với đỉnh 1, 2, 3, 4 chọn cạnh {3, 4} có trọng số

min là 7. {2, 3, 4} tạo thành chu trình nên bỏ cạnh {3, 4}.- Step 5: trong số những cạnh kề với đỉnh 1, 2, 3, 4, chọn cạnh {1, 5} có trọng số

min là 16.

Kruskal Algorithm- Step 1: chọn cạnh {1, 2} có trọng số min là 3.- Step 2: chọn cạnh {2, 3} có trọng số min là 5.

22

Page 23: Graph Theory

- Step 3: chọn cạnh {2, 4} có trọng số min là 6.- Step 4: chọn cạnh {3, 4} có trọng số min là 7. Nhưng {2, 3, 4} tạo thành chu trình

nên bỏ cạnh {3, 4}.- Step 5: chọn cạnh {1, 5} có trọng số min là 16.

Kruskal Algorithm Code C++ 1Step 1: Sắp xếp các cạnh của đồ thị theo thứ tự trọng số tăng dần và khởi tạo cây T = Ø Step 2: Duyệt theo cạnh e thuộc danh sách đã sắp xếp. Nếu T + e ko chứa chu trình thì: Ghép cây e vào cây: T = T + {e}; Nếu T đủ n – 1 phần tử thì dừng.

#include <iostream.h>#include <stdio.h> #define MAX 100class Kruskal {

private: struct Edge1 {

int u, v, weight; } Edge[MAX];int Tree[MAX][2], set[MAX]; int n;

public: int ReadEdges(); void MakeSet(); int Find (int vertex); void Join (int v1, int v2); void Arrange (int k); int SpanningTree (int k); void Display (int k);};int Kruskal :: ReadEdges() {

int i, j, k, m; k = 1; n = 5; m = 0; int x[] = { 3, 24, 35, 16, 5, 6, 17, 7, 38, 19 };

for (i = 1; i <= n; i++)for (j = i+1; j <= n; j++) {

Edge[k].u = i; Edge[k].v = j;Edge[k++].weight = x[m]; m++;

}return (k - 1);

}void Kruskal :: MakeSet() { int i;

for (i = 1; i <= n; i++)

23

Page 24: Graph Theory

set[i] = i;}int Kruskal :: Find (int vertex) { return (set[vertex]);}void Kruskal :: Join (int v1, int v2) {

int i, j;if (v1 < v2) {

printf ("if (v1 = %d < v2 = %d) \n", v1, v2); printf ("set [v2] = v1; set[%d] = %d \n", v2, v1);set[v2] = v1; }

else {printf ("if (v1 = %d > v2 = %d) \n", v1, v2); printf ("set[v1] = v2; set[%d] = %d \n", v1, v2);set[v1] = v2; }

}void Kruskal :: Arrange (int k) {

int i, j;struct Edge1 temp;for (i = 1; i < k; i++)

for (j = 1; j <= k - i; j++)if (Edge[j].weight > Edge[j + 1].weight) {

temp = Edge[j];Edge[j] = Edge[j + 1];Edge[j + 1] = temp;

}}int Kruskal :: SpanningTree (int k) {

int i, t, j, sum, k1, k2; Arrange(k); t = 1; sum = 0;for (i = 1; i <= k; i++)

printf ("Edge (%d, %d): %d \n", Edge[i].u, Edge[i].v, Edge[i].weight); for (i = 1; i <= n; i++)

if (Find (Edge[i].u) != Find (Edge[i].v)) {for (j = 1; j <= n; j++)

printf ("set[%d] = %d ", j, set[j]); k1 = Edge[i].u; k2 = Edge[i].v;printf ("\n if (Find (Edge[%d].u) != Find (Edge[%d].v)) \n", i, i);printf (" Find(%d) = set [%d] = %d \n", k1, k1, set[k1]);printf (" Find(%d) = set [%d] = %d \n", k2, k2, set[k2]);Tree[t][1] = Edge[i].u;Tree[t][2] = Edge[i].v;printf ("Tree[%d][1] = Edge[%d].u = %d \n", t, i, Edge[i].u); printf ("Tree[%d][1] = Edge[%d].v = %d \n", t, i, Edge[i].v); sum += Edge[i].weight;printf ("Join (Edge[%d].u, Edge[%d].v); t++ = %d; \n\n", t, t, t+1);

24

Page 25: Graph Theory

Join (Edge[t].u, Edge[t].v); t++;}else {

printf ("if (Find (Edge[%d].u) == Find (Edge[%d].v)) continue \n", i, i);printf ("Edge[%d].u = %d, Edge[%d].v = %d \n", i, Edge[i].u, i, Edge[i].v);continue; }

return sum;}void Kruskal :: Display (int k) {

int i;cout << "\n The Edges of the Minimum Spanning Tree are \n ";for (i = 1; i < n; i++)

cout << Tree[i][1] << " - " << Tree[i][2] << endl;cout << "\n The Cost of the Minimum Spanning Tree is : " << k;

}int main() {

int ecount, totalcost; Kruskal k;ecount = k.ReadEdges(); k.MakeSet();totalcost = k.SpanningTree (ecount);k.Display (totalcost);return 0;

}

Kruskal Algorithm Code C++ 2#include <iostream.h> #include <stdio.h> class Kruskal { private: int n; // number of nodes int noe; //no edges in the graph int graph [100][4]; int sets[10]; int k2; public: void ReadGraph(); void Initial(); void SortEdges(); void Algorithm(); int FindNode(int k); void print();};

void Kruskal :: ReadGraph() { int i, j, k, w; n = 5; noe = 0; k = 0;

25

Page 26: Graph Theory

int x[] = { 3, 24, 35, 16, 5, 6, 17, 7, 38, 19 }; for (i = 1; i <= n; i++) { for (j = i+1; j <= n; j++) {

if (x[k] != 0) { noe++; graph [noe][1] = i; graph [noe][2] = j; graph [noe][3] = x[k]; k++; } } } // print the graph edges cout << "\n The edges in the given graph are:: \n"; for (i = 1; i <= noe; i++) cout << " < " << graph [i][1] << " , " << graph [i][2] << " > ::" << graph [i][3] << endl;}void Kruskal :: SortEdges() { /* Sort the edges using bubble sort in increasing order */ int i, j; for (i = 1; i <= noe-1; i++) { for (j = 1; j <= noe-i; j++) { if (graph [j][3] > graph [j+1][3]) { int t = graph [j][1]; graph [j][1] = graph [j+1][1]; graph [j+1][1] = t; t = graph [j][2]; graph [j][2] = graph [j+1][2]; graph [j+1][2] = t; t = graph [j][3]; graph [j][3] = graph [j+1][3]; graph [j+1][3] = t; } } } // print the graph edges cout << "\n After sorting the edges in the given graph are:: \n"; for (i = 1; i <= noe; i++) cout << " < " << graph [i][1] << " , " << graph [i][2] << " > ::" << graph [i][3] << endl;}void Kruskal :: Algorithm() { int i, j, k1, p1, p2; k2 = 1; // ->make a set for each node for (i = 1; i <= n; i++) { sets[i] = i; } cout << "\n The algorithm starts :: \n"; for (i = 1; i <= n; i++) { printf ("p1 = FindNode (graph[%d][1] = %d) \n", i, graph [i][1]); p1 = FindNode (graph [i][1]); printf ("p1 = %d \n", p1);

printf ("p2 = FindNode (graph[%d][2] = %d) \n", i, graph [i][2]); p2 = FindNode (graph [i][2]);

26

Page 27: Graph Theory

printf ("p2 = %d \n", p2); if (p1 != p2) { cout << "The edge included in the tree is :: " << " < " << graph [i][1] << " , " << graph [i][2] << " > " << endl;

k2++; } /* End if (p1 != p2) */

else { cout << "Inclusion of the edge " << " < " << graph [i][1] << " , " << graph [i][2] << " > " << "forms a cycle so it is removed \n"; }

} /* End for (i = 1; i <= noe; i++) */}int Kruskal :: FindNode (int n) { for (int i = 1; i <= k2; i++) { if (n == sets[i]) { printf ("if (%d == sets[%d] = %d) \n", n, i, sets[i]); printf ("return 1 \n"); return 1; } else { printf ("if (%d != sets[%d] = %d) \n", n, i, sets[i]); printf ("return -1 \n"); } } return -1;}int main() { Kruskal obj; obj.ReadGraph(); obj.SortEdges(); obj.Algorithm(); return 0;}

Code Maple Kruskalwith(GraphTheory):G := Graph( { [{1, 2}, 3], [{1, 3}, 24], [{1, 4}, 35], [{1, 5}, 16], [{2, 3}, 5], [{2, 4}, 6], [{2, 5}, 17], [{3, 4}, 7], [{3, 5}, 38], [{4, 5}, 19] } );DrawGraph(G);

Kruskal := proc(G::Graph)local n, A, i, j, k, t, min, il, jl, T, Mien, tam;

min := 999; A := WeightMatrix(G); n := NumberOfVertices(G); Mien := array(1..n): T := Graph(n);

if not IsConnected(G) then

27

Page 28: Graph Theory

return ("Do thi nay ko lien thong");end if;for i from 1 to n do

Mien[i] := i;end do;for t from 1 to n-1 do

min := 999; for i from 1 to n-1 do

for j from 1 to n do if 0 < A[i, j] < min and Mien[i] != Mien[j] then

min := A[i, j]; il := i; jl := j; end if; end do; end do;

T := AddEdge(T, {il, jl} ); Mien[jl] := Mien[il];

end do; return T;end proc:

with(GraphTheory):with(RandomGraphs):G := RandomGraph( 8, 10, connected, weights = 1..10);T := Kruskal(G, 1);HighlightEdges(G, T, red);DrawGraph(G);

Code 2:Kruskal := proc(G::Graph)

local n, A, i, j, k, t, min, il, jl, T, Mien, tam, Kt; min := 999; Kt := { }; A := WeightMatrix(G); n := NumberOfVertices(G); Mien := array(1..n): T := Graph();

if not IsConnected(G) thenreturn ("Do thi nay ko lien thong");

end if;for i from 1 to n do

Mien[i] := i;end do;for t from 1 to n-1 do

min := 999; for i from 1 to n do

for j from 1 to n do if 0 < A[i, j] < min and Mien[i] != Mien[j] then

28

Page 29: Graph Theory

min := A[i, j]; il := i; jl := j; end if; end do; end do;

if il ∉ Kt then T := AddVertex(T, il); Kt := Kt union {il}; end if;if jl ∉ Kt then T := AddVertex(T, jl); Kt := Kt union {jl}; end if;T := AddEdge(T, {il, jl} ); Mien[jl] := Mien[il];

end do; return T;end proc:

with(GraphTheory):with(RandomGraphs):G := RandomGraph( 8, 10, connected, weights = 1..10);T := Kruskal(G, 1);HighlightEdges(G, T, red);DrawGraph(G);

Depth First Search

#include <iostream.h>#include <stdio.h>#include <conio.h>#include <string.h> #define MAX 20int A[MAX][MAX];int v[MAX];int i = 1, n; int T[20]; void DFS (int v1) { int v2; cout << v1 << "\t"; v[v1] = 1;

printf ("v[%d] = 1 \n", v1); for (v2 = 1; v2 <= n; v2++) if (A[v1][v2] != 0 && v[v2] == 0) {

printf ("if (A[%d][%d] == 1 && v[%d] == 0) \n", v1, v2, v2);printf ("%d - %d \n", v1 , v2);printf ("DFS (%d) \n", v2);T[i] = v1; T[i+1] = v2; i = i + 2;

DFS (v2);}

}void Create() { n = 9; int i, j, k1; k1 = 0;

29

Page 30: Graph Theory

int x1[] = { 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

for (i = 1; i <= n; i++) for (j = i+1; j <= n; j++) { A[j][i] = A[i][j] = x1[k1]; k1++;

}for (i = 1; i <= n; i++) {

j = i; A[i][j] = 0; }

for (i = 1; i <= n; i++) { for (j = 1; j <= n; j++) { cout.width(5);

cout << A[i][j]; } printf ("\n"); }

}int main() { int i, v1, v2; Create(); for (v1 = 1; v1 <= n; v1++) v[v1] = 0; DFS (1);

for (i = 1; i < 2*n-1; i += 2)printf ("%d - %d \n", T[i], T[i+1]);

return 0;}

Code Maple DFS

with(GraphTheory):G := Graph( [1, 2, 3, 4, 5, 6, 7, 8, 9]);AddEdge( G, { {1, 2}, {1, 3}, {2, 4}, {2, 5}, {2, 6}, {3, 7}, {3, 8}, {3, 9} });DrawGraph(G);

DFS := proc(k::integer)local i; global Kt, A, n, E;

Kt := Kt union {k};for i from 1 to n do

if A(k, i) != 0 and i ∉ Kt thenE := AddEdge(E, {k, i} ); DFS(i);

end if;end do;

end proc:

main := proc(G::Graph, k)global n, A, E, Kt;

30

Page 31: Graph Theory

n := NumberOfVertices(G); A := AdjacencyMatrix(G);E := Graph(n); Kt := { };if not IsConnected(G) then

return ("Do thi nay ko lien thong");end if;DFS(k);return E;

end proc:

with(GraphTheory):with(RandomGraphs):G := RandomGraph( 8, 10, connected, weights = 1..10);T := main(G, 2);HighlightEdges(G, T, red);DrawGraph(G);

Tạo 1 mảng có 10 phần tử = 0 trong Maple:V := [ seq( 0, i = 1..10) ];V := array(1..n)for i from 1 to n do

V[i] := 0;end do;

Depth First Search Algorithm- Given graph G = (X, E), X is the set of vertices, E is the set of edges.- Step 1: Sorting the vertices by order: x1, x2, x3... Choose arbitrary vertex x = x1,

A = X – {x1} (remove x1 out of set of vertices). Initialize set of edges T = Ø.- Step 2: If N(x) (set of vertices near x) intersect with A = Ø, so going to Step 4.

If N(x) intersect with A ≠ Ø, so going to Step 3.- Step 3: Choose min i so that xi in N(x) intersect with A,

and choosing e = {x, xi}. T = T + e, A = A – xi, x = xi. Return Step 2.- Step 4: If x = x1 then stopping. T is the Tree.

If x ≠ x1, then search predecessor (phần tử trước) x: x = pre(x). Return Step 2.

31

Page 32: Graph Theory

1 2 3 4 5 6 7 8 91 0 1 1 0 0 0 0 0 02 0 0 1 1 1 0 0 03 0 0 0 0 1 1 14 0 0 0 0 0 05 0 0 0 0 06 0 0 0 07 0 0 08 0 09 0

int x1[] = { 1, 1, 0, 0, 0, 0, 0, 0,/ 0, 1, 1, 1, 0, 0, 0,/ 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0,/ 0, 0, 0, 0,/ 0, 0, 0,/ 0, 0,/ 0}; int x1[] = { 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

- Step 1: Khởi tạo mảng v[9] = {0}. Chọn x1 là phần tử bắt đầu, v[1] = 1, đánh dấu phần tử x1. Bỏ x1 khỏi A: A = { x2, x3, x4, x5, x6, x7, x8, x9}

- Step 2: If (v[2] == 0 && A[1][2] != 0), chọn x2 là phần tử nhỏ nhất kề với x1, x = x2. Thêm vào T cạnh {x1, x2}. v[2] = 1, bỏ x2 khỏi A: A = { x3, x4, x5, x6, x7, x8, x9}

- Step 2: If (v[4] == 0 && A[2][4] != 0), chọn x4 là phần tử nhỏ nhất kề với x2, x = x4. Thêm vào T cạnh {x2, x4}. v[4] = 1, bỏ x4 khỏi A: A = { x3, x5, x6, x7, x8, x9}

- Step 3: Vì giao các đỉnh kề của x4 với A = Ø nên dò ngược pre(x4) = x2.- Step 2: If (v[5] == 0 && A[2][5] != 0), chọn x5 là phần tử kế tiếp kề với x2, x =

x5. Thêm vào T cạnh {x2, x5}. v[5] = 1, bỏ x5 khỏi A: A = { x3, x6, x7, x8, x9 }- Step 3: Vì giao các đỉnh kề của x5 với A = Ø nên dò ngược pre(x5) = x2.- Step 2: If (v[6] == 0 && A[2][6] != 0), chọn x6 là phần tử kế tiếp kề với x2, x =

x6. Thêm vào T cạnh {x2, x6}. v[6] = 1, bỏ x6 khỏi A: A = { x3, x7, x8, x9 }- Step 3: Vì giao các đỉnh kề của x6 với A = Ø nên dò ngược pre(x6) = x2.Vì giao các đỉnh kề của x2 với A = Ø nên dò ngược pre(x2) = x1.

32

Page 33: Graph Theory

- Step 2: If (v[3] == 0 && A[1][3] != 0), chọn x3 là phần tử kế tiếp kề với x1, x = x3. Thêm vào T cạnh {x1, x3}. v[3] = 1, bỏ x3 khỏi A: A = { x7, x8, x9 }

T = { {x1, x2}, {x2, x4}, {x2, x5}, {x2, x6}, {x1, x3}, {x3, x7}, {x3, x8}, {x3, x9} }

Breadth First Search Algorithm - Given graph G = (X, E), X is the set of vertices, E is the set of edges.- Step 1: Sorting the vertices by order: x1, x2, x3... Choose arbitrary vertex x = x1,

A = {x1}, B = X – {x1} (remove x1 out of set of vertices). Initialize set of edges T = Ø. N(x) is the set of vertices near x.

- Step 2: If B = Ø then stopping. T is the tree.If B ≠ Ø then going to Step 3 where S = Ø.

- Step 3: Put x = minA. If N(x) intersect with B = Ø then going Step 4.If N(x) intersect with B = { y1,..., yk } then choosing the edges e = xyj and

T = T + e1 +... ek, B = B – { y1,..., yk }.S = S + { y1,..., yk }- Step 4: A = A – {x}. If A is different Null, then returning Step 2.If A is Null, then returning Step 3 with A = S.

- Step 1: Khởi tạo mảng v1[9] = {0}. Chọn x1 là phần tử bắt đầu, v1[1] = 1, v1[] là mảng đánh dấu phần tử x1 của B. Bỏ x1 khỏi B: B = { x2, x3, x4, x5, x6, x7, x8, x9 }, v[1] = 1, A = {x1}. v2[9] = {0}, v2[] là mảng đánh dấu phần tử của S.T = Ø, S = Ø.

- Step 2: If B ≠ Ø then going to Step 3 with S = Ø.B ≠ Ø:for (i = 0; i < n; i++)

if (v1[i] == 0)

S = Ø:for (i = 0; i < n; i++)

v2[i] = 0;

- Step 3: Put x = minA = x1, N(x) intersect with B = {x2, x3}.

33

Page 34: Graph Theory

T = T + {x1, x2} + {x1, x3}; v[2] = v[3] = 1; B = B – {x2, x3} = { x4, x5, x6, x7, x8, x9 }; S = S + {x2, x3} = {x2, x3}.- Step 4: A = A – {x1} = Null; returning Step 2 with A = S.- Step 2: If B ≠ Ø then going to Step 3 with S = Ø.- Step 3: Put x = minA = x2, N(x) intersect with B = { x4, x5, x6 }.T = T + {x2, x4} + {x2, x5} + {x2, x6}; v[4] = v[5] = v[6] = 1; B = B – { x4, x5, x6 } = { x7, x8, x9 }; S = { x4, x5, x6 }.- Step 4: A = A – {x2} = {x3}; returning Step 3.- Step 3: Put x = minA = x3, N(x) intersect with B = { x7, x8, x9 }.T = T + {x3, x7} + {x3, x8} + {x3, x9}; v[7] = v[8] = v[9] = 1; B = B – { x7, x8, x9 } = Null. S = { x7, x8, x9 }.- Step 4: A = A – {x3} = Null; returning Step 2.- Step 2: If B = Null then stopping algorithm. T is the Tree.

T = { {x1, x2}, {x1, x3}, {x2, x4}, {x2, x5}, {x2, x6}, {x3, x7}, {x3, x8}, {x3, x9} }

BFS Code Maplewith(GraphTheory):G := Graph( [1, 2, 3, 4, 5, 6, 7, 8, 9]);AddEdge( G, { {1, 2}, {1, 3}, {2, 4}, {2, 5}, {2, 6}, {3, 7}, {3, 8}, {3, 9} });DrawGraph(G);

BFS := proc( G::Graph, x1)local A, B, C, S, T, x, y, n; A := {x1}; n := NumberOfVertices(G); T := Graph(n); B := { op(Vertices(G)) }; B := B minus {x1}; S := { };if not IsConnected(G) then

return ("Do thi nay ko lien thong");end if;while not (B = { }) do

x := A[1];C := { op(Neighbors(G, x) ) } intersect B; B := B minus C;for y in C do

T := AddEdge( T, {x, y}); end do;S := S union C; A := A minus {x};if A = { } then A := A union S; end if;S := { }; C := { };

end do;return T;

end proc:

with(GraphTheory):with(RandomGraphs):G := RandomGraph( 8, 10, connected, weights = 1..10);T := BFS(G, 2);

34

Page 35: Graph Theory

HighlightEdges(G, T, red);DrawGraph(G);

BFS Code C++#include <iostream.h>class Queue {

private:int data;Queue *Next;

public: void Enque (int data); int Deque();} *Head, *Tail;void Queue :: Enque (int data) { Queue *temp; temp = new Queue; temp->data = data; temp->Next=NULL; if (Head == NULL) Head = temp; else Tail->Next = temp; Tail = temp;}int Queue :: Deque() { Queue* temp; temp = Head; Head = Head->Next; return temp->data;}int visit[100];int bfs_span_tree[100][100];class Graph { private: int a; Graph *Next; public: void BFS(); Graph* Create (Graph* Head, int *x, int n); void Ftraverse (Graph *Head);};Graph* Graph :: Create (Graph *Head, int *x, int n) { int a, i, k; k = 0; Graph *last; Head = last = NULL; Graph *temp;

for (i = 0; i < n; i++) { temp = new Graph; temp->a = x[i]; temp->Next = NULL;

35

Page 36: Graph Theory

if (Head == NULL) Head = temp; else last->Next = temp; last = temp; } return Head;}void Graph :: Ftraverse (Graph *h) { while (h != NULL) { cout << h->a << "->"; h = h->Next; } cout << "NULL \n";}void Graph :: BFS() { cout << "This program is to implement BFS for an unweighted graph \n"; Graph *ptr[100]; int n, i; n = 2; int x1[9] = { 1, 2, 4, 6, 7, 3, 5, 1, 6 }; int x2[9] = { 4, 7, 3, 5, 1, 2, 5, 7, 4};

ptr[1] = Create (ptr[1], x1, 9); ptr[2] = Create (ptr[2], x2, 9); cout << "\n The Entered Graph is ::\n"; for (i = 1; i <= n; i++) { cout << "< " << i << " > ::"; Ftraverse (ptr[i]); } int x; cout << "\n Enter the start node " << n << ">:"; cin >> x; cout << "\n The Breadth first search traversal is: \n"; Queue object; // Mark all the nodes as not viseted for (i = 1; i <= n; i++) visit[i] = 0; for (i = 1; i <= n; i++) for (int j = 1; j <= n; j++) bfs_span_tree[i][j] = 0; // Enque the start node object.Enque (x); int p; while (Head != NULL && Tail != NULL) { // Deque a node p = object.Deque(); int x = p; // If p is not visited yet. while (ptr[p] != NULL) { if (visit [ptr [p]->a] != 1) { cout << "node " << ptr[p]->a << " is visited \n";

36

Page 37: Graph Theory

// Mark the node as visited. visit [ptr [p]->a] = 1; bfs_span_tree [ptr [p]->a] [x] = 1; } // Enque all its adjacent nodes. object.Enque (ptr[p]->a); ptr[p] = ptr[p]->Next; } } cout << "\n The required bfs spanning tree is ::\n"; for (i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) cout << bfs_span_tree[i][j] << ' '; cout << "\n"; } cout << "\n";}int main() { Graph obj; obj.BFS(); return 0;}

Dijkstra Algorithm - Cho đồ thị G = (X, E) với các cạnh có trọng số ko âm.- Dữ liệu nhập cho thuật toán là ma trận trọng số L và 2 đỉnh x, y cho trước. (với

quy ước L(x, y) = 999 nếu ko có cạnh nối từ đỉnh x đến đỉnh y).- Dữ liệu xuất là đường đi ngắn nhất từ x đến y.

Step 1: Assign (gán) T = X, the set of vertices (các đỉnh) of graph.Initial (khởi động): length[x] = 0; with every k in X \{x}, length[k] = 999.last[k] = 0; mark[k] = 0. - length[k] is the length of path from vertex x to vertex k. last[] is the array to save

the path element. mark[] is the array to mark the elements whether is visited or not.Step 2: If y not in T, Stop.

Choose vertex v in T so that length[v] is min and remove v out of T. mark[v] = 1.Step 3:

With every vertex k in T, and there exist an edge from v to k.If length[k] > length[v] + L(v, k) // weight of edge from v to k.

length[k] = length[v] + L(v, k)last[k] = v.

Continuos step 2.

Code Dijkstra Algorithm

37

Page 38: Graph Theory

#include <iostream.h>#include <stdio.h> class Dijkstra {

private:int graph[15][15];int last[15], mark[15], length[15];int source;int n; // num_of_verticespublic:int Minimum();int Read();void Initialize (int source);void Printpath (int i);void Algorithm (int source);void Output();

};int Dijkstra::Read() {

n = 5; int i, j, k = 0;int x1[] = { 3, 24, 35, 16, 5, 6, 17, 7, 38, 19};cout << "enter the adjacent matrix: \n";for (i = 1; i <= n; i++)

for (j = i+1; j <= n; j++) {graph[j][i] = graph[i][j] = x1[k]; k++;

}for (i = 1; i <= n; i++)

graph[i][i] = 0; for (i = 1; i <= n; i++) {

for (j = 1; j <= n; j++) printf ("%d ", graph[i][j]);

printf ("\n");}cout << "\n enter the source vertex \n"; cin >> source;return source;

}void Dijkstra::Initialize (int source) {

int i;for (i = 1; i <= n; i++) {

mark[i] = 0;length[i] = 999;last[i] = 0;

} length [source] = 0;}void Dijkstra::Algorithm (int source) {

38

Page 39: Graph Theory

Initialize (source); int count = 0, i, u;while (count < n) {

u = Minimum();printf ("u = Minimum() = %d \n", u);count++; mark[u] = 1;printf ("mark[%d] = 1 \n", u);for (i = 1; i <= n; i++)

if (graph[u][i] > 0) {if (mark[i] != 1) {

printf ("if (mark[%d] != 1) \n", i);if (length[i] > length[u] + graph[u][i]) {

printf ("if (length[%d] > length[%d] + graph[%d][%d]) \n", i, u, u, i);printf ("length[%d] = %d, length[%d] = %d \n", i, length[i], u,

length[u]);printf ("graph[%d][%d] = %d \n", u, i, graph[u][i]);length[i] = length[u] + graph[u][i];last[i] = u;printf ("length[%d] = length[%d] + graph[%d][%d] = %d \n", i, u, u, i,

length[i]);printf ("last[%d] = %d \n", i, u);

}} } /* End if (graph[u][i] > 0) */

} }void Dijkstra::Printpath (int i) {

cout << endl;if (i == source)

cout << source;else if (last[i] == 0)

cout << "no path from " << source << " to " << i;else {

Printpath (last[i]);cout << "..." <<i; }

}void Dijkstra::Output() {

int i;for (i = 1; i <= n; i++) {

Printpath(i);if (length[i] != 999)

cout << "->(" << length[i] << ") \n";} cout << endl;

}int Dijkstra::Minimum() {

int min = 999; int i, t;for (i = 1; i <= n; i++) {

if (mark[i] != 1) {

39

Page 40: Graph Theory

if (min >= length[i]) {min = length[i];t = i;

} }} return t;

}int main() {

int source; Dijkstra s; source = s.Read();s.Algorithm (source); s.Printpath(4);return 0;

}

Code Maple Dijsktra with(GraphTheory): with(RandomGraphs):with(LinearAlgebra):Dijsktra := proc()

global m, n, DoDai, Browse, Kt; local i, v, min;while Kt != ∅ do

min := 999; v := 0;for i in Kt do

if min >= DoDai[i] then min := DoDai[i]; v := i; end if;end do;Kt := Kt minus {v};for i in Kt do

if A[i, v] > 0 and DoDai[i] > DoDai[v] + A[i, v] then DoDai[i] := DoDai[v] + A[i, v];Browse[i] := v;

end if;end do;

end do;end proc:

ve := proc(x0)local i, E; E := Digraph(n);for i from 1 to n do

if Truoc[i] != i then E := AddArc(E, { [Browse[i], i] }); end if;end do;print(E);HighlightEdges(G, E, red); HightlightVertex(G, x0, red);print( DrawGraph(E) );

end proc:

40

Page 41: Graph Theory

khoitao := proc(G::Graph, x0)global m, n, DoDai, Browse, Kt, A;local i, j;A := WeightMatrix(G); n := NumberOfVertices(G);Kt := { }; Browse := array(1..n); DoDai := array(1..n);if not IsConnected(G) then

return ("Do thi nay ko lien thong");end if;for i from 1 to n do

Kt := Kt union {i};Browse[i] := i; DoDai[i] := 999;

end do;for i from 1 to n dofor j from 1 to n do

if A[i, j] = 0 then A[i, j] := 999; end if;end do; end do;DoDai[x0] := 0;HighlightVertex(G, x0, red);

end proc:

with(GraphTheory):with(RandomGraphs):G := RandomGraph( 8, 10, connected, weights = 1..10);khoitao(G, 1)Dijsktra();ve(1);

Dijkstra Algorithm run by hand > with(GraphTheory):G := Graph( { [{1, 2}, 3], [{1, 3}, 24], [{1, 4}, 35], [{1, 5}, 16], [{2, 3}, 5], [{2, 4}, 6], [{2, 5}, 17], [{3, 4}, 7], [{3, 5}, 38], [{4, 5}, 19] } );DrawGraph(G);

41

Page 42: Graph Theory

WeightMatrix(G);

1 2 3 4 51 0 3 24 35 162 3 0 5 6 173 24 5 0 7 384 35 6 7 0 195 16 17 38 19 0

int x1[] = { 0, 3, 24, 35, 16, 3, 0, 5, 6, 17, 24, 5, 0, 7, 38, 35, 6, 7, 0, 19, 16, 17, 38, 19, 0 };int x1[] = { 3, 24, 35, 16, 5, 6, 17, 7, 38, 19};

DijkstrasAlgorithm( G, 1, 4 );[ [1, 2, 3, 4], 15]

Tìm đường đi ngắn nhất từ đỉnh 1 đến đỉnh 4;Step 1: Assign T = X\{x}, the set of vertices of graph.

Initial (khởi động): length[1] = 0; with every k in X \{x}, length[k] = 999.last[k] = 0; mark[k] = 0. - length[k] is the length of path from vertex x to vertex k. last[] is the array to save

the path element. mark[] is the array to mark the elements whether is visited or not.Step 2: If y not in T, Stop.

Choose vertex v in T so that length[v] is min and remove v out of T. mark[v] = 1.Step 3:

With every vertex k in T, and there exist an edge from v to k.If length[k] > length[v] + L(v, k) // weight of edge from v to k.

length[k] = length[v] + L(v, k)last[k] = v.

Continue step 2.

42

Page 43: Graph Theory

Step 2: Choose v = 1, length[1] = 0 is min; mark[1] = 1; T = { 2, 3, 4, 5 };Step 3: The vertices k in T that there exist and edge from 1 to k: 2, 3, 4, 5.

for (i = 1; i <= 5; i++) If (mark[2] != 1) {If (length[2] > length[v] + L(v, k) ) {

// length[2] = 999; length[v] = length[1] = 0; L(v, k) = L(1, 2) = 3;length[2] = length[1] + L(1, 2) = 3;last[2] = 1; }

}if (mark[3] != 1)if (length[3] > length[1] + L(1, 3) )

// length[3] = 999; length[1] = 0; L(1, 3) = 24;length[3] = length[1] + L(1, 3) = 24;last[3] = 1;

}if (mark[4] != 1) {if (length[4] > length[1] + L(1, 4) ) {

// length[4] = 999; length[1] = 0; L(1, 4) = 35;length[4] = length[1] + L(1, 4) = 35;last[4] = 1; }

}if (mark[5] != 1) {if (length[5] > length[1] + L(1, 5) ) {

// length[5] = 999; length[1] = 0; L(1, 5) = 16;length[5] = length[1] + L(1, 5) = 16;last[5] = 1; }

}

Step 2: Choose v = 2, length[2] = 3 is min; mark[2] = 1; T = { 3, 4, 5 };Step 3: The vertices k in T that there exist and edge from 2 to k: 3, 4, 5.

for (i = 1; i <= 5; i++) If (mark[3] != 1)If (length[3] > length[2] + L(2, 3) )

// length[3] = 24; length[2] = 3; L(2, 3) = 5;length[3] = length[1] + L(2, 3) = 8;last[3] = 2;

}If (mark[4] != 1) {If (length[4] > length[2] + L(2, 4) ) {

// length[4] = 35; length[2] = 3; L(2, 4) = 6;length[4] = length[2] + L(2, 4) = 9;last[4] = 2; }

}If (mark[5] != 1) {

43

Page 44: Graph Theory

If (length[5] < length[2] + L(2, 5) ) {// length[5] = 16; length[2] = 3; L(2, 5) = 17;Stop; }

}

Step 2: Choose v = 3, length[3] = 8 is min; mark[3] = 1; T = { 4, 5 };Step 3: The vertices k in T that there exist and edge from 3 to k: 4, 5.

for (i = 1; i <= 5; i++) If (mark[4] != 1) {If (length[4] < length[3] + L(3, 4) )

// length[4] = 9; length[3] = 8; L(3, 4) = 7;Stop; }

}If (mark[5] != 1) {If (length[5] < length[3] + L(3, 5) ) {

// length[5] = 16; length[3] = 8; L(3, 5) = 38;Stop; }

}

Step 2: Choose v = 4, length[4] = 9 is min; mark[4] = 1; T = { 5 };Step 3: The vertices k in T that there exist and edge from 4 to k: 5.

for (i = 1; i <= 5; i++) If (mark[5] != 1) {If (length[5] < length[4] + L(4, 5) ) {

// length[5] = 16; length[4] = 9; L(4, 5) = 19;Stop; }

}

Step 2: If v = 4 == y is not in T. Stop;

The path: void Dijkstra::Printpath (int i) {

cout << endl;if (i == source)

cout << source;else if (last[i] == 0)

cout << "no path from " << source << " to " << i;else {

Printpath (last[i]);cout << "..." << i; }

}Printpath(4); if (last[4] = 2 != 0) Printpath(2);if (last[2] = 1 != 0) Printpath(1);if (i = 1 == source) cout << "..." << i;

44

Page 45: Graph Theory

1 → 2 → 4.

Bellman-Ford Algorithm- Step 1: Initialize: P[0][x] = 0; P[0][i] = 9999, with every i ≠ x, k = 1.- Step 2: With every vertex i in X, we calculate:P[k][i] = min ( { P[k-1][i] }, { P[k-1][j] + L[i][j] ). There exists path from i to j.

L[i][j] is the weight matrix.- Step 3: If row k and row k-1 of matrix P are equal then P[k][i] is the length of

shortest path from x to i.If row k and row k-1 of matrix P are different

If k < n then increasing k = k + 1 and returning Step 2.If k == n then stopping cause graph have negative path.

#include <iostream.h>#include <stdio.h> #include <stdlib.h>#define MAX 20

class bell_ford {private:int n; int graph[MAX][MAX]; int start;int distance[MAX]; int pre[MAX];public:void read_graph();void initialize();void update();void check();void algorithm();

};void bell_ford::read_graph() {

int i, j, k; n = 5; k = 0;int x1[] = { 3, 24, 35, 16, 5, 6, 17, 7, 38, 19 };for (i = 1; i <= n; i++)for (j = i+1; j <= n; j++) {

graph[j][i] = graph[i][j] = x1[k]; k++; }for (i = 1; i <= n; i++)

graph[i][i] = 0;for (i = 1; i <= n; i++) {

for (j = 1; j <= n; j++) {printf ("%d ", graph[i][j]); }

printf ("\n"); }cout << "Enter the start vertex ::";

45

Page 46: Graph Theory

cin >> start;}void bell_ford::initialize() {

int i; for (i = 1; i <= 5; i++) {

distance[i] = 9999;pre[i] = 0;

} distance[start] = 0;}void bell_ford::update() {

int i, u, v;printf ("update \n");for (u = 1; u <= n; u++) for (v = 1; v <= n; v++)

if (graph[u][v] != 0) {if (distance[v] > distance[u] + graph[u][v]) {

printf ("\n if (distance[%d] > distance[%d] + graph[%d][%d] ) \n", v, u, u, v);

printf ("distance[%d] = %d, distance[%d] = %d \n", v, distance[v], u, distance[u]);

printf ("graph[%d][%d] = %d \n", u, v, graph[u][v]);distance[v] = distance[u] + graph[u][v];printf ("distance[%d] = distance[%d] + graph[%d][%d] = %d \n", v, u, u, v,

distance[v]);pre[v] = u;printf ("pre[%d] = %d \n", v, u);

} else {

printf ("\n if (distance[%d] < distance[%d] + graph[%d][%d] ) \n", v, u, u, v);

printf ("distance[%d] = %d, distance[%d] = %d \n", v, distance[v], u, distance[u]);

printf ("graph[%d][%d] = %d \n", u, v, graph[u][v]);printf ("continue \n");

}}

}void bell_ford::check () {

int i, j, u, v; printf ("Check Function \n");for (u = 1; u <= n; u++) for (v = 1; v <= n; v++) {

if (graph[u][v] != 0) {if (distance[v] > distance[u] + graph[u][v]) {

cout << "does not exist's ";

46

Page 47: Graph Theory

return;} } }

cout << "\n\n There is no negative weight cycle and \n";cout << "The final paths and the distances are \n";for (i = 1; i <= n; i++) {

cout << "path for node " << i << " is ::\n";int arr[MAX], k = 1; j = i;while (pre[j] != 0) {

printf ("while pre[%d] != 0 \n", j);arr[k] = pre[j]; k++;printf ("arr[%d] = pre[%d] = %d \n", k-1, j, arr[k-1]);printf ("j = pre[%d] = %d, k = %d \n", j, pre[j], k);j = pre[j];

}for (k = k - 1; k > 0; k--)

printf ("arr[%d] = %d -> ", k, arr[k]);cout << i << endl;cout << "distance is " << distance[i] << endl << endl;

}}void bell_ford::algorithm() {

read_graph(); initialize();update(); check();

}int main() {

bell_ford obj;obj.algorithm();

}

BellmanFord Code 2.#include <stdio.h>#include <stdlib.h>#include <iostream.h>

struct Edge{int source;int dest;int weight;

};void BellmanFord (Edge edges[], int edgecount, int nodecount, int source) {

int *d = new int [nodecount + 1];int i, j, k1, k2, k3, d1;for (i = 0; i <= nodecount; i++)

d[i] = 9999;

47

Page 48: Graph Theory

d[source] = 0;for (i = 0; i < edgecount; i++) {

k1 = edges[i].source; k2 = d[edges[i].source];k3 = edges[i].dest;if (d[edges[i].source] != 9999) {

printf ("\n if (d[%d] = %d != 9999) \n", k1, k2);d1 = d[edges[i].source] + edges[i].weight;printf ("d1 = d[%d] + edges[%d].weight = %d \n", k1, i, d1);printf ("edges[%d].source = %d \n", i, k1);printf ("edges[%d].dest = %d \n", i, k3);printf ("edges[%d].weight = %d \n", i, edges[i].weight);if (d1 < d[edges[i].dest]) {

printf ("if (d1 = %d < d[%d] = %d) \n", d1, k3, d[k3]);d[edges[i].dest] = d1;printf ("d[%d] = %d \n", k3, d1);

}else {

printf ("if (d1 = %d > d[%d] = %d) \n", d1, k3, d[k3]);printf ("continue \n");

}}

}for (i = 0; i < edgecount; i++)

if (d[edges[i].dest] > d[edges[i].source] + edges[i].weight) {printf ("Negative edge weight cycles detected!");free(d);return;

} for (i = 1; i <= nodecount; i++) {

printf ("The shortest distance between nodes %d and %d is %d \n",source, i, d[i]);

}free(d);return;

}int main() {

Edge edges[10] = { {1, 2, 3}, {1, 3, 24}, {1, 4, 35}, {1, 5, 16}, {2, 3, 5}, {2, 4, 6}, {2, 5, 17}, {3, 4, 7}, {3, 5, 38}, {4, 5, 19} };

BellmanFord (edges, 10, 5, 1);return 0;

}

Bellman-Ford run by hand > with(GraphTheory):

48

Page 49: Graph Theory

G := Graph( { [{1, 2}, 3], [{1, 3}, 24], [{1, 4}, 35], [{1, 5}, 16], [{2, 3}, 5], [{2, 4}, 6], [{2, 5}, 17], [{3, 4}, 7], [{3, 5}, 38], [{4, 5}, 19] } );DrawGraph(G);

BellmanFordAlgorithm( G, 1, 4);

Edge edges[10] = { {1, 2, 3}, {1, 3, 24}, {1, 4, 35}, {1, 5, 16}, {2, 3, 5}, {2, 4, 6}, {2, 5, 17}, {3, 4, 7}, {3, 5, 38}, {4, 5, 19} };

- Step 1: Initialize distance[i] = 9999 with every i ≠ 1.distance [1] = 0; pre[i] = 0 with every i in X (set of vertices).

- Step 2: for (u = 1; u <= n; u++) for (v = 1; v <= n; v++)

if (graph[1][2] == 3 != 0) if (distance[2] > distance[1] + graph[1][2])distance[2] = 9999; distance[1] = 0; graph[1][2] = 3;distance[2] = distance[1] + graph[1][2] = 3.pre[2] = 1;

if (graph[1][3] == 24 != 0) if (distance[3] > distance[1] + graph[1][3])distance[3] = 9999; distance[1] = 0; graph[1][3] = 24;distance[3] = distance[1] + graph[1][3] = 24.pre[3] = 1;

if (graph[1][4] == 35 != 0) if (distance[4] > distance[1] + graph[1][4])distance[4] = 9999; distance[1] = 0; graph[1][4] = 35;distance[4] = distance[1] + graph[1][4] = 35.pre[4] = 1;

49

Page 50: Graph Theory

if (graph[1][5] == 16 != 0) if (distance[5] > distance[1] + graph[1][5])distance[5] = 9999; distance[1] = 0; graph[1][5] = 16;distance[5] = distance[1] + graph[1][5] = 16.pre[5] = 1;

if (graph[2][1] == 3 != 0) if (distance[1] < distance[2] + graph[2][1])distance[1] = 0; distance[2] = 3; graph[2][1] = 3;continue;

if (graph[2][3] == 5 != 0) if (distance[3] > distance[2] + graph[2][3])distance[3] = 24; distance[2] = 3; graph[2][3] = 5;distance[3] = distance[2] + graph[2][3] = 8.pre[3] = 2;

if (graph[2][4] == 6 != 0) if (distance[4] > distance[2] + graph[2][4])distance[4] = 35; distance[2] = 3; graph[2][4] = 6;distance[4] = distance[2] + graph[2][4] = 9.pre[4] = 2;

if (graph[2][5] == 17 != 0) if (distance[5] < distance[2] + graph[2][5])distance[5] = 16; distance[2] = 3; graph[2][5] = 17;continue;

path for node 3 is:while (pre[j] != 0)arr[1] = pre[j] = pre[3] = 2;j = pre[3] = 2;arr[1] = pre[2] = 1;1 → 2 → 3; distance = 8.

Floyd Code#include <stdio.h>#include <stdlib.h>#include <string>/* Floyd's All pairs shortest path algorithm (O (n^3) ).

input is adjacency matrix output is matrix of shortest paths.C is the adjacency matrix.n is the order of the square matrix.

50

Page 51: Graph Theory

A is the all pairs shortest paths matrix.we assume that A is allocated by the caller. */

int Floyd (int *A, int n) {int i, j, k;// for each route via k from i to j pick any better routes and// replace A[i][j] path with sum of paths i-k and j-kfor (k = 0; k < n; k++) for (i = 0; i < n; i++)

for (j = 0; j < n; j++)if ( A[i*n + k] + A[k*n + j] < A[i*n + j]) {

// A[i][j] = A[i][k] + A[k][j];A[i*n + j] = A[i*n + k]+ A[k*n + j];

}return 0;

} void FloydTest() {

int n = 5, i, j, k; k = 0;int *C = new int[n*n];int x1[] = { 3, 24, 35, 16, 5, 6, 17, 7, 38, 19 };for (i = 0; i < n; i++)for (j = i+1; j < n; j++) {

C[j*n + i] = C[i*n + j] = x1[k]; k++; }for (i = 0; i < n; i++)

C[i*n + i] = 0;for (i = 0; i < n; i++) {

for (j = 0; j < n; j++) {printf ("%d ", C[i*n + j]); }

printf ("\n"); }int *A = new int[n*n];for (i = 0; i < n; i++) for (j = 0; j < n; j++)

if ( C[i*n + j] == 0) {A[i*n + j] = 9999; // Does this look like infinity?

}else {

A[i*n + j] = C[i*n + j];}

// set the diagonals to zerofor (i = 0; i < n; i++) {

A[i*n + i] = 0; }Floyd (A, n);for (i = 0; i < n; i++)

for (j = i+1; j < n; j++) {printf ("path from %d to %d is %d\n", i+1, j+1, A[i*n+j]);

51

Page 52: Graph Theory

} printf("\n");delete []A; delete []C;

} int main() { FloydTest();}

Code Maple Floyd 1with(GraphTheory):G := Graph( { [{1, 2}, 3], [{1, 3}, 24], [{1, 4}, 35], [{1, 5}, 16], [{2, 3}, 5], [{2, 4}, 6], [{2, 5}, 17], [{3, 4}, 7], [{3, 5}, 38], [{4, 5}, 19] } );DrawGraph(G);

Floyd := proc(G::Graph)local i, j, k, n, A, B; A := WeightMatrix(G); n := NumberOfVertices(G);B := Matrix(n);if not IsConnected(G) then

return ("Do thi nay ko lien thong");end if;for i from 1 to n dofor j from 1 to n do

if A[i, j] > 0 then for k from 1 to n do

if A[i, k] > 0 then if A[j, k] < A[j, i] + A[i, k] then

B[j, k] := A[j, i] + A[i, k]; end if;end if;

end do; end if;

end do; end do; return B;

end proc:A := Floyd(G);

Code Maple Floyd 2with(GraphTheory): with(RandomGraphs):Floyd := proc(G::Graph)

local M, M1, M2, i, j, a, n, k;M := WeightMatrix(G); n := NumberOfVertices(G);k := 1; M1 := Matrix( M, datatype = anything); M2 := Matrix(n);for i from 1 to n dofor j from 1 to n do

52

Page 53: Graph Theory

if [i, j] ∉ Edges(G) and i != j then M1[i, j] := ∞else M2[i, j] := j; end if;

end do; end do;while (k ≤ n) do

for i from 1 to n dofor j from 1 to n do

a := M1[i, k] + M1[k, j]; if (a < 0) and (i = j) then

error "Co mach am"; end if; if (M1[i, j] > a) then

M1[i, j] := a; M2[i, j] := M2[i, k]; end if;end do; end do; k := k + 1;

end do;print( M1, M2 );

end proc:

G1 := RandomDigraph( 5, 10, weights = -10..10 ); DrawGraph(G1); Floyd(G1);

Chu trình EulerEuler CycleFleury Algorithm for finding an Euler Cycle

- Starting from arbitrary vertex and using two following rules:- Rule 1: Remove the edges were browsed and isolated vertices (điểm cô lập).- Rule 2: At every vertices, we only use one path.

> with(GraphTheory):with(SpecialGraphs):G := CompleteGraph(5);DrawGraph(G);

53

Page 54: Graph Theory

IsEulerian( G, 'T');true;

T = Trail( 1, 2, 3, 1, 4, 2, 5, 3, 4, 5, 1);

- Starting from vertex 1; Trong số các đỉnh kề với đỉnh 1 thì đỉnh 2 là đỉnh nhỏ nhất và cạnh {1, 2} chưa qua, thêm cạnh {1, 2} vào T.

- Trong số các đỉnh kề với đỉnh 2 thì đỉnh 3 là đỉnh nhỏ nhất và cạnh {2, 3} chưa qua, thêm cạnh {2, 3} vào T.

- Trong số các đỉnh kề với đỉnh 3 thì đỉnh 1 là đỉnh nhỏ nhất và cạnh {3, 1} chưa qua, thêm cạnh {3, 1} vào T.

- Trong số các đỉnh kề với đỉnh 1 thì đỉnh 4 là đỉnh nhỏ nhất và cạnh {1, 4} chưa qua, thêm cạnh {1, 4} vào T.

- Trong số các đỉnh kề với đỉnh 4 thì đỉnh 2 là đỉnh nhỏ nhất và cạnh {4, 2} chưa qua, thêm cạnh {4, 2} vào T.

DeleteEdge(G, { {1, 2}, {2, 3}, {3, 1}, {1, 4}, {4, 2} } );DrawGraph(G);

Euler Cycle Maple Code 1 with(GraphTheory):with(RandomGraphs):Euler := proc(G::Graph, x0)

global n, Result, A, B, t1; local i, j, t, x, Kt;x:= x0; Kt := { }; Kt := { op( Neighbors(G, x) ) }; for i in Kt do

if B[x, i] != 0 then Result[t1] := i; t1 := t1 + 1;B[x, i] := 0; B[i, x] := 0; Euler(G, i);

end if;end do;

end proc:

54

Page 55: Graph Theory

main := proc(G::Graph, x0)global n, A, B, t1, Result; local i, t;n := NumberOfVertices(G); t := 0; A := AdjacencyMatrix(G); Result := array(1..n.n); B := A; t1 := 2;print( DrawGraph(G) );if not IsConnected(G) then

return ("Do thi nay ko lien thong");end if;for i in Vertices(G) do

if (Degree(G, i) mod 2 = 1) then t := t + 1; end if;

end do; if (t != 0 and (t != 2 or (Degree(G, x0) mod 2) = 0 ) ) then

error ("Dont have any Euler"); end if; for i from 1 to n.n do

Result[i] := 0; end do;Euler(G, x0); Result[1] := x0;print( Result );

end proc:

G1 := RandomGraph(5, 8, Connected); DrawGraph(G1); main(G1, 4);

Euler Cycle Maple Code 2 with(GraphTheory): with(RandomGraphs): with(LinearAlgebra): Euler := proc(G::Graph, x0)

local M, n, t, i, Road, Stack, x, X, k; # M: Ma trận kề, n: số đỉnh của đồ thị G, Road: biểu diễn đường đi Euler.# Stack: ngăn xếp, x: phần tử cuối của Road, X: tập hợp.# k: số phần tử của Stack.if (IsConnected(G) = false or IsDirected(G) = true) then

error ("Data Error"); end if; M := AdjacencyMatrix(G); t := 0;n := nops( Vertices(G) ); print(n);for i in Vertices(G) do

if (Degree(G, i) mod 2 = 1) then t := t + 1; end if;

end do; if (t != 0 and (t != 2 or (Degree(G, x0) mod 2) = 0 ) ) then

error ("Dont have any Euler"); end if;

55

Page 56: Graph Theory

Stack := Matrix([x0]); X := { };Road := Matrix([ ]);while Equal( Stack, Matrix([ ]) ) = false do

k := ArrayNumElems(Stack);x := Stack( 1, k ); i := 1;while (i < n + 1) and (M(x, i) = 0 or (M(x, i) = 1 and i ∈ X) ) do

i := i + 1;if (i = n + 1) then break; end if;

end do; if (i < n + 1) then

Stack := <Stack|i>;M[i, x] := 0; else if Equal( M, AdjacencyMatrix(G) ) then

M[ Stack( k ), Stack( k - 1 ) ] := 1;end if;Road := <Stack( 1, k ) | Road>; X := X union { Stack( k ) }; Stack := DeleteColumn( Stack, [k] );

end if; end do;print(Road);

end proc:

G1 := RandomGraph(5, 8, Connected); DrawGraph(G1); Euler(G1, 4);

Stack: with(LinearAlgebra): Stack := Matrix([3]);Stack := <Stack | 5>; # Thêm phần tử 5 vào Stack;Stack := <Stack | 7>; k := ArrayNumElems(Stack): # k là số phần tử của Stack;i := Stack(1, k): # i là phần tử cuối của Stack;j := Stack(1, 1): # i là phần tử đầu của Stack;print(`k = `, k, `i = `, i, `j = `, j);Stack := DeleteColumn( Stack, [k] ); # Delete phần tử cuối của Stack;

s := stack[new](1, 2, 3): # Khởi tạo Stack.stack[push]( 7, s ): # Thêm phần tử 7 vào Stack;print(s);k := stack[depth](s); # k là số phần tử của Stack;

56

Page 57: Graph Theory

i := stack[pop](s); # i là phần tử cuối của Stack;

with(GraphTheory):with(RandomGraphs):G := CompleteGraph(7);DrawGraph(G);

IsEulerian(G, ‘T’);T

Trail( 1, 2, 3,/ 1, 4, 2, 5,/ 1, 6, 2, 7,/ 3, 4, 5, 3,/ 6, 4, 7, 5,/ 6, 7, 1)1 2 3 4 5 6 7

1 0 1 1 1 1 1 12 0 1 1 1 1 13 0 1 1 1 14 0 1 1 15 0 1 16 0 17 0

int x[] = { 1, 1, 1, 1, 1, 1, / 1, 1, 1, 1, 1, / 1, 1, 1, 1, / 1, 1, 1, 1, 1, 1 };int x[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };

Euler Cycle C++ Code #include <stdio.h> #include <stack.h>int Matrix[100][100]; int n;void Create() {

int i, j, k1; n = 7; k1 = 0;int x[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };for (i = 0; i < n; i++)for (j = i+1; j < n; j++) {

57

Page 58: Graph Theory

Matrix[j][i] = Matrix[i][j] = x[k1]; k1++; }for (i = 0; i < n; i++)

Matrix[i][i] = 0; for (i = 0; i < n; i++) {

for (j = 0; j < n; j++) printf ("%5d", Matrix[i][j]);

printf("\n");} printf("\n");

}/* chu trinh Euler bang phuong phap stack1. Tim duong di tai 1 diem: Kiem tra xem so bac le co = 2 khong2. Tim duong di tai tat cac cac diem : dung phuong phap de quy */int KiemTra() {

int i, j, d, s; d = 0;for(i = 0; i < n; i++) {

s = 0;for (j = 0; j < n; j++)

s += Matrix[i][j];if (s % 2 != 0) d++; // Kiem tra xem la so dinh bac co chan hay khong neu

khong thi d++}if (d > 0)

return (false);return (true);

}void Euler() {

int dCE = -1; // vi xet khoang tu 0 -> n-1;stack <int> myStack;int CE[100]; // Cycle Euler dung de luu nhung phan tu lay tu ngan xep.int v, x, u; u = 0; // Chon u = 0 de ta lay diem bat dau la so 1. myStack.push(u);do {

v = myStack.top(); // chon x lam phan tu dau.x = 0;while (x < n && Matrix[v][x] == 0)

x++;if (x >= n) {

dCE++; CE[dCE] = v;myStack.pop();

}else {

myStack.push(x);Matrix[v][x] = 0; Matrix[x][v] = 0; // xoa cac canh di

}} while (!myStack.empty());

58

Page 59: Graph Theory

printf ("Co chu trinh Euler \n");for (int i = dCE; i>= 0; i--)

printf ("%5d", CE[i]+1);}int main() {

Create();if(KiemTra())

Euler();else

printf ("Khong co chu trinh Euler \n");}

with(GraphTheory):with(RandomGraphs):G := CompleteGraph(5);DrawGraph(G);

IsEulerian(G, ‘T’);T

Trail(1, 2, 3, 1, 4, 2, 5, 3, 4, 5, 1);1 2 3 4 5

1 0 1 1 1 12 0 1 1 13 0 1 14 0 15 0

int x[] = { 1, 1, 1, 1, / 1, 1, 1, / 1, 1, 1};int x[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};

Chu trình HamiltonQuy tắc xác định đồ thị Hamilton

59

Page 60: Graph Theory

- Rule 1: Tất cả các cạnh kề với 1 đỉnh bậc 2 phải ở trong H.- Rule 2: Ko có chu trình con nào (chu trình có chiều dài nhỏ hơn n) được tạo

thành trong quá trình xây dựng H.- Rule 3: Khi chu trình Hamiltom mà ta đang xây dựng đi qua đỉnh i thì xóa tất cả

cạnh kề với i mà chưa đi qua. Điều này có thể cho ta 1 số đỉnh bậc 2 và ta lại có thể dùng quy tắc 1.

- Rule 4: Ko có đỉnh cô lập hay cạnh treo nào được tạo nên sau khi dùng quy tắc 3.

Hamilton Maple Code

with(GraphTheory):with(SpecialGraphs):with(RandomGraphs):Hamilton := proc(G::Graph)

global n, M, Road, check, Kt; local i, k, E;n := NumberOfVertices(G); E := Graph(n);DrawGraph(G); check := false;M := AdjacencyMatrix(G); Road := array(1..n); k := 1;for i from 1 to n do

if check = true then break;

else Kt := {i}; Road[1] := i; Browse(i, 1);

end if;end do;if check = false then

error "Ko ton tai duong di Hamilton";else

for i from 1 to n-1 do AddEdge( E, { Road[i], Road[i+1] } );

end do;HighlightEdges(G, E, red);print( DrawGraph(G) ); print(Road);

end if;end proc:

Browse := proc(x0, k) global M, Road, Kt, check; local i;if k = n then

check := true; end if; if check = false then

for i from 1 to n doif i ∉ Kt and M(x0, i) != 0 then

60

Page 61: Graph Theory

Kt := Kt union {i}; if check = false then Road[k+1] := i; end if;Browse(i, k+1); Kt := Kt \ {i};

end if;end do;

end if;end proc:

G1 := PetersenGraph(); AddEdge(G1, {1, 3});Hamilton(G1);

> with(GraphTheory):with(SpecialGraphs):G := PetersenGraph();AddEdge(G, {1, 3});DrawGraph(G);

IsHamiltonian(G, 'T');T = { 1, 2, 9, 8, 5, 4, 10, 6, 7, 3, 1 }

Đỉnh 1 2 3 4 5 6 7 8 9 10

61

Page 62: Graph Theory

1 0 1 1 0 1 1 0 0 0 02 0 1 0 0 0 0 0 1 03 0 1 0 0 1 0 0 04 0 1 0 0 0 0 15 0 0 0 1 0 06 0 1 0 0 17 0 1 0 08 0 1 09 0 10 0

int x[] = { 1, 1, 0, 1, 1, 0, 0, 0, 0, / 1, 0, 0, 0, 0, 0, 1, 0, / 1, 0, 0, 1, 0, 0, 0, / 1, 0, 0, 0, 0, 1, / 0, 0, 1, 0, 0, / 1, 0, 0, 1, / 1, 0, 0, 1, 0, 1 };int x[] = { 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1 };

Code Hamilton C++#include <stdio.h>#define max 20int a[max][max];int Mark[max], c[max];int n;void Create() {

int i, j, k1; n = 10; k1 = 0;int x[] = { 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0,

1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1 }; for (i = 0; i < n; i++)

for (j = i+1; j < n; j++) {a[j][i] = a[i][j] = x[k1]; k1++; }

for (i = 0; i < n; i++)a[i][i] = 0;

for (i = 0; i < n; i++) Mark[i] = 0;c[0] = 0; Mark[0] = 1; // Xuat phat tu dinh 0.

}void ShowPath() {

for (int k = 0; k < n; k++) printf ("%4d", c[k]+1); // In ra số hiệu đỉnh + 1

printf ("%4d \n", c[0]+1);}void Hamilton(int k) {

for (int i = 0; i < n; i++)if (Mark[i] == 0 && a [ c[k-1] ] [i] != 0) {

Mark[i] = 1; c[k] = i;if (k == n-1) {

62

Page 63: Graph Theory

if (a [ c[k]] [c[0] ] != 0) ShowPath();}else Hamilton(k+1);Mark[i] = 0;

}}int main() {

Create();Hamilton(1);

}

void Hamilton(int k) {for (int i = 0; i < n; i++)

if (Mark[i] == 0 && a [ c[k-1] ] [i]) { // Nếu đỉnh k chưa duyệt đến và có nối với đỉnh vừa được ghi nhận trước đó (thứ j-1, số hiệu là c[j-1])

Mark[i] = 1; c[k] = i; // Xem như duyệt đỉnh k và nó là đỉnh thứ j theo trình tự ghi nhận.

if (k == n-1) { // Nếu đã ghi nhận đủ số đỉnhif (a [c[k]] [c[0]] != 0) ShowPath(); // Nếu đỉnh cuối có nối với đỉnh đầu

tiên thì hiển thị chu trình. }else Hamilton(k+1); // Nếu chưa ghi nhận đủ n đỉnh thì đệ quy để tìm đỉnh

thứ j+1.Mark[i] = 0; // Quay lui chính là chỗ này đây.

}}

IsHamiltonian(G, 'T');T = { 1, 2, 9, 8, 5, 4, 10, 6, 7, 3, 1 }

- Bắt đầu từ đỉnh 1, lấy cạnh {1, 2}, {1, 3}, xóa cạnh {1, 6}, {1, 5} (do đã lấy 2 cạnh kề với đỉnh 1). Lấy {2, 3} sẽ tạo thành chu trình {1, 2, 3}, xóa cạnh {2, 3}.

63

Page 64: Graph Theory

G := DeleteEdge(G, { {1, 6}, {1, 5}, {2, 3} } );DrawGraph(G);

- Các đỉnh 5, 6 trở thành đỉnh bậc 2, lấy cạnh {5, 4}, {5, 8}, {6, 7}, {6, 10}. - Lấy cạnh {2, 9} để có liên thông. Ta có chu trình { 9, 10, 6, 7, 8, 9 }; Trong đó ta

đã lấy cạnh {6, 7}, {6, 10} vậy bỏ cạnh {7, 8}.

G := DeleteEdge(G, {7, 8} );DrawGraph(G);

- Giờ ta có đỉnh 7 và đỉnh 8 là đỉnh bậc 2. Lấy cạnh {7, 6}, {7, 3}, {8, 5}, {8, 9}.- Ta có chu trình {1, 3, 4, 5, 8, 9, 2, 1} bậc 7 nhỏ hơn 10, vậy xóa cạnh {3, 4} vì

các cạnh khác đã add.- Ta cũng có chu trình { 9, 10, 6, 7, 3, 1, 2, 9} bậc 7 nhỏ hơn 10, vậy xóa cạnh

{9, 10} vì các cạnh khác đã add.

G := DeleteEdge(G, { {3, 4}, {9, 10} } );DrawGraph(G);

64

Page 65: Graph Theory

Chu trình 2:> with(GraphTheory):with(SpecialGraphs):G := PetersenGraph();AddEdge(G, {1, 3});DrawGraph(G);

IsHamiltonian(G, 'T');T = { 1, 2, 9, 8, 5, 4, 10, 6, 7, 3, 1 }

- Bắt đầu từ đỉnh 1, lấy cạnh {1, 2}, {1, 3}, xóa cạnh {1, 6}, {1, 5} (do đã lấy 2 cạnh kề với đỉnh 1). Lấy {2, 3} sẽ tạo thành chu trình {1, 2, 3}, xóa cạnh {2, 3}.

G := DeleteEdge(G, { {1, 6}, {1, 5}, {2, 3} } );DrawGraph(G);

65

Page 66: Graph Theory

- Các đỉnh 5, 6 trở thành đỉnh bậc 2, lấy cạnh {5, 4}, {5, 8}, {6, 7}, {6, 10}. - Lấy cạnh {2, 9} để có liên thông. Ta có chu trình { 9, 10, 6, 7, 8, 9 }; Trong đó ta

đã lấy cạnh {6, 7}, {6, 10} vậy bỏ cạnh {8, 9}.

G := DeleteEdge(G, { {1, 6}, {1, 5}, {2, 3}, {8, 9} } );DrawGraph(G);

- Giờ ta có đỉnh 8 và đỉnh 9 là đỉnh bậc 2. Lấy cạnh {8, 5}, {8, 7}, {9, 2}, {9, 10}.- Ta có chu trình {3, 4, 5, 8, 7, 3} bậc 5 nhỏ hơn 10, vậy xóa cạnh {7, 3} vì các

cạnh khác đã add.

G := DeleteEdge(G, { {1, 6}, {1, 5}, {2, 3}, {8, 9}, {3, 7} } );DrawGraph(G);

66

Page 67: Graph Theory

- Ta còn chu trình { 6, 7, 8, 5, 4, 10, 6 } bậc 6 nhỏ hơn 10, vậy xóa cạnh {4, 10}.

G := DeleteEdge(G, { {1, 6}, {1, 5}, {2, 3}, {8, 9}, {3, 7}, {4, 10} } );DrawGraph(G);

- Ta có chu trình { 1, 2, 9, 10, 6, 7, 8, 5, 4, 3, 1 }.

Dijsktra 2> with(GraphTheory):G := Graph( { [{1, 3}, 7], [{1, 4}, 3], [{1, 6}, 5], [{1, 7}, 8], [{2, 4}, 4], [{3, 2}, 6], [{3, 4}, 2], [{3, 6}, 8], [{3, 7}, 5], [{4, 5}, 6], [{5, 7}, 4] } );DrawGraph(G);

67

Page 68: Graph Theory

Tìm đường đi ngắn nhất từ đỉnh 2 đến các đỉnh còn lại:2 → 3 = 6; 2 → 4 = 4; 2 → 4 → 3 = 6; 2 → 3 = 62 → 3 → 1 = 13; 2 → 4 → 1 = 7; 2 → 1 = 72 → 3 → 6 = 14;2 → 3 → 7 = 11;2 → 4 → 5 = 10;

Bước Đỉnh 1 Đỉnh 3 Đỉnh 4 Đỉnh 5 Đỉnh 6 Đỉnh 7Đỉnh chọn

1 (∞, –) (6, 2) (4, 2) (∞, –) (∞, –) (∞, –) 22 (7, 4) (6, 2) (6, 2) (10, 4) (∞, –) (∞, –) 43 (7, 4) (6, 2) – (10, 4) (14, 3) (11, 3) 34 (7, 4) – – (10, 4) (14, 3) (11, 3) 15 – – – (10, 4) (14, 3) (11, 3) 56 – – – – (14, 3) (11, 3) 77 (14, 3) – 6

Kết quả (7, 4) (6, 2) (6, 2) (10, 4) (14, 3) (11, 3)

Đường đi ngắn nhất từ đỉnh 2 đến đỉnh 1 là 7 và đi qua đỉnh 4.Đường đi ngắn nhất từ đỉnh 2 đến đỉnh 3 là 6 và đi qua đỉnh 2.Đường đi ngắn nhất từ đỉnh 2 đến đỉnh 4 là 6 và đi qua đỉnh 2.Đường đi ngắn nhất từ đỉnh 2 đến đỉnh 5 là 10 và đi qua đỉnh 4.Đường đi ngắn nhất từ đỉnh 2 đến đỉnh 6 là 14 và đi qua đỉnh 3.Đường đi ngắn nhất từ đỉnh 2 đến đỉnh 7 là 11 và đi qua đỉnh 3.

Tìm cây khung tối thiểu của G bằng thuật toán Prims

68

Page 69: Graph Theory

- Bắt đầu từ đỉnh 1, các đỉnh kề với đỉnh 1 là 3, 4, 6, 7. Cạnh {1, 4} có độ dài 3 là min, thêm cạnh {1, 4} vào T.

- Các đỉnh kề với đỉnh 1, 4 là 3, 6, 7, 2, 5. Cạnh {4, 3} có độ dài 2 là min, thêm cạnh {4, 3} vào T.

- Cạnh {4, 2} có độ dài 4 là min, thêm cạnh {4, 2} vào T.- Cạnh {1, 6} có độ dài 5 là min, thêm cạnh {1, 6} vào T.- Cạnh {3, 7} có độ dài 5 là min, thêm cạnh {3, 7} vào T.- Cạnh {7, 5} có độ dài 4 là min, thêm cạnh {7, 5} vào T. Đủ 6 cạnh.- T = { {1, 4}, {4, 3}, {4, 2}, {1, 6}, {3, 7}, {7, 5} }

Có thể nào di chuyển con mã trên một bàn cờ vua 4x4 đi qua tất cả các ô của bàn cờ, mỗi ô một lần và trở về ô xuất phát không?Đồ thị Hamilton1 2 3 45 6 7 89 10 11 1213 14 15 16

G ko Hamilton vì có chu trình con nhỏ hơn 16: {7, 16, 10, 8, 2, 9, 7}

69

Page 70: Graph Theory

'

70