1. Trang chủ
  2. » Công Nghệ Thông Tin

Phương pháp Tham Lam trong kĩ thuật lập trình

6 532 6

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 6
Dung lượng 23,83 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

THUẬT TOÁN THAM LAMGồm có Bài toán tam giác số, Bài toán hái táo, Bài toán cái túi, Bài toán giao hàng du lịch, Tô màu 1.

Trang 1

THUẬT TOÁN THAM LAM

Gồm có (Bài toán tam giác số, Bài toán hái táo, Bài toán cái túi, Bài toán giao hàng (du lịch), Tô màu)

1 Bài toán tam giác số :

int TamGiacThamLam(int [MAX][MAX],int ,int path[MAX])

{

int tong=0;

int i=1,j=0,k=0;

path[k++]=a[0][0];

tong+=a[0][0];//cập nhật tổng

while(i<n {

if( [i][j]>a[i][j+1])//lựa chọn đường đi

{

tong+=a[i][j];//cập nhật tổng

}

else

{

tong+=a[i][j+1];//cập nhật tổng

j++;//cập nhật cột

} i++;//xét hàng tiếp theo

}

return tong;

}

2 Bài toán hái táo :

int HaiTaoThamLam(int [MAX][MAX],int ,int path[MAX])

{

//tìm cây táo nhiều trái nhất ở hàng dọc đầu tiên

int max=a[0][0],vt=0,soTao=0;

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

if(max<a[i][0]) {

max=a[i][0];

vt=i;

}

//lưu vị trí xuất phát

int k=0;

path[k++]=vt;

int hangdoc=0,//hàng táo

ddi=vt;//đường đi

soTao+=a[ddi][hangdoc];

while(hangdoc!=n-1)

{

//tìm cây nhiều trái nhất trong 3 cây

ddi=timCayNhieuTrai(a n,ddi,hangdoc);

//đi đến hàng tiếp theo

Trang 2

//lưu đường đi

path[k++]=ddi;

soTao+=a[ddi][hangdoc];

}

return soTao;

}

int timCayNhieuTrai(int [MAX][MAX],int ,int ,int ) {

int maxcay=a i][j+1],vtm=i

if( [ +1][j+1]>maxcay && i+1 <n

{

maxcay=a i+1][j+1];

vtm = i+1;

}

if( [ -1][j+1]>maxcay && i-1>=0)

{

maxcay=a i-1][j+1];

vtm = i-1;

}

return vtm;

}

3 Bài toán cái túi :

struct MONDO{

unsigned w; //trọng lượng món đồ

int v; //giá trị món đồ

};

//Khai báo biến toàn cục

MONDO a[100];

int n;//số loại món đồ khác nhau

//Hàm đọc dữ liêu từ tập tin

void docfile(char *fname, MONDO a[], int &n)

{

FILE *fp = fopen(fname, "rt");

if (!fp) return;

fscanf(fp, "%d", &n);

for(int i=0; i<n; i++)

fscanf(fp, "%u", &a[i].w);

for(int i=0; i<n; i++)

fscanf(fp, "%d", &a[i].v);

}

void swap(MONDO &a, MONDO &b)

{

MONDO t = a; a = b; b = t;

}

//sắp xếp danh sách các món đồ giảm dần theo đơn giá

void sort(MONDO a[], int n){

for(int i=0; i<n-1; i++)

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

if (a[i].v*1.0/a[i].w < a[j].v*1.0/a[j].w)

swap(a[i],a[j]);

}

Trang 3

//sắp xếp danh sách các món đồ giảm dần theo giá trị

void sort2(MONDO a[], int n){

for(int i=0; i<n-1; i++)

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

if (a[i].v < a[j].v)

swap(a[i],a[j]);

}

//sắp xếp danh sách các món đồ tăng dần theo trọng lượng

void sort3(MONDO a[], int n){

for(int i=0; i<n-1; i++)

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

if (a[i].w > a[j].w)

swap(a[i],a[j]);

}

//Hàm lựa chọn 1 danh sách con các món đồ

//bỏ vừa vào 1 cái túi có sức chứa c

//Sao cho tổng giá trị là lớn nhất

//Chiến thuật: chọn món có đơn giá lớn nhất

//còn bỏ vừa vào túi

//Hàm trả về tổng giá trị của các món được chọn

