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

Tiểu luận môn lập trình trí tuệ nhân tạo Lập trình hàm và lập trình Logic

17 692 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 17
Dung lượng 785,5 KB

Nội dung

LỜI NÓI ĐẦULập trình trí tuệ nhân tạo là một công nghệ tiên tiến đã và đang làm thay đổi có tính cách mạng trong rất nhiều lĩnh vực, đặc biệt là trong lĩnh vực trí tuệ nhân tạo, gia

Trang 1

ĐẠI HỌC ĐÀ NẴNG

TIỂU LUẬN MÔN

Giảng viên hướng dẫn: PGS.TS Phan Huy Khánh Học viên thực hiện :

Võ Phi Thanh Nguyễn Trần Sỹ Hoàng Công Tiến Nguyễn Thị Hà Phương

Quảng Bình, tháng 12 năm 2012

Trang 2

MỤC LỤC

MỤC LỤC 2

LỜI NÓI ĐẦU 3

PHẦN I LÝ THUYẾT 4

I.1 Kiểu dữ liệu trong Scheme 4

I.2 Kiểu tập hợp (set) trong Scheme 4

I.2.1 Khái niệm 4

I.2.2 Các phép toán 6

PHẦN II BÀI TẬP 9

II.1 Lập trình hàm 9

II.1.1 Phân tích bài toán 9

II.1.2 Chương trình bằng ngôn ngữ Scheme 11

II.1.3 Kết quả chạy chương trình Scheme 12

II.2 Lập trình logic 13

II.2.1 Phân tích bài toán 13

II.2.2 Chương trình bằng Prolog 14

II.2.3 Kết quả chạy chương trình 15

KẾT LUẬN 16

TÀI LIỆU THAM KHẢO 17

Trang 3

LỜI NÓI ĐẦU

Lập trình trí tuệ nhân tạo là một công nghệ tiên tiến đã và đang làm thay đổi có tính cách mạng trong rất nhiều lĩnh vực, đặc biệt là trong lĩnh vực trí tuệ nhân tạo, giao tiếp hệ thống,

xử lý ngôn ngữ tự nhiên, tính toán hình thức.

Vận dụng những kiến thức thu nhận được trong quá trình học tập, tìm hiểu và nghiên cứu

về môn Lập trình trí tuệ nhân tạo, được sự phân công và hướng dẫn của thầy giáo PGS.TS Phan Huy Khánh, chúng tôi đã chọn một phần nội dung kiến thức để đi sâu nghiên cứu và làm

đề tài tiểu luận cho môn học.

Nội dung của tiểu luận được chia làm 2 phần như sau:

Phần I Lý thuyết: Đề cập đến các vấn đề cơ bản về cấu trúc dữ liệu kiểu tập hợp (set) trong ngôn ngữ lập trình hàm Scheme

Phần II Bài tập: Gồm 2 nội dung: Lập trình hàm và lập trình Logic

Lập trình hàm: Viết chương trình bằng Scheme để tính tổng (Bài tập 6):

6 5

4 3

2 4 3

2 2

x x x x x

Với độ chính xác  =10-5

Lập trình Logic: Viết chương trình Prolog mô phỏng các hàm đệ quy thực hiện kiểm tra số nguyên tố (Test for Prime) và đồng dư (Congruent) a ≡ b mod c (Bài tập 3)

- numdiv(x) = divisors_leq(x, x)

- divisors_leq(x, 0) = 0

- divisors_leq(x, y+1) = divisors_leq(x, y) + test(remaind(x, y+1))

- is_prime(x) = equal(numdiv(x), 2)

- congruent(a, b, c) = equal(remaind(a, c), remaind(b, c))

Trang 4

PHẦN I LÝ THUYẾT Câu 11 Kiểu cấu trúc dữ liệu truyền thống tập hợp (set) trong scheme

I.1 Kiểu dữ liệu trong Scheme

Kiểu dữ liệu (data type) là một tập hợp các giá trị có quan hệ cùng loại với nhau (related values) Các kiểu dữ liệu được xử lý theo bản chất của chúng và thường có tính phân cấp Trong Sheme có 2 loại dữ liệu là kiểu đơn giản (simple data type) và kiểu phức hợp (compound data type).

Kiểu đơn giản bao gồm: kiểu số (number), kiểu lôgic (boolean), kiểu ký tự (character) và kiểu ký hiệu (symbol).

