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

Báo cáo thực hành Toán rời rạc

28 213 0

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

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 28
Dung lượng 191,5 KB

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

Nội dung

Toán rời rạc là một lĩnh vực của toán học nghiên cứu các đối tượng rời rạc. Chúng ta sẽ phải sử dụng công cụ của toán rời rạc khi phải đếm các đối tượng,khi nghiên cứu quan hệ giữa các tập rời rạc,khi phân tích các quá trình hữu hạn. Một trong những nguyên nhân chủ yếu làm nâng tầm quan trọng của toán rời rạc là việc cất giữ và xử lý thông tin trên máy tính bản chất là các quá trình rời rạc.Và ba lĩnh vực có nhiều ứng dụng của toán rời rạc lý thuyết tổ hợp,lý thuyết đồ thị và hàm số logic. Vì vậy,việc học toán rời rạc rất là quan trọng.Và môn Thực hành Toán rời rạc có nhiêm vụ là bổ sung và củng cố lại các kiến thức đã học,và biết được những ứng dụng của Toán rời rạc trên thực tế.

Trang 1

MỤC LỤC

MỤC LỤC 1

LỜI NÓI ĐẦU 2

Bài toán đếm & Bài toán liệt kê 4

Bài 1 4

Bài 2 4

Bài 3 6

Bài 4 8

Bài toán tối ưu rời rạc 11

Bài 1 11

Bài 2 12

Bài toán trên đồ thị 16

Thuật toán 16

Chương trình 18

Bài toán luồng cực đại trên mạng 22

Thuật toán 22

Chương trình 24

Trang 2

LỜI NÓI ĐẦU

Toán rời rạc là một lĩnh vực của toán học nghiên cứu các đối tượng rời rạc Chúng ta sẽ phải sử dụng công cụ của toán rời rạc khi phải đếm các đối tượng,khi nghiên cứu quan hệ giữa các tập rời rạc,khi phân tích các quá trình hữu hạn Một trong những nguyên nhân chủ yếu làm nâng tầm quan trọng của toán rời rạc là việc cất giữ và xử lý thông tin trên máy tính bản chất là các quá trình rời rạc.Và ba lĩnh vực có nhiều ứng dụng của toán rời rạc lý thuyết tổ hợp,lý thuyết đồ thị và hàm số logic.

Vì vậy,việc học toán rời rạc rất là quan trọng.Và môn Thực hành Toán rời rạc

có nhiêm vụ là bổ sung và củng cố lại các kiến thức đã học,và biết được những ứng dụng của Toán rời rạc trên thực tế.

Trang 3

Phần I Bài toán liệt kê

Trang 4

Bài toán đếm & Bài toán liệt kê

=============

Bài 1:

Đếm số xâu nhị phân độ dài n:

a) Bất kỳ

b) Không có hai bit 0 kề Nhau

c) Có ít nhất hai bit 0 kề nhau

Bài 2:

Viết chương trình liệt kê tất cả các xâu nhị phân độ dài n như yêu cầu của bài toán 1.Liệt kê có số thứ tự để kiểm tra kết quả đã đếm được.Thử nhập với nhiều giá trị khác nhau của n.Lưu ý các trường hợp n=1 và n=2

Thuật toán

Thuật toán chung cho cả hai bài là liệt kê bằng phương pháp đệ quy Sử dụng hàm “chỉnh hợp lặp chập n của k loại phần tử” (với n=độ dài xâu nhị phân, k=0 hoặc 1.)

