Đồ án cấu trúc dữ liệu và giải thuật (Giải sudoku) docx

24 2.3K 45
Đồ án cấu trúc dữ liệu và giải thuật (Giải sudoku) docx

Đ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

Khoa Công Nghệ Thông Tin Đại học Bách Khoa Đà Nẳng Đồ án cấu trúc liệu giải thuật  I.Giới thiệu thuật toán Thuật toán quay lui Thuật tốn quay lui thuật tốn điển hình để giải toán ứng dụng tin học Bằng việc liệt kê tình huống, thử khả tìm thấy lời giải đúng, thuật toán quay lui chia nhỏ toán, lời giải toán lớn sẻ kết việc tìm kiếm theo chiều sâu tập hợp tốn phần tử Trong suốt q trình tìm kiếm gặp phải hướng mà biết khơng thể tìm thấy đáp án quay lại bước trước tìm hướng khác hướng vừa tìm kiếm Trong trường hợp khơng cịn hướng khác nửa thuật tốn kết thúc Khác với thuật toán tham lam (cũng điểm mạnh), thuật tốn quay lui có điểm khác khơng cần phải duyệt hết tất khả năng, nhờ tránh khả khơng nên giảm thời gian giải Thuật toán quay lui thường cài đặt theo lối đệ quy, lần gọi hàm đệ quy, hàm đệ quy truyền tham số (trong tham số) số tốn con, hàm sẻ cố gắng tìm lời giải cho tốn đó, tìm thấy gọi hàm đệ quy để giải toán đưa đáp án toán lớn đầy đủ lời giải, khơng tìm thấy chương trình sẻ trở điểm gọi hàm Mục đích việc sử dụng hàm đệ quy để thuật toán rỏ ràng, dễ viết, dễ hiểu để bảo toàn biến, trạng thái lúc giải tốn Thuật tốn quay lui thể theo sơ đồ tìm kiếm theo chiều sâu bên Từ hình vẽ, ta dễ dàng nhận thấy : Ở toán (mỗi nốt), ta tìm lời giải cho tốn Ứng với lời giải, ta giải toán lúc toán trở gốc nên đầy đủ Lời giải toán gốc thường lối từ gốc đến nốt cuối (khơng có nốt con) Sinh Viên : Võ Quang Hồ Lớp 07T4,Nhóm 12A Trang Khoa Cơng Nghệ Thơng Tin Đại học Bách Khoa Đà Nẳng Đồ án cấu trúc liệu giải thuật  - II.Giới thiệu tốn ứng dụng : Sudoku trị chơi trí tuệ tiếng, thu hút nhiều người tham gia đặc biệt giới trẻ Ra đời Nhật không lâu sau trở nên phổ biến giới Quy luật trò chơi tương đối đơn giản, cho bàn hình vng chia thành lưới 81 ô nhỏ hàng cột 81 nhỏ lại chia thành vùng, vùng có Đề Sudoku bàn hình vng thế, số ô, người ta điền sẳn số giá trị Ví dụ Yêu cầu dùng số từ đên để điền nốt vào cịn lại cho hàng, cột vùng ô, phải điền đầy đủ số từ đến Như ví dụ đáp án sẻ III.Đặc tả cấu trúc liệu giải thuật Cấu trúc liệu Dữ liệu sử dụng chương trình liệu kiểu mảng int [,] row = new int[10, 10]; int [,] collum=new int[10,10]; int [,] area=new int[10,10]; Sinh Viên : Võ Quang Hồ Lớp 07T4,Nhóm 12A Trang Khoa Công Nghệ Thông Tin Đại học Bách Khoa Đà Nẳng Đồ án cấu trúc liệu giải thuật  int [,] AREA=new int[10,10]; int [,] Area = new int[10, 10]; int[, ,] agree = new int[10, 10, 11]; int[,] value = new int[10, 10]; int[,] problem = new int[10, 10]; - - Mảng row,collum, area mảng chiều dùng để đánh dấu hàng, cột, vùng đánh số hay khơng, ví dụ row[2,3]=1 tức hàng đánh số Mảng AREA để mảng cố định, AREA[i,j]=k nghĩa ô hàng i, cột j vùng k Mảng Area để phục vụ cho việc duyệt theo vùng, với giá trị Area [i,j]=k nghĩa vùng i, có trống thứ j k Mảng agree để đánh dấu trống một, điền giá trị Cách diễn tả sau o value[i,j,0]=k nghĩa ô trống hàng i, cột j có k khả điền o Các giá trị value[i,j,1] value[i,j,2] value[i,j,3]… value[i,j,k] khả điền Mảng value mảng chiều để giá trị điền value[i,j]=a tức ô hàng i, cột j điền số agree[i,j,a] o Ví dụ : Nếu argree[1,2,0]=5 giá trị argree[1,2,1]=1, argree[1,2,2]=3, argree[1,2,3]=6, argree[1,2,4]=7, argree[1,2,5]=9, Và value[1,2]=3 có nghĩa ô hàng 1, cột đánh số thứ khả năng, tức đánh số Cách đánh dấu có điểm thuận lợi dễ dàng duyệt khả điền ô, cho phép loại bỏ khả biết khả khơng thuận lợi Sinh Viên : Võ Quang Hồ Lớp 07T4,Nhóm 12A Trang Khoa Công Nghệ Thông Tin Đại học Bách Khoa Đà Nẳng Đồ án cấu trúc liệu giải thuật  IV.Thuật giải 1)Tổng quan o Xác định toán  Input : Đề sudoku, bảng số cho file người dùng nhập giao diện GUI  Output : Kết quả, lời giải sudoku (nếu có) Nếu đề có nhiều đáp án phải xuất nhiều đáp án o Các cách xác định ô số  Xác định theo số thứ tự từ đến 81 Cách ta sẻ sử dụng chủ yếu để duyệt tồn 81 ơ, hay để lấy đề bài, xuất kết giao diện người dùng 10 19 11 20 12 21 13 22 14 23 15 24 16 25 17 26 18 27 28 37 46 29 38 47 30 39 48 31 40 49 32 41 50 33 42 51 34 43 52 35 44 53 36 45 54 55 64 73 56 65 74 57 66 75 58 67 76 59 68 77 60 69 78 61 70 79 62 71 80 63 72 81  Xác định [hàng, cột], Với cách xác định này, ta dễ dàng duyệt theo chiều cột, theo hàng ta có bảng sau [1,1] [1,2] [1,3] [1,4] [1,5] [1,6] [1,7] [1,8] [1,9] [2,1] [2,2] [2,3] [2,4] [2,5] [2,6] [2,7] [2,8] [2,9] [3,1] [3,2] [3,3] [3,4] [3,5] [3,6] [3,7] [3,8] [3,9] [4,1] [4,2] [4,3] [4,4] [4,5] [4,6] [4,7] [4,8] [4,9] [5,1] [5,2] [5,3] [5,4] [5,5] [5,6] [5,7] [5,8] [5,9] [6,1] [6,2] [6,3] [6,4] [6,5] [6,6] [6,7] [6,8] [6,9] [7,1] [7,2] [7,3] [7,4] [7,5] [7,6] [7,7] [7,8] [7,9] [8,1] [8,2] [8,3] [8,4] [8,5] [8,6] [8,7] [7,8] [8,9] [9,1] [9,2] [9,3] [9,4] [9,5] [9,6] [9,7] [9,8] [9,9]  Xác định {vùng, số thứ tự vùng}, Cách xác định cho phép ta duyệt theo vùng ta có bảng {1,1} {1,2} {1,3} {2,1} {2,2} {2,3} {3,1} {3,2} {3,3} {1,4} {1,5} {1,6} {2,4} {2,5} {2,6} {3,4} {3,5} {3,6} {1,7} {1,8} {1,9} {2,7} {2,8} {2,9} {3,7} {3,8} {3,9} {4,1} {4,2} {4,3} {5,1} {5,2} {5,3} {6,1} {6,2} {6,3} {4,4} {4,5} {4,6} {5,4} {5,5} {5,6} {6,4} {6,5} {6,6} Sinh Viên : Võ Quang Hồ Lớp 07T4,Nhóm 12A Trang Khoa Cơng Nghệ Thông Tin Đại học Bách Khoa Đà Nẳng Đồ án cấu trúc liệu giải thuật  {4,7} {4,8} {4,9} {5,7} {5,8} {5,9} {6,7} {6,8} {6,9} {7,1} {7,2} {7,3} {8,1} {8,2} {8,3} {9,1} {9,2} {9,3} {7,4} {7,5} {7,6} {8,4} {8,5} {8,6} {9,4} {9,5} {9,6} {7,7} {7,8} {7,9} {8,7} {8,8} {8,9} {9,7} {9,8} {9,9} - Để ý cách cách dễ dàng chuyển đổi qua lại lẫn công thức Chuyển từ dạng sang dạng x[i,j] int toi(int x) { return (x-1)/9+1; } int toj(int x) { return (x-1)%9+1; } Chuyển từ dạng sang dạng int tox(int i, int j) { return (i - 1) * + j; } Đối với dạng ta lưu thành mảng AREA để sử dụng, mảng này, giá trị AREA[i,j]= số thứ tự dạng 2)Vấn đề Chương trình giải dựa thuật giải quay lui Tư tưởng thuật giải chi nhỏ toán lớn thành toán phần tử, giải tốn phần tử đó, ứng với trường hợp giải toán phần tử đó, ta tìm lời giải cho tốn phần tử toán lớn trở nên đầy đủ void Try(int i){ { } } Ta nhận xét rằng, - Khi xét vị trí thứ i, ta đưa phương án để tiếp tục xét vị trí i+1, có phương án sẻ làm cho vị trí i+1, i+2… tìm tiếp phương án dẫn đến kết cuối (Gọi phương án khả thi) có phương án sẻ khơng có kết (gọi phương án bất khả thi) Vậy để chương trình chạy nhanh, ta cần phải loại bỏ phương án bất khả thi nhiều tốt - Thuật toán biểu diễn đệ quy ta cài đặt đệ quy sẻ khơng có lợi, phải sử dụng bơ nhớ stack, gọi hàm đệ quy nhiều lần, điều làm Sinh Viên : Võ Quang Hồ Lớp 07T4,Nhóm 12A Trang Khoa Công Nghệ Thông Tin Đại học Bách Khoa Đà Nẳng Đồ án cấu trúc liệu giải thuật  chương trình sẻ chạy chậm, Vì ta cài đặt khơng đệ quy mà tin thần giải dựa phương pháp đệ quy Để làm điều này, cần phải có cách cho di chuyển thử khả ô dễ dàng 3)Giải vấn đề o Vấn đề Ta đánh dấu khả điền số tìm cách loại bỏ khả bất khả thi Các bước làm sau  Khởi tạo, tất ô trống có khả điền từ đến 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9  Tạo stack để lưu ô điền Cứ ô [i,j] điền giá trị NewValue, ta tiến hành thao tác sau  Đánh dấu hàng, cột vùng chứa ô [i,j] giá trị NewValue điền không điền nửa cách đặt giá trị row[i,j, NewValue], collum[i,j, NewValue], area[i,j, NewValue]  Đặt giá trị vùng [i,j] sau Agree[i,j,0]=1 (Chỉ giá trị điền), Agree[i,j,1]= NewValue, value[i,j]=1  Với hàng, cột, vùng chứa (tất nhiên phải khác đó) ta loại bỏ khả điền số NewValue khỏi tập khả Ví dụ ô [1,4] điền số 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 Sinh Viên : Võ Quang Hồ Lớp 07T4,Nhóm 12A Trang Khoa Công Nghệ Thông Tin Đại học Bách Khoa Đà Nẳng Đồ án cấu trúc liệu giải thuật   Ta tiến hành tìm số chưa xét đưa vào stack xử lý khơng tìm thấy nửa Đó thỏa mãn  Là hàng (hoặc cột, vùng) điền số Ví dụ hàng điền số ô cột (dấu x), ta sẻ xóa khả điền số ô đánh dấu (-), - - - - x -  Là có khả điền Ở ví dụ sau, [5,6] (Đánh dấu x) điền số Nhờ đánh dấu (-) loại bỏ số khỏi tập phương án, - - - X - - - - - Ngồi kiểm tra có hàng, cột hay vùng mà khơng thể điền giá trị kết sẻ khơng có nghiệm Hoặc có khơng có khả điền, sudoku sẻ khơng có nghiệm o Vấn đề Khử đệ quy thuật toán Tư tưởng chính, ta sử dụng biến điều khiển việc di chuyển lên trước, sau giửa ô số Để việc di chuyển dễ dàng, ta dùng cách xác định ô số thứ Biến điều khiển add sẻ mang giá trị cần phải tiến lên phía trước, -1 quay phía sau Biến index để vị trí Thuật tốn để tìm đáp án tóm tắt sau : o Bước : index =1 (Đang xét ô 1) add=1 (đang tiến) o Bước : Lặp vị trí tiếp ta xét lớn  Nếu index ==82 (nghĩa từ ô đến ô 81 đúng), ta đưa kết thoát Sinh Viên : Võ Quang Hồ Lớp 07T4,Nhóm 12A Trang Khoa Công Nghệ Thông Tin Đại học Bách Khoa Đà Nẳng Đồ án cấu trúc liệu giải thuật   - - Nếu ô có khả tiếp tục vịng lặp (Ta khơng xét này), ln có value[,]  Nếu có giá trị giá trị tối đa, nghĩa khơng thể tăng lên nửa, ta cho giá trị nhỏ nhất, cho add=-1, tiếp tục vòng lặp, lùi trước  Ta cần thay đổi giá trị ô số thời nên giá trị cũ bị bỏ Những ràng buộc giá trị cũ hàng, cột vùng bị bỏ  Tìm giá trị tập khả điền cho tại, giá trị phải đạt yêu cầu :  Chưa điền hàng, cột, vùng chứa  Xây dựng cấu hình sudoku theo chiều hướng tăng theo thứ tự từ điển, nghĩa ta phải tìm giá trị lớn giá trị thời  Nếu bước  Tìm thấy giá trị thỏa mãn ta tạo ràng buộc điền giá trị cột, hàng, ô chứa ô số đó.Cho add=1, sau tiếp tục vịng lặp để tiến tiếp phía sau  Nếu khơng tìm thấy ta cho add=1, tiếp tục vịng lặp ta xét ô liền trước Thực tế, ta không cần tìm đáp án mà ta cịn phải đếm số đáp án, xem đáp án đầu tiên, nên từ thuật tốn trên, ta có số điều chỉnh sau o Ta tạo biến ResultCount để đếm số đáp án tìm được, tìm thấy đáp án ta tăng biến thêm o Ta thêm tham số count cho hàm, tham số số kết  Nếu -1 tức đếm số kết quả, gặp tham số này, ta không xuất kết quả, ResultCount lớn tối đa số kết cần tìm khơng tìm thấy kết nửa ta trả giá trị ResultCount  Nếu là in kết đầu tiên, chương trình sẻ chạy thuật tốn Nếu tim thấy kết quả, chương trình sẻ xuất kết trả giá trị 1, không thấy, trả 0;  Nếu số dương ta sẻ in kết ResultCount == count, Nếu tim thấy kết quả, chương trình sẻ xuất kết trả giá trị 1, không thấy, trả 0; Chương trình giải Do cài đặt C#, thuật tốn cài đặt lớp SDK, lớp có phương thức sau quan trọng: o public SDK(int[] _pro) : Tạo đối tượng lớp SDK, khởi tạo giá trị cho biến cần thiết cho hàm giải o private bool inputData(): Đưa đề có dạng mảng hai chiều để khởi tạo mảng dùng cho việc giải mảng agree[,,] mảng value[,] Sinh Viên : Võ Quang Hồ Lớp 07T4,Nhóm 12A Trang Khoa Công Nghệ Thông Tin Đại học Bách Khoa Đà Nẳng o o o o o Đồ án cấu trúc liệu giải thuật  Ngoài ra, hàm phát trường hợp đề có mâu thuẩn (như hàng có giá trị…), lúc đề khơng có đáp án private void preSolve(): Giải thủ công, bước giải để chuẩn bị nhằn hạn chế trường hợp không dẫn tới đáp án cho hàm giải int Solve(int count): Giải đề thuật toán quay lui, tham số int count để điều khiển công việc hàm giải xem đáp án có số thứ tự đó, đếm số đáp án Tùy thuộc tham số cout mà hàm sẻ trả giá trị khác public bool SolveFirst(): Hàm gọi hàm Solve(0) để tìm đáp án Khi hàm Solve(0) sẻ trả tìm thấy, khơng tìm thấy public bool SolveTo(int) : Hàm gọi hàm Solve(int) để giải đến đáp án public int ResultCount():Hàm gọi hàm Solve(-1) để đếm số đáp án đề Khi hàm Solve sẻ giải khơng tìm thấy đáp án nửa trả tổng số đáp án giải đến đáp án thứ 10.000 kết luận đề có nhiều đáp án, trả -1 4) Chương trình giải class SDK { int index=0 , add=1 , i=0, j=0; public int MaxIndexResultCanFind; public int[] Result = new int[82]; public int MaxIndex { get { return MaxIndexResultCanFind; } set { MaxIndexResultCanFind = value; } } bool HaveResult = true; const int size = 9; int tox(int x) { return (x-1)/size+1; } int toj(int x) { return (x-1)%size+1; } Sinh Viên : Võ Quang Hoà Lớp 07T4,Nhóm 12A Trang Khoa Cơng Nghệ Thơng Tin Đại học Bách Khoa Đà Nẳng Đồ án cấu trúc liệu giải thuật  int tou(int x, int y) { return (x - 1) * size + y; } int [,] row = new int[10, 10]; int [,] collum=new int[10,10]; int [,] area=new int[10,10]; int [,] AREA=new int[10,10]; int [,,] agree=new int [size+1,size+1,11]; int [,] value=new int [size+1,size+1]; int [,] Area=new int [size+1,size+1]; int [,] problem=new int[size+1,size+1]; int[] stack=new int [500]; int top = 0; void push(int a) { top++; stack[top] = a; } int pop() { top ; return stack[top + 1]; } void initilizing()//Khởi tạo giá trị cần thiết { int i, j, for (i = 1; i

Ngày đăng: 09/07/2014, 17:20

Từ khóa liên quan

Tài liệu cùng người dùng

Tài liệu liên quan