Kiểu phức hợp gồm: kiểu tập hợp (set), kiểu mảng (array), kiểu chuỗi (string), kiểu vectơ (vector), kiểu bộ đôi (doublet), kiểu danh sách.

Trong phạm vi của đề tài này chúng tôi chỉ trình bày chi tiết về kiểu cấu trúc dữ liệu truyền thống tập hợp trong Scheme.

I.2 Kiểu tập hợp (set) trong Scheme

I.2.1 Khái niệm

Trong toán học, tập hợp (set) là một nhóm hay một bộ sưu tập các đối tượng phân biệt {x1, x2, …, x2}, được gọi là các phần tử (elements) của tập hợp Do mỗi phần tử của tập hợp chỉ được liệt kê một lần và không được sắp xếp thứ tự nên người ta không nói đến phần tử thứ nhất, phần tử thứ hai, v.v… Ví dụ hai tập hợp sau đây là đồng nhất:

{a, b, d, a, d, e, c, d} = {a, b, c, d}

Do tập hợp cũng là một danh sách, người ta có thể sử dụng cấu trúc danh sách để biểu diễn tập hợp trong Scheme Như vậy, một tập hợp rỗng là một danh sách rỗng Để

so sánh hai tập hợp bằng nhau không, ta có thể sử dụng vị từ equal? Như sau:

