QUỐC CA Việt Nam

Liên kết website

Time

Quang Lê


Truyện cười

Thành viên trực tuyến

1 khách và 0 thành viên

Thống kê

  • truy cập   (chi tiết)
    trong hôm nay
  • lượt xem
    trong hôm nay
  • thành viên
  • Gốc > Bài viết > Pascal >

    Phương pháp quy hoạch động

       Phương pháp quy hoạch động dùng để giải bài toán tối ưu có tính chất đệ quy, tức là việc tìm phương án tối ưu cho bài toán đó có thể đưa về tìm phương án tối ưu của một số hữu hạn các bài toán con. Đối với nhiều thuật toán đệ quy, nguyên lý chia để trị (devide and conquer) thường đóng vai trò chủ đạo trong việc thiết kế thuật toán. Để giải quyết một bài toán lớn, ta chia nó thành nhiều bài toán con cùng dạng với nó để có thể giải quyết độc lập. Trong phương pháp quy hoạch động, nguyên lý này càng được thể hiện rõ: Khi không biết cần phải giải bài những toán con nào, ta sẽ đi giải quyết tất cả các bài toán con và lưu trữ những lời giải hay đáp số của chúng với mục đích sử dụng lại theo một sự phối hợp nào đó để giải quyết những bài toán tổng quát hơn. Đó chính là điểm khác nhau giữa Quy hoạch động và phépđệ quy và cũng là nội dung Phương pháp quy hoạch động:

     +Phép đệ quy bắt đầu từ bài toán lớn phân rã thành nhiều bài toán con và đi giải từng bài toán con đó. Việc giải từng bài toán con lại đưa về phép phân rã tiếp thành nhiều bài toán con nhỏ hơn và lại đi giải quyết bài toán nhỏ hơn đó bất kể nó đã được giải hay chưa.

    +Quy hoạch động bắt đầu từ việc giải tất cả các bài toán nhỏ nhất (bài toán cơ sở) để từ đó từng bước giải quyết những bài toán lớn hơn, cho tới khi giải được bài toán lớn nhất (bài toán ban đầu).

    Sau đây ta sẽ xét một ví dụ đơn giản và rất quen thuộc: 
    Ví dụ: Dãy Fibonacci là dãy số nguyên dương được định nghĩa như sau:
    F[1]=F[2]=1;
    Với mọi i: 3 = F[i-1] + F[i-2]
    Hãy tính F[6]

    Xét hai cách cài đặt chương trình bằng C++:

     Code:

    * Cách 1 (dùng đệ quy):


    int F(int i)
    {
        if (i<3)
            return 1;
        else
            return F(i-1) + F(i-2);
    }
    int main()
    {
        cout<<F(6);
        return 0;
    }

     Code:

     * Cách 2 (dùng quy hoạch động):

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

    int i;

    int main()
    {
        F[1]=1; F[2]=1;
        for (int i=3;i<=6;++i)
            F[i]=F[i-1]+F[i-2];
        cout<     return 0;
    }
     

     Trong cách 1, ta viết một hàm đệ quy F(i) để tính số Fibonacci thứ i. Chương trình chính gọi F(6), nó sẽ gọi tiếp F(5) và F(4) để tính … Quá trình tính toán có thể vẽ như cây dưới đây. Ta nhận thấy để tính F(6) nó phải tính 1 lần F(5), 2 lần F(4), 3 lần F(3), 5 lần F(2), 3 lần F(1).

     

     

    tinhoche11_012

     

    Cách 2 thì không như vậy. Trước hết nó tính sẵn F[1] và F[2], từ đó tính tiếp F[3], lại tính tiếp được F[4], F[5], F[6]. Đảm bào rằng mỗi giá trị Fibonnaci chỉ phải tính 1 lần.

     (Cách 2 còn có thể cải tiến thêm nữa, chỉ cần dùng 3 biến tính lại giá trị lẫn nhau).


    Trước khi áp dụng phương pháp quy hoạch động ta phải xét xem phương pháp đó có thỏa mãn những yêu cầu dưới đây hay không:
    +Bài toán lớn phải phân rã được thành nhiều bài toán con, mà sự phối hợp lời giải của các bài toán con đó cho ta lời giải của bài toán lớn.
    +Vì quy hoạch động là đi giải tất cả các bài toán con, nên nếu không đủ không gian vật lý lưu trữ lời giải (bộ nhớ, đĩa,…) để phối hợp chúng thì phương pháp quy hoạch động cũng không thể thực hiện được.
    +Quá trình từ bài toán cơ sở tìm ra lời giải bài toán ban đầu phải qua hữu hạn bước.

    Các khái niệm:
    +Bài toán giải theo phương pháp quy hoạch động gọi là bài toán quy hoạch động.
    +Công thức phối hợp nghiệm của các bài toán con để có nghiệm của bài toán lớn gọi là công thức truy hồi của quy hoạch động.
    +Tập các bài toán nhỏ nhất có ngay lời giải để từ đó giải quyết các bài toán lớn hơn gọi là cơ sở quy hoạch động.
    +Không gian lưu trữ lời giải các bài toán con để tìm cách phối hợp chúng gọi là bảng phương án của quy hoạch động.

    Các bước cài đặt một chương trình sử dụng quy hoạch động: (Nhớ kỹ)
    +Giải tất cả các bài toán cơ sở (thông thường rất dễ), lưu các lời giải vào bảng phương án.
    +Dùng công thức truy hồi phối hợp những lời giải của các bài toán nhỏ đã lưu trong bảng phương án để tìm lời giải của những bài toán lớn hơn và lưu chúng vào bảng phương án. Cho tới khi bài toán ban đầu tìm được lời giải.
    +Dựa vào bảng phương án, truy vết tìm ra nghiệm tối ưu.

    Cho đến nay, vẫn chưa có một định lý nào cho biết một cách chính xác những bài toán nào có thể giải quyết hiệu quả bằng quy hoạch động. Tuy nhiên để biết được bài toán có thể giải bằng quy hoạch động hay không, ta có thể tự đặt câu hỏi : “Một nghiệm tối ưu của bài toán lớn có phải là sự phối hợp các nghiệm tối ưu của các bài toán con hay không?” và “Liệu có thể nào lưu trữ được nghiệm các bài toán con dưới một hình thức nào đó để phối hợp tìm được nghiệm bài toán lớn”.

    Cuối cùng trước khi khảo sát một số bài toán quy hoạch động, ta nhắc lại: Phương pháp tốt nhất để giải quyết mọi bài toán trong tin học là biết sử dụng và phối hợp uyển chuyển nhiều thuật toán, không được lạm dụng hay coi thường bất cứ một phương pháp nào./.

    Theo http://bariavungtau.edu.vn


    Nhắn tin cho tác giả
    Âu Trường Sơn @ 17:10 26/02/2014
    Số lượt xem: 1186
    Số lượt thích: 0 người
     
    Gửi ý kiến

    Tin mới nhất