Bài tâp 1: Viet chuong trinh dinh nghia cau truc stack voi cac thao tac tuong ung Su dung cau truc stack va cac thao tac da cai dat de luu tru n so nguyen duoc nhap tu ban phim . Lay cac gia tri ra khoi stack va hien thi ra man hinh. Bài tập 2 : Tìm kiếm theo chiều rộng Bài tập 3 : Thuật toán tìm kiếm A Bài tập 4: Thuật toán Best First Search Bài tập 5: Thuật toán nhánh cận ( Bài tập : Người du lịch )
Trang 1Bài tâp 1: Viet chuong trinh dinh nghia cau truc stack voi cac thao tac
tuong ung
Su dung cau truc stack va cac thao tac da cai dat de luu tru n so nguyen duoc nhap tu ban phim Lay cac gia tri ra khoi stack va hien thi ra man hinh.
Bài tập 2 : Tìm kiếm theo chiều rộng
Bài tập 3 : Thuật toán tìm kiếm A*
Bài tập 4: Thuật toán Best First Search
Bài tập 5: Thuật toán nhánh cận ( Bài tập : Người du lịch )
Lời Giải Bài 1 : Viet chuong trinh dinh nghia cau truc stack voi cac thao tac tuong ung
Su dung cau truc stack va cac thao tac da cai dat de luu tru n so nguyen duoc nhap tu ban phim
Lay cac gia tri ra khoi stack va hien thi ra man hinh.
CODE:
#include <iostream>
#include <conio.h>
using namespace std;
#define MAX 100
// Tao Node
struct Node{
int data;
Node* next;
};
// Tao cau truc ngan xep
struct Stack{
Node* top;
};
// Khoi tao ngan xep
void Init(Stack &s){
s.top = NULL;
}
// Kiem tra rong
int IsEmpty(Stack s){
if (s.top==NULL)
return 1;
return 0;
}
// Tao nut
Node* createnode(int x){
Node* p=new Node;
if(p==NULL) return NULL;
p->data=x;
Trang 2return p;
}
// Dau vao
void Push(Stack &s, int x){
Node* p=createnode(x);
if (IsEmpty(s)==1)
s.top=p;
else {
p->next=s.top;
s.top=p;
}
}
// dau ra
int Pop(Stack &s){
int x;
Node* p=s.top;
if (IsEmpty(s)==1)
return 0;
x=p->data;
s.top=s.top->next;
delete p;
return x;
}
int Search(Stack s, int x){
for (Node* p=s.top; p!=NULL; p=p->next)
if (p->data==x)
return 1;
return 0;
}
#define SIZE 7
const int X = 32767;
char Label[7] = {'A','B','C','D','E','F','G'};
int main(){
int T[7][7] = {{0, 1, 1, X, X, X, X},
{1, 0, X, 1, 1, X, X},
{1, X, 0, X, X, 1, 1}, {X, 1, X, 0, X, X, X}, {X, 1, X, X, 0, X, X}, {X, X, 1, X, X, 0, X}, {X, X, 1, X, X, X, 0}};
int u, v, start = 0, goal = 5, ok=0; int Close[SIZE]={0}; // Chua dinh nao duoc phat trien
Trang 3int Father[SIZE]; //Father[i] = chi so dinh cha cua i
Stack OP;
Init(OP);
Push(OP, start);
while (!IsEmpty(OP)){
//lay u la trang thai o dau hang doi
u = Pop(OP);
//Kiem tra u co phai trang thai dich
if (u==goal){
ok = 1;
break;
} //Luu u vao danh Close - de xac dinh u da duoc phat trien Close[u] = 1;
//xet lan luot con v cua u for (v=SIZE; v>=0; v )
if (T[u][v]==1)
if (Search(OP, v)==0 && Close[v]==0){
Push(OP, v);
Father[v] = u;
} }
if (ok==1){
cout << "Duong di la: " << endl;
while (u!=start){
cout << Label[u] << "< ";
u = Father[u];
} cout << Label[start] << endl;
}
}
Bài tập 2 : Tìm kiếm theo chiều rộng
#include <iostream>
using namespace std;
//Dinh nghia cau truc hang doi va cac thao tac tren do
#define MAX 100
struct Node{
int data;
Node *next;
};
struct Queue{
Node *pHead;
Node *pTail;
};
// Khoi tao
void Init(Queue &q){
Trang 4q.pHead=q.pTail=NULL;
}
// Tao nut
Node *taonut(int x){
Node *p=new Node;
if (p==NULL) return NULL;
p->data=x;
p->next=NULL;
return p;
}
// Them vao cuoi
void Add(Queue &q, Node *p){
if(q.pHead==NULL) q.pHead=q.pTail=p; else{
q.pTail->next=p;
q.pTail=p;
}
}
// Xoa hang doi
int Remove(Queue &q){
if (q.pHead==NULL){
cout << "Hang doi rong!";
return 0;
}
Node *p=q.pHead;
int x= p->data;
q.pHead=q.pHead->next;
delete p;
return x;
}
// Tim kiem hang doi
int Search(Queue q, int x){
Node *p;
for (p=q.pHead; p!=NULL; p=p->next)
if (p->data==x)
return 1;
return 0;
}
// Huy hang doi
void huy(Queue &q){
while(q.pHead!=NULL){
Node *p=q.pHead;
q.pHead=q.pHead->next;
delete p;
}
q.pTail==NULL;
Trang 5const int X = 32767;
char Label[7] = {'A','B','C','D','E','F','G'};
int main(){
int T[7][7] = {{0, 1, 1, X, X, X, X},
{1, 0, X, 1, 1, X, X},
{1, X, 0, X, X, 1, 1}, {X, 1, X, 0, X, X, X}, {X, 1, X, X, 0, X, X}, {X, X, 1, X, X, 0, X}, {X, X, 1, X, X, X, 0}};
int u, v, start = 0, goal = 3, ok=0;
int Close[7]={0}; // Chua dinh nao duoc phat trien
int Father[7]; //Father[i] = chi so dinh cha cua i
Queue OP;
Init(OP);
Node *p =taonut(start);
Add(OP, p);
while (OP.pHead!=NULL){
//lay u la trang thai o dau hang doi
u = Remove(OP);
//Kiem tra u co phai trang thai dich
if (u==goal){
ok = 1;
break;
} //Luu u vao danh Close - de xac dinh u da duoc phat trien Close[u] = 1;
//xet lan luot con v cua u for (v=0; v<7; v++)
if (T[u][v]==1)
if (Search(OP,v)==0 )
if (Close[v]==0){
Node *q=taonut(v);
Add(OP, q);
Father[v] = u;
} }
if (ok==1){
cout << "Duong di la: " << endl;
while (u!=start){
cout << Label[u] << "< ";
u=Father[u];
} cout << Label[start] << endl;
Trang 6huy(OP);
}
Bài tập 3: Thuật toán tìm kiếm A*
1 #include <fstream>
2 #include <iostream>
3 using namespace std;
4
5 struct Node
6 {
7 int stt;// so thu tu
8 int g;// khoang cach tu dinh ban dau den dinh hien taị
9 int f;// f = h + g;
10 int h;// duong di ngan nhat
11 int color;// danh dau dinh di qua
12 int dad;// dinh cha
13 };
14
15 int a[100][100];
16 Node p[100];
17 Node Open[100];
18 Node Close[100];
19
20 void ReadfileInput1(int *b,int &n)
21 {
22 fstream myfile("Input1.txt");
23
24 if (!myfile.is_open())
26 cout <<"Khong the mo duoc file"<< endl;
28 else
30 myfile >> n;
31
32 for int i = 0; i < n; i++)
34 myfile >> b[i];
37 }
38
39 void ReadfileInput2(int a[100][100], int &n,int &start,int &finsh)
40 {
41 fstream shichiki("Input2.txt");
42 if (!shichiki.is_open())
Trang 743 {
44 cout <<"Khong the mo duoc file !";
46 else
48 shichiki >> n >> start >> finsh; 49
50 for int i = 0; i < n; i++)
52 for int j = 0; j < n; j++)
53 shichiki >> a[i][j];
56 shichiki.close();
57
58 }
59 void printfmaxtric(int a[100][100], int n)
60 {
61 for int i = 0; i < n; i++)
63 for int j = 0; j < n; j++)
65 cout << a[i][j]<<"\t";
67 cout <<"\n";
69 }
70
71 int Count(int n,Node *Open)
72 {
73 int count = 0;
74 for int i = 0; i < n; i++)
76 if Open[i].color == 1)
79 return count;
80 }
81
82 int Find(int n,Node *Open)
83 {
84
85 for int i = 0; i < n; i++)
86 if Open[i].color == 1)
88 }
89
90 int Findmin(int n,Node *Open)
Trang 891 {
92 int min1 = Find(n,Open);
93 int min = Open[min1].f
94 for int i = 0; i < n; i++)
96 if Open[i] < min && Open[i].color == 1)
102 return min1;
103 }
104
105 void Init(int n,int *b)
106 {
107 for int i = 0; i < n; i++)
109 p[i].stt = i;
110 p[i].color = 0;
111 p[i].g = b[i];
112 p[i].dad = 0;
113 p[i] = p[i] ;
114 p[i].h = 0;
116 }
117
118 int Findpoint(int n,Node *q,int o)
119 {
120 for int i = 0; i < n; i++)
121 if q[i].stt == o)
123 }
124
125 void AStar(int a[100][100], int n,int start,int finsh,int b[])
126 {
127 int l = 0;
128 Open[l]= p[start];
129 Open[l].color = 1;
130 Open[l] = Open[l].h + Open[l] ;
132 int w = 0;
133
134 while Count(l,Open) != 0)// kiem tra xem tap Open co con phan tu nao khong
136 int k = Findmin(n,Open); // tim vi tri nho nhat trong Open
137 Open[k].color = 2;// cho diem tim duoc vao Close
Trang 9138 Close[w]= Open[k];
139 Close[w].color = 2;
141 p[Findpoint(n, p,Open[k].stt)].color = 2;
142 if Findpoint(n, p,Open[k].stt)== finsh)
144 cout <<"Duong di qua la"<< endl;
145 cout << finsh <<"\t";
146 int y = Findpoint(w,Close, finsh);
147 int u = Close[y].dad;
148 while u != start)
152 cout << u <<"\t";
158 for int i = 0; i < n; i++)
160 if a[Findpoint(n, p,Open[k].stt)][i]!= 0 &&
p[i].color == 0)// neu chua co trong Open va Close
164 Open[l].h = a[Findpoint(n, p,
Open[k].stt)][i]+ Open[k] ;// tinh h khoang cach ngan nhat tu dinh bat dau den dinh hien tai
165 Open[l] = Open[l].g + Open[l] ;
Open[k].stt);
170 if a[Findpoint(n, p,Open[k].stt)][i]!= 0 &&
p[i].color == 1)// neu dinh da co trong open
172 int h = Findpoint(l,Open, p[i].stt);
175 tam.h = a[Findpoint(n, p,Open[k].stt)][i] + Open[k] ;
177 tam.f = tam.h + tam.g;
178 if tam.f < Open[h f //neu f trang thai hien tai be hon trang thai cap nhat truoc do
Trang 10179 Open[h]= tam;
181 if a[Findpoint(n, p,Open[k].stt)][i]!= 0 &&
p[i].color == 2)// neu dinh da co trong Close
183 int h = Findpoint(l,Close, p[i].stt);
186 tam.h = a[Findpoint(n, p,Open[k].stt)][i] + Open[k] ;
188 tam.f = tam.h + tam.g;
189 if tam.f < Close[h f //neu f trang thai hien tai be hon trang thai truoc do
dinh do thuoc Open
199 }
200
201 int main()
202 {
204 int start;
205 int finish;
206 int b[100];
207
208 ReadfileInput2(a, n, start, finish);
209 ReadfileInput1(b, n);
210
211 Init(n, b);
212 cout <<"Dinh bat dau"<< endl;
213 cout << start << endl;
214 cout <<"Dinh ket thuc"<< endl;
215 cout << finsh << endl;
216
217 AStar(a, n, start, finish, b);
218 return 0;
219 }
Bài tập 4 : Thuật toán Best First Search
Trang 111 #include <stdio.h>
2 #include <queue>
3 #include <conio.h>
4 using namespace std;
5
6 // dinh nghia lop do thi
7 class Graph
8 {
9 private:
10 int n;
11 int **edge;
12 public:
13 Graph(int size = 2);
14 ~Graph();
15 bool isConnected(int,int);
16 void addEdge(int,int);
17 void breadthFirstSearch(int,int);
18 };
19
20 Graph::Graph(int size)
21 {
22 int i, j;
23
24 // xac dinh so dinh cua do thi
25 if size < 2)
26 n = 2;
27 else
29
30 // tao ra cac dinh trong do thi
31 edge = new int*[n
32 for i = 0; i < n; i++)
33 edge[i]= new int[n];
34
35 // mac dinh giua cac dinh khong co ket noi voi nhau (= 0)
36 for i = 0; i < n; i++)
37 for j = 0; j < n; j++)
38 edge[i][j]= 0;
39 }
40
41 Graph::~Graph()
42 {
43 for int i = 0; i < n;++i)
44 delete[] edge[i];
45 delete[] edge;
46 }
47
48 // kiem tra giua hai dinh co ke nhau hay khong
Trang 1249 bool Graph::isConnected(int x,int y)
50 {
51 if edge[x -1 y -1]== 1)
52 return true;
53
54 return false;
55 }
56
57 // tao canh noi giua hai dinh, lam cho hai dinh ke nhau
58 void Graph::addEdge(int x,int y)
59 {
60 if x < 1 || x > n || y < 1 || y > n)
62
63 edge[x -1][y -1]= edge[y -1 x -1]= 1;
64 }
65
66 void Graph::breadthFirstSearch(int s,int g)
67 {
68 if s > n || s < 0 || g > n || g < 0)
70 printf("Could not traverse this graph with your request\n");
73 queue <int> open;
74 bool *close = new bool[n];
75 int i;
76 int p;
77
78 // mac dinh cac dinh chua duoc duyet
79 for i = 0; i < n; i++)
80 close[i]= false;
81
82 // dua dinh goc s vao queue open, chuan bi duyet
83 open.push(s);
84
85 printf("With Breadth first Search , we have vertex(s):\n");
86
87 while (!open.empty())
89 // lay mot dinh ra khoi open tro thanh dinh dang xet p
94
95 p = open.front();
Trang 1397 }while close[p -1]== true);
98
99 // in ra dinh dang xet
100 printf("%d ", p);
101
103 close[p -1]= true;
104
105 // ket thuc duyet khi tim ra ket qua can tim
106 if p == g)
108
109 // tim dinh ke voi dinh dang xet, dinh nao chua duoc duyet dua vao open
110 for i = 1; i <= n; i++)
112 if isConnected(p, i)&& close[i -1])
118 printf("\n");
119
120 delete[] close;
121 }
void main()
1 {
2 // khoi tao do thi
3 Graph g(9);
4
5 // tao canh noi giua cac dinh ke
6 g.addEdge(1,2);
7 g.addEdge(1,3);
8 g.addEdge(1,4);
9 g.addEdge(2,5);
10 g.addEdge(2,6);
11 g.addEdge(3,4);
12 g.addEdge(3,5);
13 g.addEdge(3,7);
14 g.addEdge(3,8);
15 g.addEdge(3,9);
16
17 // duyet bang Breadth First Search
18 g.breadthFirstSearch(1,8);
19 }
Trang 14Bài tập 5 : Thuật toán nhánh cận ( Bài tập : Người du lịch )
#include<iostream>
using namespace std;
const int size = 20;
int maxE = 100;
int maxC = size * maxE;
int C[size][size]; //Ma trận chi phí
Trang 15int X[size+1]; //X đểthửcác khảnăng, BestWay đểghi nhận nghiệm int T[size]; //T[i] đểlưu chi phí đi từX[1] đến X[i]
int BestWay[size+1]; //, BestWay để ghi nhận nghiệm
bool FREE[size]; //Free để đánh dấu, Free[i]= True nếu chưa đi qua tp i int minSpending; //Chi phí hành trình tối ưu
int M,N;
void input()
{
int i,j,k;
cin >> N; //Nhap so thanh pho
cin >> M; //Nhap so duong
for ( i = 1; i <= N; i++ ) //Khởi tạo bảng chi phí ban đầu
{
for ( j = 1; j <= N; j++ )
{
if ( i == j ) C[i][j] = 0;
else C[i][j] = maxC;
}
}
for ( int k = 1; k <= M; k++ )
{
cin >> i; //Nhap thanh pho bat dau
cin >> j; //Nhap thanh pho den
cin >> C[i][j]; //Nhap gia di tu thanh pho i den j
C[j][i] = C[i][j]; //Chi phí như nhau trên 2 chiều
}
}
void init()
{
for ( int i = 0; i <= N; i++ )
FREE[i] = true;
FREE[1] = false; //Các thành phố là chưa đi qua ngoại trừ thành phố 1 X[1] = 1; //xuat phat tu thanh pho 1
T[1] = 0; //Chi phí tại thành phố xuất phát là 0
minSpending = maxC;
}
void output()
{
if ( minSpending == maxC )
cout << "NO SOLUTION ";
else
{
for ( int i = 1; i <= N; i++ )
Trang 16cout << BestWay[i] << "->";
cout << "1" << endl;
cout << "Cost : " << minSpending;
}
}
void tim(int i) //Thử các cách chọn xi
{
for ( int j = 2; j <= N; j++ ) //Thử các thành phố từ 2 đến n
{
if (FREE[j]) //Nếu gặp thành phố chưa đi qua
{
X[i] = j;
T[i] = T[i-1] + C[X[i-1]][j]; //Chi phí = Chi phí bước trước + chi phí đường đi trực tiếp
if ( T[i] < minSpending ) //Hiển nhiên nếu có điều này thì C[x[i - 1], j] < +∞ rồi {
FREE[j] = false; //Đánh dấu thành phố vừa thử
if(i == N)
{
if ( ( T[N] + C[X[N]][1] ) < minSpending ) // Từx[n] quay lại 1 vẫn tốn chi phí ít hơn trước
{
for ( int i = 0; i <= N; i++ ) // Cập nhật BestConfig
BestWay[i] = X[i];
minSpending = T[N] + C[X[N]][1];
}
}
else tim( i + 1 ); // Tìm các khả năng chọn x[i+1]
FREE[j] = true; // Bỏ đánh dấu
}
}
}
}
int main()
{
input();
init();
tim(2);
output();
}