(define (setequal? E1 E2)

(cond ; hai tập hợp rỗng thì bằng nhau

((and (null? E1) (null? E2)) #t)

; hai tập hợp có hai phần tử đầu tiên bằng nhau ((equal? (car E1) (car E2))

(setequal? (cdr E1) (cdr E2)))

; hai tập hợp có hai phần tử đầu tiên khác nhau thì khác nhau!

(else #f))) (setequal? '(1 3 4 5 6) '(1 3 4 5 6)

Trang 5

> #t

Hoặc:

(define E1 '(a b c d e))

(define E2 E1)

(setequal? E1 E2)

> #t

Để ý rằng trong vị từ setequal? Trên đây, ta chưa xử lý hai tập hợp có các phần tử giống nhau và có cùng số phần tử, nhưng không được sắp xếp thứ tự như nhau:

(setequal? '(1 3 4 5 6) '(1 3 4 5 6))

> #f

Sau đây ta sẽ sử dụng thường xuyên hàm member để sử lý tập hợp Hàm này kiểm tra một phần tử có thuộc danh sách đã cho hay không:

; trường hợp phần tử kiểm tra có kiểu đơn giản

(member 'c '(a b c d e))

> '(c d e)

; trường hợp phẩn tử kiểm tra có kiểu phức hợp

(member (list 'a) '(b (a) c))

> '((a) c)

Vị từ in? kiểm tra một phần tử có thuộc một tập hợp đã cho hay không?

(define (in? x E)

(cond ((null? E) #f) ; danh sách rỗng

((member x E) #t) ; x là phần tử kiểu đơn giản (else (in? x (cdr E))))) ; x là phần tử kiểu phức hợp

(in? 'c E1)

> #t

Để xây dựng một tập hợp từ một danh sách, người ta phải loại bỏ các phần tử trùng lặp Hàm list->set sau đây sử dụng hàm member lần lượt kiểm tra các phần tử của danh sách đã cho Kết quả trả về chỉ giữ lại phần tử cuối cùng đối với những phần

tử trùng nhau và chưa sắp xếp lại các phần tử theo thứ tự

(define (list -> set L)

(cond ((null? L) '())

((member (car L) (cdr L))

(list -> set (cdr L))) (else (cons (car L)

(list -> set (cdr L)))))

Trang 6

(list -> set '(a b d a d e c d))

> '(b a e c d)

(define (union? E1 E2)

(cond ((null? E1) E2)

((member (car E1) E2) (union2 (cdr E1) E2)) (else (cons (car E1) (union2 (cdr E1) E2)))))

I.2.2 Các phép toán

I.2.2.1 Phép hợp trên các tập hợp

Giả sử cho hai tập hợp E1 và E2, ta cần tìm kết quả của phép hợp của hai tập hợp E1E2 là một tập hợp như sau:

(define (union2 E1 E2)

(cond ; tập hợp thứ nhất rỗng thì kết quả là tập hợp thứ hai

((null? E1) E2)

; nếu tập hợp thứ nhất có phần tử thuộc tập hợp thứ hai thì bỏ qua

((member (car E1) E2) (union2 (cdr E1) E2))

; tiếp tục sau khi gảm kích thước tập hợp thứ nhất (else (cons (car E1) (union2 (cdr E1) E2))))) (union2 '(1 2 3 7) '(2 3 4 5 6))

> '(1 7 2 3 4 5 6)

Mở rộng phép hợp của hai tập hợp, ta xây dựng phép hợp trên các tập hợp bất kỳ bằng cách sử dụng hàm list-it:

(define (union Lset)

(list-it union2 Lset '())) (union '(1 2 3 4) '(2 3 4 5 6) '(4 5 6 7) '(6 7 8))

> '(1 2 3 4 5 6 7 8)

I.2.2.2 Phép giao trên các tập hợp

Tương tự cách xây dựng phép hợp trên các tập hợp bất kỳ, trước tiên ta xây dựng phép giao của hai tập hợp E1E2 như sau:

(define (intersection2 E1 E2)

(cond ; nếu một tập hợp là rỗng thì kết quả cũng rỗng

((null? E1) E1)

; chon ra phần tử nằm ở cả hai tập hợp ((member (car E1) E2) (cons (car E1)

(intersection2 (cdr E1) E2)))

Trang 7

; tiếp tục sau khi giảm kích thước tập hợp thứ nhất (else (intersection2 (cdr E1) E2))))

(intersection2 '(1 2 3 4) '(2 3 4 5 6))

> '(2 3 4)

Mở rộng phép giao của hai tập hợp, ta xây dựng phép giao trên các tập hợp bất kỳ bằng cách sử dụng hàm apply đã được định nghĩa ở mục Error! Reference source not found.:

(define (intersection Lset)

(cond ; giao của các tập hợp rỗng cũng là rỗng

((null? Lset) '())

; giao của một tập hợp là chính nó ((null? (cdr Lset)) (car Lset))

; đưa về thực hiện phép giao của hai tập hợp (else (intersection2

(car Lset) (apply intersection (cdr Lset)))))) (intersection '(1 2 3 4) '(2 3 4 5 6) '(4 5 6 7))

> '(4)

I.2.2.3 Phép hiệu của hai tập hợp

Cho hai tập hợp E1 và E2, ta định nghĩa phép hiệu của hai tập hợp E1\E2 như sau: (define (difference E1 E2)

(cond ; nếu E2 rỗng thì kết quả là E1

((null? E2) E1)

; nếu E1 rỗng thì kết quả là rỗng ((null? E1) '())

; nếu E1 có phần tử thuộc E2 thì bỏ qua ((member (car E1) E2)

(difference (cdr E1) E2))

; nếu tiếp tục sau khi giảm kích thước tập hợp E1 (else (cons (car E1)

(difference (cdr E1) E2))))) (defference '(1 2 3 4 5) '(1 2))

> '(3 4 5)

I.2.2.4 Tìm các tập hợp con của một tập hợp

Cho trước tập hợp E, ta tìm tập hợp tất cả các tập con (sub-set) của E, ký hiệu 2E Chẳng hạn cho E = {a, b, c} thì 2E = {, {a}, {b}, {c}, {a, b}, {a, c}, {b, c}, {a, b, c}}

có tất cả 8 phần tử bao gồm tập hợp rỗng và bản thân tập hợp E

Trang 8

Nếu tập hợp E rỗng, thì 2E cũng rỗng Nếu E khác rỗng, xét một phần tử aE, khi

đó có các tập hợp con chứa a và các tập hợp con không chứa a Đầu tiên xây dựng tập hợp E\{a}, sau đó, chèn vào tất cả các tập hợp con của E\{a} Ta có hàm subset như sau:

(define (subset E)

(if (null? E)

(list '()) (let ((Lremain (subset (cdr E))))

(append Lremain

(map (lambda (L)

(cons (car E) L))

Lremain))))) (subset '(a b c))

> '(() (c) (b) (b c) (a) (a c) (a b) (a b c))

Trang 9

PHẦN II BÀI TẬP II.1 Lập trình hàm

6 5

4 3

2 4 3

2 2

x x x x x

Với độ chính xác  =10-5

II.1.1 Phân tích bài toán

Tổng:

6 5

4 3

2 4 3

2

2

x x x x x

S

có thể viết lại như sau:

) 1 (

1

2 ) 2 ( 2 ) 2

(

x i

i S

j j

i

n

Các chỉ số lặp có bước nhảy là +2

Với j=2 ta có

2

Với j=4 ta có

4 3

2 2

Đây là một tổng dương, tăng vô hạn

Xét phần tử thứ n:

Sn = i i x j

j j

i

1

2

)

2

(

2

Theo yêu cầu của bài toán, tổng S dừng khi phần tử Sn <=  Ta thấy xn/n nếu x càng lớn thì xn -> rất nhanh khi n->, do đó cần phải xác định x thuộc khoảng nào

để đảm bảo thuật toán dừng với điều kiện Sn <= .

Vậy, điều kiện của x để thỏa mãn yêu cầu bài toán là x  [0 2)

Giải thuật

Đối với các bài toán tính tổng một dãy số với độ chính xác  nào đó thì việc sử

dụng phương pháp đệ qui để giải quyết là không khuyến khích, bởi sẽ làm cho việc tiêu tốn bộ nhớ tăng lên đáng kể Phương pháp tốt là dùng phương pháp tích lũy dần sẽ tiết kiệm được bộ nhớ rất nhiều mang lại hiệu quả cho bài toán.

Trang 10

Để thực hiện phép lặp tính tổng S ta cần xây dựng hàm tính giá trị của một phần

tử thứ j (j=2 n,(+2)) TICH( x, j ,R) với biến chạy là i, đích của i là j-2 và R chứa kết quả của tích

Sau đó ta xây dựng hàm tính TONG(x, eps, Rs) với j là biến chạy, eps là điều kiện dừng, Rs là biến tích lũy kết quả tính tổng.

Thuật toán lặp:

o khởi động biến chứa kết quả của tổng S=1// biến tổng tích lũy

o khởi động biến lặp j=2

o 

o Lặp //vòng lặp tính tổng

số hạng R =1

o Bước 3:

o Bước 4:

o Kiểm tra nếu R >=  thì quay về bước 2

o Kết thúc và in kết quả

Mã giả của hàm TICH( x, j ,R) theo phương pháp lặp

Function TICH( x, j,R)

{

If x>1 return 0 // không thỏa mãn điều kiện TICH <eps

Else

{

R=1 For i=2 to j-2 do R=R*i/(i+1) R=R*x^j/j

}

Return R

Trang 11

Mã giã theo phương pháp đệ qui

Function TICH(x, j)

{

If x>1 return 0 // không thỏa mãn điều kiện TICH <eps

Else

If j=2 TICH =1 Else TICH = i/(i+1)*TICH(x,i+2,j-2) }

TICH=TICH*x^j/j

}

Mã giả Hàm TONG(x, eps)

Function TONG(x, eps)

{

S = 1

I=2

If x>1 return 1 // tổng không xác định theo điều kiện eps

Else

Do {

S = S + TICH(x,j) J=j+2

} While (TICH(x,j)>=eps) Return S

}

}

II.1.2 Chương trình bằng ngôn ngữ Scheme

(define (sumx x) ; định nghĩa hàm tính tổng sumx

(define (isumx n s) ; định nghĩa hàm lặp tính tổng

(if ( < (sohang x n) 0.000001) ; kiểm tra điều kiện dừng

s

(isumx ( + n 1) ( + s (sohang x n))))) ; biểu thức lặp

để tính tổng

(isumx 2 (+ 1 (/ (* x x) 2)))) ; giá trị khởi động

(define (sohang x1 j) ; định nghĩa hàm tính giá trị của một số hạng

thứ j

(define (itich i s1) ; hàm lặp tính tích

Trang 12

(if ( > i (* 2 j)) ;điều kiện dừng

( * s1 ( / (expt x1 ( * 2 j)) (* 2 j)))

(itich ( + i 2) (* s1 ( / i ( + i 1)))))) ; lặp tính

tích i=2->i>j-2

(itich 2 1)) ; giá trị khởi động

II.1.3 Kết quả chạy chương trình Scheme

Welcome to DrScheme, version 360

> (sumx 0.1)

1.0050133333333333

> (sumx 0.2)

1.0202182095238097

> (sumx 0.5)

1.1347666222666224

> (sumx 0.9)

1.592667214172984

> (sumx 1.0)

2.1274910366817195

> (sumx 1.1)

4.50444030771407e+038

> (sumx 1.2)

1.0583625201649785e+077

> (sumx 1.5)

6.384531740134797e+175

> (sumx 1.7)

1.9385448564751084e+231

> (sumx 2.0)

Máy treo

Máy chạy không dừng khi x >=2

Trang 13

II.2 Lập trình logic

Câu 3 Hãy viết chương trình Prolog mô phỏng các hàm đệ quy thực hiện kiểm tra số

nguyên tố (Test for Prime) và đồng dư (Congruent) a ≡ b mod c :

- numdiv(x) = divisors_leq(x, x)

- divisors_leq(x, 0) = 0

- divisors_leq(x, y+1) = divisors_leq(x, y) + test(remaind(x, y+1))

- is_prime(x) = equal(numdiv(x), 2)

- congruent(a, b, c) = equal(remaind(a, c), remaind(b, c))

II.2.1 Phân tích bài toán

Xây dựng hàm test

test(X,1):-X=:=0

test(X,0):-X=\=0

Xây dựng hàm s

s(A,B):-suss(A,B)

Xây dựng hàm equal

equal(X,Y):-X=:=Y

Xây dựng hàm remaind

% Doan chuong trinh de tinh: Numerator mod Denominator va luu so du vao bien R

remaind(Numerator, Denominator,R)

:-rem(Denominator, Numerator,R)

rem(X,Y,Y):-Y < X

rem(X, Y,

R):-Y >= X, Y1 is Y - X, rem(X,Y1,R)

Xây dựng hàm numdiv

% Doan chuong trinh de dem so luong cac uoc cua X va luu so luong cac uoc vao bien N

numdiv(X,N) :- divisors_leq(X,X,N)

Trang 14

divisors_leq(X,Y,N)

:-Y>=0, Y1 is Y - 1, divisors_leq(X,Y1,N1), remaind(X,Y,R),

test(R,A),

N is N1 + A

Xây dựng hàm is_prime

% Doan chuong trinh de kiem tra X co phai la snt khong?

is_prime(X):-numdiv(X,N), equal(N,2)

Xây dựng hàm congruent

is_congruent(X,Y,Z):-remaind(X,Z,R1)=:= remaind(Y,Z,R2)

II.2.2 Chương trình bằng Prolog

test(X,1):-X=:=0

test(X,0):-X=\=0

s(A,B):-suss(A,B)

equal(X,Y):-X=:=Y

% Doan chuong trinh de tinh: Numerator mod Denominator va luu

so du vao bien R

remaind(Numerator, Denominator,R)

:-rem(Denominator, Numerator,R)

rem(X,Y,Y):-Y < X

rem(X, Y,

R):-Y >= X, Y1 is Y - X, rem(X,Y1,R)

% Doan chuong trinh de dem so luong cac uoc cua X va luu so luong cac uoc vao bien N

Trang 15

numdiv(X,N) :- divisors_leq(X,X,N).

divisors_leq(X,0,0)

divisors_leq(X,Y,N)

:-Y>=0, Y1 is Y - 1, divisors_leq(X,Y1,N1), remaind(X,Y,R),

test(R,A),

N is N1 + A

% Doan chuong trinh de kiem tra X co phai la snt khong?

is_prime(X):-numdiv(X,N), equal(N,2)

is_congruent(X,Y,Z):-remaind(X,Z,R1)=:= remaind(Y,Z,R2)

II.2.3 Kết quả chạy chương trình.

Kiểm tra số nguyên tố:

is_prime(11)

-> yes

is_prime(22)

-> no

Kiểm tra số đồng dư:

is_congruent(23,5,2)

-> yes

is_congruent(23,5,3)

-> no

Trang 16

KẾT LUẬN

Qua thời gian thực hiện đề tài về Lập trình trí tuệ nhân tạo, nhóm chúng em đã trình bày những vấn đề cơ bản của cấu trúc dữ liệu tập hợp trong ngôn ngữ Scheme; Tìm hiểu ngôn ngữ lập trình Scheme để giải quyết các bài toán tính tổng; Tìm hiểu ngôn ngữ lập trình Prolog để giải quyết bài toán số nguyên tố và số đồng dư.

Tuy nhiên, do thời gian và khả năng tiếp cận còn hạn chế nên đề tài chỉ dừng lại ở mức tìm hiểu những lý thuyết cơ bản, chưa nghiên cứu và khai thác hết các chức năng của ngôn ngữ lập trình, đây cũng là hướng phát triển của đề tài trong tương lai.

Xin chân thành cảm ơn Thầy giáo PGS.TS Phan Huy Khánh, đã tận tình giúp đỡ chúng

em hoàn thành tiểu luận này.

Xin chân thành cảm ơn ý kiến đóng góp của thầy giáo và bạn đọc quan tâm để đề tài được hoàn thiện hơn.

Ngày đăng: 23/03/2015, 13:30

TỪ KHÓA LIÊN QUAN

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

TÀI LIỆU LIÊN QUAN

w