Professional Documents
Culture Documents
NgoThiDieuLinh 17000894
NgoThiDieuLinh 17000894
Msv: 17000894
Môn: Thiết kế đánh giá thuật toán
1. Viết chương trình cho các thuật toán đã phân tích và xây dựng (theo bài giảng):
(Chọn 2 trong 3 bài để thực hiện)
import java.util.Scanner;
}
public static void print() {
for(int i=0;i<n;i++) {
System.out.print(x[i]);
}
System.out.println();
}
}
Đề bài: Bài toán người bán hàng: Một người bán hàng trên hệ thống n thành phố. Giữa
các thành phố có thể có hoặc không các đường nối, mỗi đường nối có chi phí xác định từ
trước. Người bán hàng xuất phát từ một thành phố, đi tới tất cả các thành phố khác và
mỗi thành phố đi qua lần và quay trở lại thành phố ban đầu. Hãy xác định một hành trình
sao cho tổng chi phí trên đường đi là nhỏ nhất.
Viết chương trình
package week4;
import java.util.Scanner;
class TSP_Bai1 {
public TSP_Bai1(int[][] c) {
this.c = c;
flag = new int[c.length];
x = new int[c.length];
x_best = new int[c.length];
// tim Cmin
public static int cmin() {
cMin = c[0][0];
for (int i = 0; i < c.length; i++) {
for (int j = 0; j < c.length; j++) {
if (cMin > c[i][j])
cMin = c[i][j];
}
}
return cMin;
}
/* in ra mang x_best */
public static void printResult() {
for (int i = 0; i < c.length; i++) {
System.out.print((x_best[i] + 1) + " ");
/*
* O buoc thu i, nguoi du lich se di qua thanh pho nao
*/
// thuat toan ap dung cho chay tu thanh pho 0 den cac thanh pho con lai
// khong ap dung cho chay tu thanh pho bat ki
public static void tsp(int i) {
for (int j = 1; j < c.length; j++) {
if (flag[j] == 0) {
x[i] = j;
flag[j] = 1;
sum = sum + c[x[i - 1]][x[i]]; //chi phi
g = sum + (c.length - i) * cmin(); // tinh can : chi phi
tu 0 den thanh pho hien tai+ chi phi nho nhat cua cac thanh pho con lai
if (i == c.length - 1) {
cost = sum + c[x[c.length - 1]][0]; // chi phi tu 0
den thanh pho cuoi cung+ chi phi tp cuoi cung + thanh pho ban dau
update();
} else {
if (g < f)
tsp(i + 1);
// n=sc.nextInt();
flag[i] = 0;
}
System.out.println("bài toán người bán hàng");
System.out.println("phương pháp nhánh cận");
tsp.tsp(1); // tu thanh pho 0 di den thanh pho 1
tsp.printResult();
}
}
2. Phân tích bài toán, xây dựng thuật toán và viết chương trình cho các bài toán
sau:(Chọn 2 trong 4 bài để thực hiện)
Xây dựng thuật toán: Chẳng hạn X = { 1, 2, 3, 4}. Các hoán vị các phần tử của X
được liệt kê theo thứ tự từ điển {1 2 3 4}, {1 2 4 3}, {1 3 2 4}, {1 4 2 3}, {1 4 3
2}, {2 1 3 4}, {2 1 4 3}, {2 3 1 4}, {2 3 4 1}....{4 3 2 1}.
- Như vậy, hoán vị đầu tiên trong thứ tự từ điển là (1, 2, …, n) và hoán vị cuối cùng
là (n, n- 1,..., 1). Giả sử a = a1a2... an là một hoán vị chưa phải là cuối cùng. Khi đó
ta có thể chứng minh được rằng, hoán vị kế tiếp trong thứ tự từ điển có thể xây dựng
bằng cách thực hiện các qui tắc biến đổi sau đối với hoán vị hiện tại:
Tìm từ phải qua trái hoán vị có chỉ số j đầu tiên thoả mãn aj< aj+1.
Tìm ak là số nhỏ nhất còn lớn hơn aj trong các số ở bên phải aj;
Đổi chỗ aj với ak
Lật ngược đoạn từ aj+1 đến an.
VD: Chẳng hạn ta đang có hoán vị (3, 6, 2, 5, 4, 1), cần xây dựng hoán vị kế tiếp theo thứ
tự
Ta duyệt từ j = n-1 sang bên trái để tìm j đầu tiên thoả mãn aj < aj+1 ta nhận
được j = 3 ( a3=2 <a 4=5).
Số nhỏ nhất còn lớn hơn a3 trong các số bên phải a3 là a5(a5=4).
Đổi chỗ a3 cho a5 ta thu được (3, 6, 4, 5, 2, 1),
Lật ngược đoạn từ a4 đến a6 ta nhận được (3,6,4,1,2,5).
Viết chương trình:
package week4;
import java.util.Scanner;
else
Binary(i+1);
b[j]=0;
}
}
}
public static void print() {
for(int i=0;i<n;i++) {
System.out.print(x[i]+1);
}
System.out.println();
}
}
Đề bài: 2.4. Bài toán xâu ABC: Cho số nguyên dương N <100, tìm 1 xâu gồm toàn các kí
tự A,B,C thoả mãn: Xâu có độ dài N, 2 đoạn con bất kì liền nhau đều khác nhau, xâu có ít
kí tự C nhất.
Phân tích bài toán:
- Nếu dãy X1 X 2 …X n thỏa mãn 2 đoạn con bất kỳ liền nhau đều khác nhau, thì trong
4 kí tự liên tiếp bất kỳ bao giờ cũng phải có 1 kí tự “C”. Như vậy với 1 dãy con
gồm k kí tự liên tiếp của dãy X thì số kí tự C trong dãy con đó bắt buộc phải ≥ k/
4.
- Tại bước thử chọn Xi , nếu ta đã có Ti kí tự “C” trong đoạn đã chọn từ X1 đến Xi ,
thì cho dù các bước đệ quy có tốt thì số kí tự “C” sẽ phải chọn them bao giờ cũng
≥ (n-i)/4
Xây dựng bài toán:
Input: file văn bản BC.INP chứa số nguyên dương N < 100
Output: file văn bản ABC.OUT ghi xâu tìm được
ABC.INP ABC.OUT
10 ABACABCBAB
“C” Letter
Count: 2
static int N;
static char X[] = new char[101]; // luu nghiem hien tai
static char Best[] = new char[101]; //luu nghiem tot nhat
static int MinC; // it ki tu c nhat
static int count=0;
public ABC_Bai2_4() {
}
// kiem tra ki tu trong chuoi co giong nhau k
static boolean isSame(int i, int k) {
int kitu=i-k;
for(int l=0;l<k;l++) { // l la do dai cua chuoi ,l=1..n chuoi co do dai 1..n
if(X[i-l]!=X[kitu-l]) // kiem tra tu ki tu cua chuoi co do dai n
return false; // nau khac nhau thi return false
}
return true;
}
return true;
}
}
}
if(i==N) {
keepResult();
}
else {
int g=count+ (N-i)/4; // g luu so luong chuoi co so ki tu hien tai + so
ki tu con lai xuat hien ki tu C
if(g<MinC) // neu g < MinC:so luong c it nhat
attempt(i+1);
}
}
}
}
MinC = N;
attempt(1);
printResult();
}
}
3. Tự đặt đề bài toán, phân tích bài toán, xây dựng giải thuật, đánh giá độ phức tạp và
viết chương trình để minh họa phương pháp quay lui, phương pháp nhánh cận
(mỗi phương pháp ít nhất 01 bài).
ARRANGE.INP ARRANGE.OUT
32 12
13
21
23
31
32
package week4;
import java.util.Scanner;
}
public void nhap() {
try (Scanner sc = new Scanner(System.in)) {
System.out.println("phương pháp quay lui");
System.out.println("bài toán chỉnh hợp chập k");
System.out.println("Nhap so n");
n=sc.nextInt();
System.out.println("Nhap so k");
k=sc.nextInt();
sc.close();
}
a=new int[k];
b=new int[n];
for(int i=0;i<n;i++) {
b[i]=1;
}
}
public void Binary(int i)
{
for(int j=0;j<n;j++)
{
if(b[j]==1) {
a[i]=j+1;
b[j]=0; // danh dau chi so j co gia tri j+1 da ton tai
if(i==k-1)
{
for(int m=0;m<k;m++)
{
System.out.print(a[m]+" ");
}
System.out.println();
}
else
Binary(i+1);
b[j]=1; // bo danh dau
}
}
}
}
Phương pháp nhánh cận:
Đề bài: Bài toán xếp balo (dung phương pháp nhánh cân;)
Phân tích bài toán: Cho một cái balo có thể đựng một trọng lượng W và n
loại đồ vật, mỗi đồ vật i có một trọng lượng g[i] và một giá trị v[i]. Tất cả
các loại đồ vật đều có số lượng không hạn chế. Tìm một cách lựa chọn các
đồ vật đựng vào balo, chọn loại đồ vật nào? Mỗi loại lấy bao nhiêu sao cho
tổng trọng lượng không vượt quá W và tổng giá trị là lớn nhất.
1.Tính đơn giá (giá cho 1 đơn vị trọng lượng) cho các loại đồ vật
2. Xét các loại đồ vật theo thứ tự đơn giá từ lớn đến nhỏ
3. Với mỗi đồ vật được xét sẽ lấy một số lượng tối đa mà trọng
lượng còn lại của balo cho phép
4. Xác định trọng lượng còn lại của balo và quay lại bước 3 cho đến
khi không còn có thể chọn được đồ vật nào nữa.
import java.util.Scanner;
class Knapsack_Bai3 {
static int w[]; // mang luu trong luong cua cac do vat
static int v[]; // mang luu gia tri cua cac do vat
static int m; // trong luong toi da cua cai tui
static int n; // so luong do vat
static int x[]; // luu nghiem hien tai
static int x_best[]; // luu nghiem tot nhat
static int sum = 0;
static float g;
static float max = 0;
static int weight;
/* in ra mang x_best */
public static void printResult() {
for (int i = 0; i < n; i++) {
System.out.print(x_best[i] + " ");
}
}
// cap nhat
public void check() {
if (sum > max) { // neu gia tri hien tai lon hon gia tri max
max = sum;
for (int k1 = 0; k1 < n; k1++)
x_best[k1] = x[k1];
}
}
x[i] = j;
sum = sum + j * v[i]; // cap nhat gia tri
weight = weight + j * w[i]; // cap nhat trong luong
if (i == n - 1 || m - weight <= 0) {
check();
else {
g = sum + (m - weight) *(v[i + 1] / w[i + 1]); // sum +
don gia vat ke tiep * trong luong con lai cua tui
if (g > max) // neu gia tri hien tai + gia tri vat ke tiep
> gia tri max hien tai
knapsack(i + 1);
}
sum = sum - j * v[i]; // cap nhat lai gia tri
weight = weight - j * w[i]; // cap nhat lai trong luong
}
}
}
// System.out.println("nhap gia tri do vat ");
for (int j = 0; j < n; j++) {
v[j] = sc.nextInt();
}
// tinh gia tri
kp.sapxep();// printResult();a
kp.knapsack(0);
kp.printResult();