int Greedy1(MONDO a[], int n, //ds tất cả các món đồ

MONDO chon[], int &nc, //ds các món được chọn

{

//B1: Sắp xếp các món đồ giảm dần theo đơn giá

sort(a,n);

int tong=0,i; //tổng giá trị các món được chọn

nc = 0;

do { //chọn bao nhiêu món ko biết, chừng nào đầy thì thôi

i=0;

//B2: Chọn món đgiá lớn nhất có w <= c cho vào túi

while (i<n && a[i].w>c) i++;

if (i<n){ //chọn được

chon[nc++] = a[i];

//B3: Cập nhật lại c và tong

c = c - a[i].w;

tong += a[i].v;

} }while (i<n);

return tong;

}

//bài toán túi với số lượng đồ hạn chế

int Greedy2(MONDO a[], int n, //ds tất cả các món đồ

MONDO chon[], int &nc, //ds các món được chọn

{

//B1: Sắp xếp các món đồ giảm dần theo đơn giá

sort(a,n);

int tong=0,i; //tổng giá trị các món được chọn

nc = 0;

do { //chọn bao nhiêu món ko biết, chừng nào đầy thì thôi

i=0;

//B2: Chọn món đgiá lớn nhất có w <= c cho vào túi

while(i<n) {

while (i<n && a[i].w>c ) i++;

if (i<n && a[i].SoLuong>0)//chọn được

{

Trang 4

chon[nc++] = a[i];

//B3: Cập nhật lại c và tong

c = c - a[i].w;

tong += a[i].v;

a[i].SoLuong ;

break; }

i++;

}

}while (i<n);

return tong;

}

//Bài toán: Bài toán cái túi (số lượng món đồ ko giới hạn)

4 Bài toán giao hàng (du lịch) :

//Hàm xác định thành phố tiếp theo sẽ đi tới

//từ thành phố hiện tại là c

//(thực chất của bài toán là tìm giá trị min

//của dòng thứ c trong ma trận kề

//nhưng chỉ xét những vị trí có v[i]==0)

//trả về số thứ tự của thành phố tiếp theo tìm được

//nếu không tìm thấy trả về -1

int nextC(int a[][MAX], int n, int v[], int c)

{

int min=10000; //giá trị nhỏ nhất

int vt=-1; //vị trí của giá trị nhỏ nhất

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

if (a[c][j]<min && v[j]==0){

min = a[c][j];

vt = j;

}

return vt;

}

//Hàm tìm đường đi du lịch qua các thành phố

//(30 phút, 4 điểm)

int timduong(int a[][MAX], int n, //ma trận kề

int tpxp, //thành phố xuất phát

int path[], //lưu đường đi

int &numv, //số tp có thể đi 1<=numv<=n+1

int &tongcp) //tổng chi phí

{

numv = 0;

int c,next;

for(int i=0; i<n; i++) v[i] = 0; //khởi gán tbộ v=0

v[tpxp] = 1;

c = tpxp; //c là thành phố hiện tại

tongcp = 0; //tổng chi phí ban đầu

path[numv++] = c; //đường đi bắt đầu từ tpxp

do{

next = nextC(a,n,v,c); //tìm tp tiếp theo đi được

v[next] = 1; //đi sang tp next

path[numv++] = next;//thêm tp đó vào lộ trình

tongcp += a[c][next];//cập nhật lại chi phí

Trang 5

c = next; //next trở thành tp hiện tại

}

}while (numv<n && next!=-1);//dừng khi đi hết, hoặc ko

//đi tiếp được nữa

if (numv<n) return 0; //ko đi đủ hết các tp

int lastc = path[numv-1];

if (a[lastc][tpxp]<10000) { //kiểm tra đường quay về

path[numv++] = tpxp;

tongcp += a[lastc][tpxp];

return 1;

}

return 0;

}

5 Tô màu :

//Thuật toán tô màu các đỉnh của đồ thị

int tomau(int a[][MAX], int n, int v[])

{

//khởi gán v

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

int somau=0;

while (1){

//tìm đỉnh đầu tiên chưa tô (từ trái sang)

int i=0, k;

while (v[i]!=0 && i<n) i++;

if (i>=n) return somau; //tô hết rồi

k = i; //chọn đỉnh k để tô

somau++; //tăng số màu được dùng lên

v[k] = somau; //tô màu cho đỉnh k

//tô màu tất cả các đỉnh ko kề với k

for(; i<n; i++) //chạy tiếp vòng while trên

if (v[i]==0){

int j; //tìm đỉnh j kề với i đã tô màu htại

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

if (v[j]==somau && a[i][j]!=10000)

break;

if (j>=n) v[i] = somau; //nếu ko có thì tô

} }

}

6 Bài Toán ATM:

//BÀI TOÁN ATM

bool tratien(int kq[], int &n, int k)

{

int t[] = {500,200,100,50,20,10};

n = 0;

while (k>0) {

int i=0;

while (i<6 && t[i]>k) i++;//tìm tờ tiền có thể rút

if (i>=6) return false; kq[n++] = t[i]; //thêm tờ tiền thứ i vào kq

k -= t[i]; //số tiền cần rút giảm đi

}

return true;

Trang 6

//Số tờ tiền của mỗi mệnh giá là hữu hạn

bool tratien2(int kq[], int &n, int k, int soto[])

{

int t[] = {500,200,100,50,20,10};

n = 0;

while (k>0) {

int i=0;

//tìm tờ tiền có thể rút

while (i<6 && (t[i]>k || soto[i]==0)) i++;

if (i>=6) return false; kq[n++] = t[i]; //thêm tờ tiền thứ i vào kq

k -= t[i]; //số tiền cần rút giảm đi

soto[i] ; //số tờ mệnh giá t[i] giảm đi 1

}

return true;

}

Ngày đăng: 09/09/2015, 17:51

TỪ KHÓA LIÊN QUAN

w