{ case 1: in(); break;

case 2: not2bit0(); break;

case 3: two_bit0(); break;

Trang 5

printf(" nhap do dai n cua xau la:"); scanf("%d",&n);

// -in ra xau bat ky -//

printf("\n Cac xau nhi phan bat ky voi do dai la :%d\n",n);

lietke(1,1);

delay(5000);

// -in ra cac xau ko co 2 bit 0 ke nhau -//

printf("\n Cac xau nhi phan ko co 2 bit 0 ke nhau :\n");

d=0;

lietke(1,2);

delay(5000);

// -in ra cac xau CO 2 bit 0 ke nhau -//

printf("\n Cac xau nhi phan CO 2 bit ko ke nhau :\n");

{ case 1: in(); break;

case 2: not2bit0(); break;

case 3: two_bit0(); break;

Trang 6

Viết chương trình nhập 1 xâu chữ gồm n các chữ cái hoa (A…Z) trong đó có

1 số chữ cái lặp.Liệt kê tất cả các cách sắp xếp n chữ cái này.Có đếm tổng

số cách sắp xếp.

Thuật toán

Thuật toán chung là liệt kê bằng phương pháp sinh kế tiếp Sử dụng hàm “hoán vị lặp của n phần tử” (với n=độ dài xâu chữ.) bằng cách thêm dấu bằng (=) vào biểu thức so sánh s[i] và s[j] (in đậm) ở hàm hoán vị n phần tử.

Trang 7

void xauchuan(char *s,int n);

void hoanvi(char &a,char &b);

void phantu(char *s,char *a,int n,int &k);

long hoanvilap(char *a,int n,int k);

printf(" Nhap 1 xau ky tu: \n"); gets(s);

printf("> -> Xau ban vua nhap la:"); puts(s);

Trang 9

Bài 4:

Xét phương trình nguyên :

x1 + x2 + ….+ xn = k với xi>=0 mọi i=1 k

Viết chương trình nhập n và k,rồi in ra tất cả các nghiệm của phương

trình.Có đếm tổng số nghiệm.

Thuật toán

Thuật toán chung cho cả hai bài là liệt kê bằng phương pháp đệ quy Sử dụng hàm “chỉnh hợp lặp chập n của k loại phần tử” (với n là số phần tử, k là tổng ) Đoạn code

Trang 10

void thu(int i);

printf("so phan tu X la: n=");scanf("%d",&n);

printf("Tong cua pt la: k=");scanf("%d",&k);

Trang 12

Phần II:

Bài toán tối ưu rời rạc

Bài toán tối ưu rời rạc

===========

Bài 1:

Viết chương trình nhập n là số chi tiết cần gia công và nhập vào thời gian gia công 2 máy của từng chi tiết.Tính và in ra thời gian hoàn thành gia công nhanh nhất.

Thuật toán

- Nhập vào số chi tiết n

- Nhập vào thời gian gia công của từng chi tiết trên 2 máy A,B Đưa vào 2 biến mảng 1 chiều: thoi_gian1[i] và thoi_gian2[i].

- So sánh hai thời gian đó và cộng dồn cái nhỏ hơn

Trang 14

Viết chương trình nhập n là số thành phố và nhập ma trận khoảng cách

void thu(int i);

void xuatmt(int c[20][20],int n);

xuatmt(c,n);

}

Trang 15

int min_khoangcach()

//Tim gia tri nho nhat cua ma tran khong nam tren duong cheo chinh

{ int i,j, min=2000;

Trang 16

thu(i+1);

} b[j]=1;

Trang 17

Phần III:

Bài toán trên đồ thị

Trang 18

Bài toán trên đồ thị

=============

Viết chương trình phát sinh ngẫu nhiên ma trận trọng số Anxn=(aij)nxn của đồ thị vô hướng liên thông G gồm n đỉnh ( aij=aji với mọi I,j=1…n).

a) Kiểm tra đồ thị G có phải là đồ thị Euler hay không

b) Nhập hai đỉnh x,y và dùng thuật toán Dijksrtra để tìm đường đi ngắn nhất từ x đến y.

c) Dùng thuật toán Prim để tìm cây khung phủ nhỏ nhất của đồ thị G.

Kiểm tra Euler

Nếu có quá 2 đỉnh có bậc là bậc lẽ thì ko phải đồ thị Euler

if(kt<=2) printf("do thi la do thi EULER\n\n");

else printf("do thi ko phai la do thi EULER\n\n");

Thuật toán prim

Để tìm cây phủ nhỏ nhất của đồ thị G làm các bước sau

1) Khởi đàu cho T gồm một đỉnh v bất kì và không cạnh

2) Lặp n-1 lần

- Tìm trọng số đỉnh rìa 1 đỉnh v có cạnh nối T là e với e là nhỏ nhất

- Đưa e và v vào T

3) In cây phủ nhỏ nhất và trọng số của nó

Trang 19

min=MAX; // nạp cho min = MAX

dinh=1; //khởi tạo tại đỉnh 1

dinh=phu; // nạp cho đỉnh tiêp theo của vòng lặp kế tiếp

if(min!=MAX) dem+=min;// nếu min khác vô cùng thì nộp min vào tổng trọng số

min=MAX;//xác lập lại min

}

}

Thuật toán Dijkstra

1) Bắt đàu từ đỉnh A , nạp D(A)=0,và D(i)=vô cùng với mọi i#A Tập T chứa tất cả các đỉnh

2) Trong khi đỉnh Z còn thuộc tập T thì thực hiện các bước sau

- Lấy ra khỏi T đỉnh v(i) có D(i) nhỏ nhất

- Vọi mọi v(j) kề v(i) và v(j) thuộc T đánh nhãn lại D(j) =min{ D(j), [ D(j)+W(ij) ] }

- Khi dỉnh Z không còn thuộc T thì kết thúc thuật toán 3) In ra đường đi và độ dài đường đi nhỏ nhất

4) Đoạn code

void dijkstra()

