graph theory
TRANSCRIPT
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
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
> 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
> 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
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
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
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
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
> 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
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
> 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
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
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
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
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
> with(GraphTheory):with(SpecialGraphs):G := GeneralizedPetersenGraph(7, 2);DrawGraph(G);
> with(GraphTheory):with(SpecialGraphs):G := WheelGraph(6);DrawGraph(G);
16
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
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
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
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
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
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
- 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
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
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
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
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
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
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
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
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
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
- 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
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
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
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
// 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
#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
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
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
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
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
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
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
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
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
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
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
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
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
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
} 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
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
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
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
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
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
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
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
- 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
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
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
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
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
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
- 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
- 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
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
- 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
'
70