1. Trang chủ
  2. » Luận Văn - Báo Cáo

Đồ Án Với số tự nhiên n cho trước tính xem có bao nhiêu cách biểu diễn n thành tổng của 1 hay nhiều số tự

20 948 1

Đ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 20
Dung lượng 732 KB

Nội dung

Đồ án cấu trúc dữ liệu và giải thuật  GVHD:Phan Thanh Tao LỜI NÓI ĐẦU Trong khoa học máy tính, cấu trúc dữ liệu là một cách lưu dữ liệu trong máy tính sao cho nó có thể được sử dụng một cách hiệu quả. Thông thường, một cấu trúc dữ liệu được chọn cẩn thận sẽ cho phép thực hiện thuật toán hiệu quả hơn. Việc chọn cấu trúc dữ liệu thường bắt đầu từ chọn một cấu trúc dữ liệu trừu tượng. Một cấu trúc dữ liệu được thiết kế tốt cho phép thực hiện nhiều phép toán, sử dụng càng ít tài nguyên, thời gian xử lý và không gian bộ nhớ càng tốt. Các cấu trúc dữ liệu được triển khai bằng cách sử dụng các kiểu dữ liệu, các tham chiếu và các phép toán trên đó được cung cấp bởi một ngôn ngữ lập trinh. Mỗi loại cấu trúc dữ liệu phù hợp với một vài loại ứng dụng khác nhau, một số cấu trúc dữ liệu dành cho những công việc đặc biệt. Trong thiết kế nhiều loại chương trình, việc chọn cấu trúc dữ liệu là vấn đề quan trọng. Kinh nghiệm trong việc xây dựng các hệ thống lớn cho thấy khó khăn của việc triển khai chương trình, chất lượng và hiệu năng của kết quả cuối cùng phụ thuộc rất nhiều vào việc chọn cấu trúc dữ liệu tốt nhất. Để có thể đi sâu và nắm vững một cách có hệ thống kiến thức đã thu nhận được trong quá trình học môn Cấu trúc dữ liệu và giải thuật, em chọn đề tài “Với số tự nhiên n cho trước tính xem có bao nhiêu cách biểu diễn n thành tổng của 1 hay nhiều số tự nhiên khác” để tìm hiểu và nghiên cứu. Trong quá trình thực hiện đồ án, chúng em xin chân thành cảm ơn sự hướng dẫn tận tình của thầy Phan Thanh Tao đã giúp đỡ em hoàn thành tốt đồ án môn học này. SVTH:Phan Lữ Đặng Bình - Đỗ Thế Viên – Hà Phước Việt – Lê Thanh Vũ – Nhóm 12A Page 1 Đồ án cấu trúc dữ liệu và giải thuật  GVHD:Phan Thanh Tao A. Giới thiệu đề tài: Tên đề tài: Với số tự nhiên n cho trước tính xem có bao nhiêu cách biểu diễn n thành tổng của 1 hay nhiều số tự nhiên khác(không tính đến thứ tự của các số hạng, ví dụ 3=2+1=1+2 coi như là một cách biểu diễn) Có nhiều phương pháp đề giải quyết bài toán. Trong đồ án này, chúng em phân tích và giải quyết bài toán theo 3 phương pháp để tìm lời giải tối ưu nhất:  Phương pháp quay lui( back tracking).  Phương pháp đệ quy(chia để trị).  Phương pháp quy hoạch động(Dynamic Programming). Ứng với mỗi phương pháp gồm :  Có cơ sở lý thuyết  Phân tích hướng giải quyết  Cài đặt chương trình. Tài liệu tham khảo:  Giải thuật và lập trình – Lê Minh Hoàng.  Thiết kế và đánh giá thuật toán – Trần Tuấn Minh.  Kiến thức được học ở trường – Phan Thanh Tao. SVTH:Phan Lữ Đặng Bình - Đỗ Thế Viên – Hà Phước Việt – Lê Thanh Vũ – Nhóm 12A Page 2 Đồ án cấu trúc dữ liệu và giải thuật  GVHD:Phan Thanh Tao B. LÝ THUYẾT I. Nghiên cứu lý thuyết liên quan : 1.Thuật toán quay lui : a. Ý tưởng : Nét đặt trưng của phương pháp quay lui là các bước hướng tới lời giải cuối cùng của mỗi bài toán hoàn thành được làm thử . Tại mỗi bước nếu có một lựa chọn được chấp nhận thì ghi nhận lựa chọn này và tiến hành các bước tiếp theo. Còn ngược lại không có lựa chọn nào thích hợp thì làm lại bước trước, xóa bỏ ghi nhận này và quay về chu trình thử các lựa chọn còn lại. Hành động này được gọi là quay lui, thuật toán thể hiện phương pháp này được gọi là quay lui. Điểm quan trọng của thuật toán là phải ghi nhớ tại mỗi bước đi qua để tránh trùng lặp khi quay lui dễ thấy là thông tin này cần lưu trữ vào một ngăn xếp nên thuật toán thể hiện ý thiết kế một cách đệ quy. b. Mô hình : Lời giải của bài toán thường biểu diễn bằng một vecto gồm n thành phần x=(x 1… x n ) phải thỏa mãn các điều kiện nào đó. Để chỉ ra lời giải x ta phải xây dựng dần các thành phần x i . Tại mỗi bước i :  Đã xây dựng xong các thành phần x 1 x i-1 .  Xây dựng thành phần x i bằng cách lần lượt thử tất cả các khả năng mà x i có thể chọn. • Nếu 1 khả năng j nào đó phù hợp cho x i thì xác định x i theo khả năng j . Thường phải có thêm thao tác ghi nhận trạng thái mới của bài toán để hổ trợ SVTH:Phan Lữ Đặng Bình - Đỗ Thế Viên – Hà Phước Việt – Lê Thanh Vũ – Nhóm 12A Page 3 Đồ án cấu trúc dữ liệu và giải thuật  GVHD:Phan Thanh Tao cho bước quay lui. Nếu i=n thì được một lời giải ngược lại thì tiến hành bước i+1 để xác định x i+1 . • Nếu không có khả năng nào chấp nhận cho x i thì ta lùi lại bước trước i-1 để xác định thành phần x i-1 . Để đơn giản, ta giả định các khả năng lựa chọn cho các x i tại mỗi bước là như nhau, do đó phải có thêm một thao tác kiểm tra khả năng j nào là chấp nhận được cho x i . Mô hình của phương pháp quay lui có thể viết bằng thủ tục sau với n là số bước cần phải thực hiện, k là số khả năng mà x i có thể lựa chọn. Try(i) { for(j=1 → k) if(x i chấp nhận được khả năng j) { Xác định x i theo khả năng j; Ghi nhận trạng thái mới; If(i<n) Try(i+1) Else Ghi nhận nghiệm; Trả lại trạng thái cũ; } } SVTH:Phan Lữ Đặng Bình - Đỗ Thế Viên – Hà Phước Việt – Lê Thanh Vũ – Nhóm 12A Page 4 Đồ án cấu trúc dữ liệu và giải thuật  GVHD:Phan Thanh Tao 2.Đệ quy và giải thuật đệ quy : a. Khái niệm : Ta nói một đối tượng là đệ quy nếu nó được định nghĩa qua chính nó hoặc một đối tượng khác cùng dạng với chính nó bằng quy nạp. b. Giải thuật : Nếu lời giải của một bài toán P được thực hiện bằng lời giải của bài toán P’ có dạng giống như P thì đó là một lời giải đệ quy. Giải thuật tương ứng với lời giải như vậy gợi là giải thuật đệ quy. Lưu ý : P’ tuy có dạng giống như P, nhưng theo một nghĩa nào đó, P’ phải «nhỏ » hơn P , dễ giải hơn P và việc giải nó không câng dùng đến P. Định nghĩa một hàm đệ quy hay một thủ tục đệ quy gồm hai phần :  Phần neo(anchor) : Phần này được thực hiện khi mà công việc quá đơn giản, có thể giải trực tiếp chứ không cần phải nhờ đến một bài toán con nào cả.  Phần đệ quy : Trong trường hợp bài toán chưa thể giải được bằng phần neo, ta xác định nhữn bài toán con và gọi đệ quy giải những bài toán con đó. Khi đã có lời giải (đáp số) của những bài toán con rồi thì phối hợp chúng lại để giải bài toán đang quan tâm. Phần đệ quy thể hiện tính « quy nạp » của lời giải. Phần neo cũng rất quan trọng bởi nó quyết định tới tính hữu hạn dừng của lời giải. c. Ví dụ về giải thuật đệ quy : Hàm tính giai thừa : Int factorial(int n) SVTH:Phan Lữ Đặng Bình - Đỗ Thế Viên – Hà Phước Việt – Lê Thanh Vũ – Nhóm 12A Page 5 Đồ án cấu trúc dữ liệu và giải thuật  GVHD:Phan Thanh Tao { If (n==0) return 1 ; // phần neo Else return n* factoria l(n-1) ; // phần đệ quy } Ở đây, phần neo định nghĩa kết quả hàm tịa n=0, còn phần đệ quy (ứng với n>0) sẽ định nghĩa kết quả hàm qua giá trị của n và giai thừa của n-1. Ta thử tính với 3 ! thì trước hết nó phải đi tính 2 ! bởi 3! được tính bằng tích của 3*2 !. Tương tự để tính 2 !, nó lại tính 1 ! bởi 2 !=2*1 !. Áp dung bước quy nạp này thêm một lần nữa , 1 !=1*0 ! , và đạt tới trường hợp của phần neo, đến giá trị 1 của 0 ! , nó tính được 1 != 1*1 ; từ giá trị của 1 ! tính được 2 !; từ giá trị của 2 ! tính được 3 !; cuối cùng cho kết quá là 6 : 3.Quy hoạch động: Đối với nhiều thuật toán, phương pháp chia để trị thường đóng vai trò chủ đạo trong việc thiết kế thuật toán trong phương pháp quy hoạch động lại càng tận dụng phương pháp này: khi không biết cần phải giải bài toán con nào, ta giải tất cả các bài toán con và lưu trữ những lời giải này(để khỏi phải tính toán lại ) nhằm sử dụng lại chúng để giải quyết bài toán lớn hơn. Phương pháp này tổ chức tìm kiếm lời giải theo kiểu từ dưới lên. Xuất phát từ các bài toán nhỏ và đơn giản nhất, tổ hợp các lời giải của chúng để có lời giải của bài toán lớn hơn. Và cứ như thế để tìm lời giải của bài toán ban đầu. SVTH:Phan Lữ Đặng Bình - Đỗ Thế Viên – Hà Phước Việt – Lê Thanh Vũ – Nhóm 12A Page 6 Đồ án cấu trúc dữ liệu và giải thuật  GVHD:Phan Thanh Tao Khi sử dụng phương pháp này để giải quyết vấn đề ta có thể gặp 2 khó khăn sau: 1. Số lượng lời giải của bài toán con có thể rất lớn không thể chấp nhận được. 2. Không phải lúc nào sự kết hợp lời giải của các bài toán con cũng cho ra lời giải của bài toán lớn. Để giải quyết những trường hợp như vậy phương pháp quy hoạch động dựa vào một nguyên lý gọi là nguyên lý tối ưu của Bellman: “Nếu lời giải bài toán là tối ưu thì lời giải của các bài toán con cũng tối ưu”. Trong thuật toán quy hoạch động thường dùng các thao tác: − Xây dựng một hàm quy hoạch động(hoặc phương trình quy hoạch động). − Lập bản lưu lại các giá trị của hàm. − Truy xuất lời giải tối ưu của bài toán từ bảng lưu. II. Mô tả bài toán : 1.Yêu cầu : Nhập từ bàn phím một số n và in ra màng hình số cách phân tích n thành tổng của dãy các số nguyên dương, các cách phân tích là hoán vị của nhau thì chỉ tính là 1. 2.Ví dụ : N = 5 thì có 7 cách phân tích : 1. 5= 1+1+1+1+1 2. 5= 1+1+1+2 3. 5= 1+1+3 4. 5= 1+2+2 5. 5= 1+4 6. 5= 2+3 7. 5= 5 SVTH:Phan Lữ Đặng Bình - Đỗ Thế Viên – Hà Phước Việt – Lê Thanh Vũ – Nhóm 12A Page 7 Đồ án cấu trúc dữ liệu và giải thuật  GVHD:Phan Thanh Tao C. GIẢI THUẬT I. Thuật toán quay lui : 1.Phương thức : Giải thuật này sẽ liệt kê tất cả các cách phân tích 1 số n thành tổng của dãy các số nguyên dương. 2.Giải thuật : Ta sẽ lưu nghiệm trong mảng x, ngoài ra có một mảng t. Mảng t xây dựng như sau : t[i] sẽ là tổng các phần tử trong mảng x từ x[1] đến x[i] : t[i]= x[1] + x[2] + … + x[i]. Khi liệt kê các dãy x có tổng các phần tử đúng bằng n, để tránh trùng lặp ta đưa thêm ràng buộc . Vì số phần tử thực sự của mảng x là không cố định nên thủ tục in() dùng để in ra 1 cách phân tích phải có thêm tham số cho biết sẽ in ra bao nhiêu phần tử. Thủ tục đệ quy thu(i) sẽ thử các giá trị có thể nhận của x[i]( ). Để tổng quát cho i=1, đặt x[0]=1 và t[0]= 0.  Xét các giá trị của x[i] từ x[i-1] đến (n-t[i-1]) div 2, cập nhật t[i]=t[i-1]+x[i] và gọi đệ quy tiếp.  Cuối cùng xét giá trị x[i]=n-t[i-1] và in kết quả từ x[1] đến x[i]. Input : nhập từ bàn phím sô nguyên dương n<100. Output : xuất ra các cách phân tích số n. SVTH:Phan Lữ Đặng Bình - Đỗ Thế Viên – Hà Phước Việt – Lê Thanh Vũ – Nhóm 12A Page 8 Đồ án cấu trúc dữ liệu và giải thuật  GVHD:Phan Thanh Tao 3. Chương trình: #include<conio.h> #include<stdio.h> #include<math.h> #include<stdlib.h> #include<dos.h> #define max 100 int x[max],t[max],n;long count; void in(int k) {int i; printf("\ncach %ld:: %d=",count++,n); for(i=1;i<k;i++) printf("%d+",x[i]); printf("%d",x[k]); } void thu(int i) {int j; for(j=x[i-1];j<=(n-t[i-1])/2;j++) {x[i]=j; t[i]=t[i-1]+j; thu(i+1); } x[i]=n-t[i-1]; in(i); } SVTH:Phan Lữ Đặng Bình - Đỗ Thế Viên – Hà Phước Việt – Lê Thanh Vũ – Nhóm 12A Page 9 Đồ án cấu trúc dữ liệu và giải thuật  GVHD:Phan Thanh Tao main() { count=1; do{printf("\nn=");scanf("%d",&n);}while(n>40); x[0]=1; t[0]=0; thu(1); getch(); } II. Thuật toán đệ quy : 1.Phương thức : Với phương thức sử dụng ở thuật toán quay lui chúng ta sẽ gặp rắc rối ở những trường hợp n tương đối lớn vì khi đó in số cách phân tích là rất lớn. Ở đây chúng ta chỉ in ra có bao nhiêu cách chứ không liệt kê ra các cách theo phương pháp đệ quy. Để làm được điều đó ta cần xây dựng công thức truy hồi cần thiết. 2. Giải thuật xây dựng công thức truy hồi: Gọi F[m,v] là sô cách phân tích số v thành tổng các số nguyên dương m. Khi đó : Các cách phân tích số v thành tổng các số nguyên dương m có thể chia làm 2 loại :  Loại 1 : không chứa số m trong phép phân tích, khi đó số cách phân tích loại này chính là số cách phân tích số n thành tổng các số nguyên dương < m, tức là số cách phân tích số v thành tổng các số nguyên dương m-1 và bằng F[m-1,v].  Loại 2 : có chưa ít nhất 1 số m trong phép phân tích. Khi đó nếu trong các cách phân tích loại này ta bỏ đi số m đó thì ta sẽ được các cách phân tích sô v – m thành tổng các số nguyên dương m(Lưu ý : điều này chỉ đúng khi không tính lặp lại các hoán vị của 1 cách). Có nghĩa là về mặt số lượng, số các cách phân tích loại này bằng F[m, v-m]. SVTH:Phan Lữ Đặng Bình - Đỗ Thế Viên – Hà Phước Việt – Lê Thanh Vũ – Nhóm 12A Page 10 [...]... biết số cách ph n tích, với việc sử dụng ng n xếp để lưu giá trị n n t n bộ nhớ Phương pháp n y cũng có độ phức tạp hàm mũ (O ( 2n) ) Với thuật to n quy hoạch động, ta tiết kiệm được bộ nhớ, có thể thực hi n với n l n Tuy nhi n, n cũng chỉ cho ta biết được số cách ph n tích Phương pháp n y có độ phức tạp O (n 2) Phương pháp n y tối ưu nhất (trong trường hợp bài to n ta đang xét) SVTH:Phan Lữ Đặng Bình... F[m’,v’] với dữ liệu nhỏ h n Tất nhi n, cuối cùng ta sẽ quan tâm đ n F [n, n] : số các cách ph n tích số n thành tổng các số nguy n dương n 3 Cài đặt đệ quy: #include #include #include long f(int m,int v) { if(m==0) { if(v==0) return 1; else return 0; } else { if(m>v) return f(m -1, v); else return (f(m -1, v)+f(m,v-m)) } } ; main() { int m ,n, v; do{printf( "n= ");scanf("%d", &n) ;}while (n> 80);... động 2 Giải thuật : Khởi tạo dòng 0 của bảng, sau đó dùng dòng 0 tính dòng 1, dùng dòng 1 tính dòng 2 v.v… tới khi tính được hết dòng n Mỗi giá trị được tính theo công thức truy hồi tr n và lưu vào mảng F[m,v] số cách ph n tích là F [n, n] Ví dụ : n= 5 ta có bảng sau : SVTH:Phan Lữ Đặng Bình - Đỗ Thế Vi n – Hà Phước Việt – Lê Thanh Vũ – Nhóm 12 A Page 12  Đồ n cấu trúc dữ liệu và giải thuật GVHD:Phan... dòng kế tiếp Không c n dùng mảng 2 chiều để tối ưu và tiết kiệm không gian nhớ #include #include int main() { unsigned long f [10 00]; int v,m ,n, i; printf("Nhap so nguyen duong n= "); scanf("%ld", &n) ; while (n 0 đều là 0 Vậy giải thuật dựng rất đ n gi n: Khởi tạo dòng 0 của bảng F: F[0, 0] = 1 c n F[0, v] với mọi v > 0 đều bằng 0, sau đó dùng công thức truy hồi tính. .. GVHD:Phan Thanh Tao Nh n vào bảng F , ta thấy rằng F[m,v] được tính bằng tổng của : Một ph n tử ở hành tr n :F[m -1, v] và 1 thành ph n ở cùng hàng b n trái F[m,v-m] Ví dụ : F[5,5] sẽ được tính bằng F[4, 5] + F[5, 0], hay F[3, 5] sẽ được tính bằng F[2, 5] + F[3, 2] Chính vì vậy để tính F[m, v] thì F[m - 1, v] và F[m, v - m] phải được tính trước Suy ra thứ tự hợp lý để tính các ph n tử trong bảng F sẽ phải... các ph n tử của bảng F Cuối cùng F [n, n] là số cách ph n tích c n tìm 3.Chương trình : a Dạng 1 : #include #include #define max 10 0 main() { int F[max][max]; int n, m, v; printf("\nnhap vao so n can phan tich : "); scanf("%d", &n) ; for(v=0;v< =n; v++) F[0][v]=0; F[0][0] =1; for(m =1; m< =n; m++) for(v=0;v< =n; v++) { if(v . ch n đề tài Với số tự nhi n n cho trước tính xem có bao nhiêu cách biểu di n n thành tổng của 1 hay nhiều số tự nhi n khác” để tìm hiểu và nghi n cứu. Trong quá trình thực hi n đồ n, chúng. Page 1 Đồ n cấu trúc dữ liệu và giải thuật  GVHD:Phan Thanh Tao A. Giới thiệu đề tài: T n đề tài: Với số tự nhi n n cho trước tính xem có bao nhiêu cách biểu di n n thành tổng của 1 hay nhiều. nhiều số tự nhi n khác(không tính đ n thứ tự của các số hạng, ví dụ 3=2 +1= 1+2 coi như là một cách biểu di n) Có nhiều phương pháp đề giải quyết bài to n. Trong đồ n n y, chúng em ph n tích

Ngày đăng: 10/04/2015, 16:24

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

w