{ int v,u,minp;

printf("\nTim duong di tu s=");scanf("%d",&s);

printf(" den ");scanf("%d",&t);

Trang 20

for(v=1;v<=n;v++)

{ d[v]=cp[s][v];//d nap khoảng cách đỉnh s đến các đỉnh còn lại

truoc[v]=s;//mảng trước là mảng in đường đi

final[v]=0;//xác lập đỉnh chưa dùng

}

truoc[s]=0;

d[s]=0;;//đánh nhãn D(s) =0;

final[s]=0;//đinh s được nạp cuối cùng(chưa được nap)

while(!final[t])//khi đỉnh cuối chưa đùng

/* chuong trinh tim khung cay phu(prim)*/

/* duong di ngan nhat(Dijkstra) */

Trang 21

printf("Nhap so dinh cua ma tran n=");

if(kt<=2) printf("do thi la do thi EULER\n\n");

else printf("do thi ko phai la do thi EULER\n\n");

}

// -ham Prim -//

Trang 22

min=b[k];

phu=k;

}a[dinh][phu]=MAX;

printf("\nTim duong di tu s=");scanf("%d",&s);

printf(" den ");scanf("%d",&t);

Trang 24

Bài toán luồng cực đại trên mạng

Bài toán luồng cực đại trên mạng

Hàm nhập ma trận liên thông có hướng:

1) Tạo ma trận an x x với n là nhập từ bàn phím,n là số đỉnh của đồ thị

2) Vì đồ thị liên thông có hướng và giả sử giữa các đỉnh có sự liên thông.

a) ví dụ từ đỉnh x có khả năng thông qua đỉnh y là c=(aij) thì điều ngược lại

Trang 25

d) Vì từ 1 đỉnh không thể có khả năng thông qua là bằng 0, a[i][i]=0 với i=1 n.

3) Nên ta có thuật toán đoạn code :

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

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

if(i!=j && i!=n && j!=1 && a[j][i]==0 )

do { printf("\ntu dinh %d den %d co kha nang thong qua la:",i,j); scanf("%d",&a[i][j]);

} while( a[j][i]!=0 );

Thuật toán Ford-Fulkerson :

Tìm luồng F(f ij) trên mạng G

Bước 1: Khởi đầu F là luồng 0 : fij=0

Bước 2: Lặp cho đến khi không còn đuờng tăng luồng

- Tìm đường tăng luông P từ đỉnh 1 đến đỉnh n.

- Tăng luồng dọc theo P

- Đánh nhãn lại khả năng thông qua của 1 luồng

- Lấy giá trị khả năng thông qua còn lại nhỏ nhất và cộng vào luồng cực đại.

Bước 3: in ra giá trị luồng cực đại.

Hàm tính luồng cực đại

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

{

ok=0; // để kiểm tra

for(h=1;h<=n;h++) if(a[1][h]) ok=1; // nếu các phần tử dòng 1 mà đều bằng 0 hêt thì kết thúc thuật toán

if( b[h]<=min ) min=b[h];

for(k=0;k<=50;k++) b[k]=0; // nạp lại các phần tử của mãng b bằng 0 để phục vụ vòng lặp kế tiếp

k=1;// nạp lại giá trị tăng cho mãng b

if(c[phu]==n) // kiểm tra đỉnh kết thúc của luồng P có phải là đích hay không

{ gt+=min; // cập nhập giá trị luồng cực đại

printf("\n Duong di la : 1"); // in đường đi

for(h=1;h<=phu;h++)

printf("%2d",c[h]);

printf(" > -> min=%d\n",min); // in giá trị của mỗi luồng

}

Trang 26

i=tam; // trả lại giá trị trị khi bắt đầu vòng lặp của i

if(min)// giá trị luồng khác không

for(j=1;j<=n;j++)//đánh nhãn lại các khả năng thông qua của luồng

if(min) i=0; // nếu giá trị tăng luồng khác không thì bắt đầu lại từ đinh1 để tìm luồng tiếp theo

else i=tam; // còn không thì tiếp tục với vòng lặp kê tiếp

void nhap(int a[50][50],int n);

void xuat(int a[50][50],int n);

void luongcucdai(int a[50][50],int n);

// -//

void main()

{ clrscr();

printf("nhap so dinh n="); scanf("%d",&n);

printf("\n moi ban nhap ma tran cua do thi \n");

printf("\n CHU Y: tinh co HUONG cua do thi \n");

nhap(a,n);

/****************************************************

* Vi neu tu 1 dinh x qua thong qua dinh y thi dieu *

* nguoc lai la khong the.O day la nhap ma tran co *

Trang 28

} }

Ngày đăng: 27/04/2018, 16:39

TỪ KHÓA LIÊN QUAN

🧩 Sản phẩm bạn có thể quan tâm

w