0% found this document useful (0 votes)
46 views11 pages

Lab 09

This document contains code defining classes and methods for working with graphs represented as adjacency matrices and lists. It includes methods for loading graph data from files into matrices and lists, printing the representations, and determining if a graph has an Euler circuit or trail. A main method instantiates examples and calls solving methods. Classes are defined to represent graph problems and solve them by analyzing the graph structures.

Uploaded by

Đào Tune
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
46 views11 pages

Lab 09

This document contains code defining classes and methods for working with graphs represented as adjacency matrices and lists. It includes methods for loading graph data from files into matrices and lists, printing the representations, and determining if a graph has an Euler circuit or trail. A main method instantiates examples and calls solving methods. Classes are defined to represent graph problems and solve them by analyzing the graph structures.

Uploaded by

Đào Tune
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 11

using System;

using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Lab09
{
internal class Program
{
static void Main(string[] args)
{
Ex1 ex1 = new Ex1("E:\\LTĐT\\Text\\EulerVoHuong.INP");
ex1.Solve("E:\\LTĐT\\Text\\EulerVoHuong.OUT");
/* Ex2 ex2 = new Ex2("E:\\LTĐT\\Text\\EulerCoHuong.INP");
ex2.Solve("E:\\LTĐT\\Text\\EulerCoHuong.OUT");
Ex3 ex3 = new Ex3("E:\\LTĐT\\Text\\ChuTrinhEuler.INP");
ex3.Solve("E:\\LTĐT\\Text\\ChuTrinhEuler.OUT");
Ex4 ex4 = new Ex4("E:\\LTĐT\\Text\\kNet.OUT");
ex4.Solve("E:\\LTĐT\\Text\\kNet.OUT");*/
}
}
}
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Lab09
{
internal class GT
{
public static int[,] LoadAdjMatrix(string path)// Hàm load ma trận kề
{
if (!File.Exists(path))// kiểm tra file không tồn tại thì throw
{
throw new FileNotFoundException(path);
}
string[] lines = File.ReadAllLines(path);// khai báo mảng string lines đọc tất cả dữ liệu từ file
int v = int.Parse(lines[0]);
int[,] adjMatrix = new int[v, v];
for (int i = 0; i < v; i++)
{
string[] number = lines[i + 1].Split();
for (int j = 0; j < v; j++)
{
adjMatrix[i, j] = int.Parse(number[j]);
}
}
return adjMatrix;
}

public static void PrintAdjMatrix(int[,] adjMatrix)// hàm in ma trận kề


{
Console.WriteLine(adjMatrix.GetLength(0));
for (int i = 0; i < adjMatrix.GetLength(0); i++)
{
for (int j = 0; j < adjMatrix.GetLength(1); j++)
{
Console.Write(adjMatrix[i, j] + " ");
}
Console.WriteLine();
}
}

public static LinkedList<int>[] LoadAdjList(string path)//hàm load danh sách kề


{
if (!File.Exists(path))
{
throw new FileNotFoundException(path);
}
string[] lines = File.ReadAllLines(path);
int v = int.Parse(lines[0]);
LinkedList<int>[] adjList = new LinkedList<int>[v];//khai báo danh sách kề với số phần tử bằng v
for (int i = 0; i < v; i++)
{
adjList[i] = new LinkedList<int>();
if (lines[i + 1] == "")
{
continue;
}
string[] numbers = lines[i + 1].Split();
foreach (string number in numbers)
{
adjList[i].AddLast(int.Parse(number));
}
}
return adjList;
}

public static LinkedList<int>[] LoadAdjList(string path, out int[] args)


{
if (!File.Exists(path))
{
throw new FileNotFoundException(path);
}
string[] lines = File.ReadAllLines(path);
string[] p = lines[0].Split();// khai báo mảng string p bắng giá trị đầu tiên của mảng line được cắt ra
args = new int[p.Length];
for (int i = 0; i < p.Length; i++)
{
args[i] = int.Parse(p[i]);
}
int v = args[0];
LinkedList<int>[] adjList = new LinkedList<int>[v];
for (int i = 0; i < v; i++)
{
adjList[i] = new LinkedList<int>();
if (lines[i + 1] == "")
{
continue;
}
string[] numbers = lines[i + 1].Split();
foreach (string number in numbers)
{
adjList[i].AddLast(int.Parse(number));
}
}
return adjList;
}

public static void PrintAdjList(LinkedList<int>[] adjList)//Hàm in danh sách kề


{
Console.WriteLine(adjList.Length);
for (int i = 0; i < adjList.Length; i++)
{
for (LinkedListNode<int> node = adjList[i].First; node != null;
node = node.Next)
{
Console.WriteLine(node.Value + " ");
}
Console.WriteLine();
}
}

public static LinkedList<Tuple<int, int>> LoadEdgeList(string path, out int v, out int e) // Hàm load danh sách cạnh
{
if (!File.Exists(path))
{
throw new FileNotFoundException(path);
}
string[] lines = File.ReadAllLines(path);
string[] firstLineData = lines[0].Split(); // Khai báo mảng string firstLineData bằng giá trị đầu tiên của mảng lines
v = int.Parse(firstLineData[0]);
e = int.Parse(firstLineData[1]);
LinkedList<Tuple<int, int>> edgeList = new LinkedList<Tuple<int,
int>>();// khai báo danh sách cạnh
for (int i = 0; i < e; i++)
{
string[] dataRow = lines[i + 1].Split();
edgeList.AddLast(new Tuple<int, int>(int.Parse(dataRow[0]),
int.Parse(dataRow[1])));
}
return edgeList; ;
}

public static void PrintEdgeList(LinkedList<Tuple<int, int>> edgeList, int v, int e) //in danh sách cạnh
{
Console.WriteLine($"{v} {e}");
foreach (Tuple<int, int> edge in edgeList)
{
Console.WriteLine($"{edge.Item1} {edge.Item2}");
}
}

public static string ExtractPath(int[] pre, int v)//Hàm trích xuất đường dẫn
{
if (pre[v - 1] == 0)//kiểm tra giá trị của mảng pre tại vị trí [v-1]
{
return v.ToString();
}
return ExtractPath(pre, pre[v - 1]) + $"{v}";//đệ quy giá trị pre vàvị trị giá trị của mảng pre tại v - 1
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;

namespace Lab09
{
internal class Ex1
{
/*Output:
k=0; G không có chu trình Euler; cũng không có đừng đi Ueler
k=1; G có chu trình Ueler
k = 2; G có đừng đi Ueler */

private int v;
private int[,] adjMatrix;
private int[] degrees;
public Ex1(string path)
{
adjMatrix = GT.LoadAdjMatrix(path);// gọi hàm load ma trận kề gán co mảng adjMatrix
v = adjMatrix.GetLength(0);// biến v được gán giá trị bằng độ dài của mảng adjMatrix
degrees = new int[v];
for (int i = 0; i < v; i++)
{
degrees[i] = 0;
}
}

private bool checkConnectedFromS(int s) //hàm check có kết nối từ đỉnh S


{
bool[] visited = new bool[v]; // khai báo một mảng visited với số phần tử là v
Queue<int> q = new Queue<int>(); // khai báo một hàng đợi q
LinkedList<int> connectedVertices = new LinkedList<int>(); // khai báo danh sách các đỉnh đã kết nối

connectedVertices.AddLast(s);// thêm vào list connectVertices


visited[s - 1] = true; // đánh dấu đã thăm
q.Enqueue(s);// thêm đỉnh s vào hàng đợi

while (q.Any())
{
int currentVertex = q.Dequeue();// giá trị biến currentVertex = giá trị của hàng đợi q được lấy ra
for (int i = 1; i <= v; i++)
{
if (adjMatrix[currentVertex - 1, i - 1] != 0)
{
if (visited[i - 1])
{
continue;
}

visited[i - 1] = true;
q.Enqueue(i);
connectedVertices.AddLast(i);
}
}
}
return connectedVertices.Count == v;
}

private bool IsConnected()// hàm kiểm tra đã kết nối hay chưa
{
for (int i = 1; i <= v; i++)
{
if (!checkConnectedFromS(i))
{
return false;
}
}
return true;
}

public bool IsEulerianGraph() //hàm xác định có phải là đồ thị Euler


{
for (int i = 0; i < v; i++)
{
int deg = 0;
for (int j = 0; j < 0; j++)
{
if (adjMatrix[i, j] != 0)
{
deg++;
}
}
if (deg % 2 != 0)
{
return false;
}
}
return true;
}

public bool HasEulerianTrail()// hàm xác định có đường đi Euler hay không
{
int oddVertex = 0;
for (int i = 0; i < v; i++)
{
int deg = 0;
for (int j = 0; j < v; j++)
{
if (adjMatrix[i, j] != 0)
{
deg++;
}
}
if (deg % 2 != 0)
{
oddVertex++;
}
}
return (oddVertex == 0 || oddVertex == 2);
}

public void Solve(string outputPath) // hàm giải


{
if (!IsConnected())
{
File.WriteAllText(outputPath, "0");
return;
}
if (IsEulerianGraph())
{
File.WriteAllText(outputPath, "1");
return;
}
if (HasEulerianTrail())
{
File.WriteAllText(outputPath, "2");
return;
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;

namespace Lab09
{
internal class Ex2
{
/*Output:
k=0; G không có chu trình Euler; cũng không có đường đi Euler
k=1; G có chu trình Euler
k = 2; G có đường đi Euler*/

private int v;
private int[,] adjMatrix;
private int[] degrees;
public Ex2(string path)
{
adjMatrix = GT.LoadAdjMatrix(path); // khai báo ma trận đọc dữ liệu từ file để load ma trận kề
v = adjMatrix.GetLength(0); // độ dài của ma trận là giá trị của biến v
degrees = new int[v];//khai báo số phần tử mảng degree bằng giá trị biến v
for (int i = 0; i < v; i++)
{
degrees[i] = 0;
}
}

private bool checkConnectedFromS(int s)//hàm check có kết nối từ đỉnh S


{
bool[] visited = new bool[v];// khai báo một mảng visited với số phần tử là v
Queue<int> q = new Queue<int>(); // khai báo hàng đợi q
LinkedList<int> connectedVertices = new LinkedList<int>();// khai báo một danh sách liên kết

connectedVertices.AddLast(s);// thêm biến s vào danh sách liên kết


visited[s - 1] = true;// đánh dấu dấu đã viếng thăm
q.Enqueue(s);// thêm đỉnh s vào hàng đợi

while (q.Any())
{
int currentVertex = q.Dequeue();// giá trị biến currentVertex = giá trị của hàng đợi q được lấy ra

for (int i = 1; i <= v; i++)// vòng lặp


{
if (adjMatrix[currentVertex - 1, i - 1] != 0)
{
if (visited[i - 1])// nếu tại vị trí của visited [i-1] thì bỏ qua
{
continue;
}

visited[i - 1] = true;// gán true vào vị trí i-1 của mảng visited
q.Enqueue(i);// thêm i vào hàng đợi
connectedVertices.AddLast(i);// thêm i vào mảng connectedVertices
}
}
}

return connectedVertices.Count == v; // trả về số lượng phần tử trong mảng = với đỉnh v


}

private bool IsConnected() // hàm kiểm tra có kết nối không


{
for (int i = 1; i <= v; i++)
{
if (!checkConnectedFromS(i))
{
return false;
}
}
return true;
}

private bool IsEulerianGraph() // hàm xác định có phải là đồ thị Euler


{
for (int i = 0; i < v; i++)
{
int inDegree = 0;
int outDegree = 0;

for (int j = 0; j < v; j++)


{
if (adjMatrix[i, j] != 0)
{
outDegree++;
}
if (adjMatrix[i, j] != 0)
{
inDegree++;
}
}

if (inDegree != outDegree)
{
return false;
}
}
return true;
}
public bool HasEulerianTrail() //hàm xác định có đường đi Euler không
{
int outLt = 0;
int inLt = 0;
for (int i = 0; i < v; i++)
{
int inDegree = 0;
int outDegree = 0;
for (int j = 0; j < v; j++)
{
if (adjMatrix[i, j] != 0)
{
outDegree++;
}

if (adjMatrix[j, i] != 0)
{
inDegree++;
}
}

if (outDegree - inDegree == 1)
{
outLt++;
}
if (inDegree - outLt == 1)
{
inLt++;
}
}
if (inLt != outLt)
{
return false;
}
return inLt <= 1;
}

public void Solve(string outputPath)// hàm giải


{
if (!IsConnected())
{
File.WriteAllText(outputPath, "0");
return;
}

if (IsEulerianGraph())
{
File.WriteAllText(outputPath, "1");
return;
}

if (HasEulerianTrail())
{
File.WriteAllText(outputPath, "2");
return;
}
}
}
}
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Lab09
{
internal class Ex3
{
private int n;
private int x;
private int[,] adjMatrix;

public Ex3(string path)


{
if (!File.Exists(path)) throw new FileNotFoundException(path);// kiểm tra file có tồn tại không

string[] lines = File.ReadAllLines(path); // khai báo mảng lines đọc tất cả các dòng trong file
string[] gArgs = lines[0].Split(' ');// khai báo mảng gArgs = giá trị đầu tiên của mảng lines
n = int.Parse(gArgs[0]);// khai báo biến n có giá trị bằng giá trị đầu tiên của mảng gArgs
adjMatrix = new int[n, n];// khai báo mảng 2 chiều adjMatrix số dòng n cột n

for (int i = 0; i < n; i++) // vòng lặp


{
string[] numbers = lines[i + 1].Split(); // khai báo mảng numbers = giá trị tại vị trí i+1 của mảng lines
for (int j = 0; j < n; j++)
{
adjMatrix[i, j] = int.Parse(numbers[j]);
}
}
}

private int TryMove(int u) // hàm thử di chuyển


{
for (int i = 0; i < n; i++)// vòng lặp
{
if (adjMatrix[u - 1, i] != 0) // nếu tại vị trí u-1, i != 0 thì tăng biến i thêm 1
{
return i + 1;
}
}
return -1;
}

private void RemoveEdge(int u, int v)// hàm xóa cạnh


{
adjMatrix[u - 1, v - 1] = 0;
adjMatrix[v - 1, u - 1] = 0;
}

public void Solve(string outputPath) // hàm xử lý


{
LinkedList<int> EulerTrail = new LinkedList<int>(); // khai báo dannh sách đường đi Euler
Stack<int> stack = new Stack<int>(); // khai báo stack
stack.Push(x);// đẩy giá trị x vào stack
while (stack.Any())
{
int currentVertex = stack.Peek();
int nextVertex = TryMove(currentVertex);
if (nextVertex == -1)
{
//cannot move
EulerTrail.AddLast(stack.Pop());
}
else
{
stack.Push(nextVertex);
RemoveEdge(currentVertex, nextVertex);
}
}
File.WriteAllText(outputPath, string.Join("", EulerTrail.Reverse()));// viết tất cả vào file outputpath và đảo ngược
EulerTrail
}
}
}
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Lab09
{
internal class Ex4
{
private int n;
private int[,] adjMatrix;
LinkedList<int> solutionPath;
bool[] visited;
private int source;

public Ex4(string path)


{
if (!File.Exists(path)) // kiểm tra file có tồn tại hay không
{
throw new FileNotFoundException(path);
}

string[] lines = File.ReadAllLines(path);// khai báo mảng lines đọc tất cả dữ liệu từ trong file
string[] gArgs = lines[0].Split(' ');// khai báo mảng gArgs với giá trị đầu tiên của mảng lines
n = int.Parse(gArgs[0]); // biến n có giá trị là giá trị đầu tiên của mảng gArgs

adjMatrix = new int[n, n]; // khai báo mảng adjMatrix với số dòng n cột n
solutionPath = new LinkedList<int>();// khai báo dánh sách
visited = new bool[n];//khai báo mảng visited với số phần tử bằng n

for (int i = 0; i < n; i++)// vòng lặp


{
string[] numbers = lines[i + 1].Split(); // khai báo mảng numbers = giá trị tại vị trí i+1 của mảng lines
for (int j = 0; j < n; j++)
{
adjMatrix[i, j] = int.Parse(numbers[j]);
}
}
}

public bool Completed() // hàm kiểm tra


{
foreach (bool v in visited)
{
if (!v)
{
return false;
}
}
return true;
}

private void HamiltonCycle(int i) // hàm kiểm tra có phải là chu trình HamitonCycle
{
if (Completed() && adjMatrix[i - 1, solutionPath.First.Value - 1] != 0)
{
Console.WriteLine(string.Join(" ", solutionPath));
return;
}
for (int j = 1; j <= n; j++)
{
if (adjMatrix[i - 1, j - 1] != 0)
{
if (visited[j - 1] == false)
{
solutionPath.AddLast(j);
visited[j - 1] = true;
HamiltonCycle(j);
visited[j - 1] = false;
solutionPath.RemoveLast();
}
}
}
}

public void Solve(string outputPath)// hàm xử lý


{
source = 3;
visited[source - 1] = true;
solutionPath.AddLast(source);
HamiltonCycle(source);
}
}
}

You might also like