- vừa được xem lúc

Thuật toán tham lam - Greedy Algorithm

0 0 48

Người đăng: Trần Trung Phong

Theo Viblo Asia

Hoàn cảnh

Vì vừa phải tìm hiểu về thuật toán này để đi thi nên chủ đề tháng này của mình xin được viết luôn về nó.

Giới thiệu

Giải thuật tham lam (tiếng Anh: Greedy algorithm) là một thuật toán giải quyết một bài toán theo kiểu metaheuristic để tìm kiếm lựa chọn tối ưu địa phương ở mỗi bước đi với hy vọng tìm được tối ưu toàn cục.

Hiểu một cách đơn giản như sau :

Bây giờ mẹ bạn cho bạn 2 tờ tiền mệnh giá 100.000 đ và 200.000 đ và bạn chỉ được chọn 1. Và đương nhiên mình sẽ chọn tờ 200.000 đ vì nó giá trị hơn mặc dù số lượng và kích thước của 2 tờ đều như nhau.

Một ví dụ khác nhé . Ta có một ba lô có trọng lượng là 37 và 4 loại đồ vật với trọng lượng và giá trị tương ứng, yêu cầu ở đây là bạn sẽ phải chọn tối đa số lượng đồ vật để vừa phù hợp với trọng lượng của ba lô mà giá trị lấy được là lớn nhất.

Từ đó ta có kỹ thuật Tham lam áp dụng cho bài toán này là:

  1. Tính đơn giá cho các loại đồ vật.

  2. Xét các loại đồ vật theo thứ tự đơn giá từ lớn đến nhỏ.

  3. Với mỗi đồ vật được xét sẽ lấy một số lượng tối đa mà trọng lượng còn lại của ba lô cho phép.

  4. Xác định trọng luợng còn lại của ba lô và quay lại bước 3 cho đến khi không còn có thể chọn được đồ vật nào nữa.

Demo tý nhé : Ta có một ba lô có trọng lượng là 37 và 4 loại đồ vật với trọng lượng và giá trị tương ứng được cho như sau :

 Loại đồ vật : A - B - C - D Trọng lượng : 15 - 10 - 2 - 4 Giá trị : 30 - 25 - 2 - 6

Từ bảng đã cho ta tính đơn giá cho các loại đồ vật và sắp xếp các loại đồ vật này theo thứ tự đơn giá giảm dần ta có bảng sau.

 Loại đồ vật : B - A - D - C Trọng lượng : 10 - 15 - 4 - 2 Giá trị : 25 - 30 - 6 - 2 Đơn giá : 2.5 - 2.0 - 1.5 - 1.0

Theo đó thì thứ tự ưu tiên để chọn đồ vật là là B, A, D và cuối cùng là C.

Vật B được xét đầu tiên và ta chọn tối đa 3 cái vì mỗi cái vì trọng lượng mỗi cái là 10 và ba lô có trọng lượng 37. Sau khi đã chọn 3 vât loại B, trọng lượng còn lại trong ba lô là 37 – 3*10 = 7. Ta xét đến vật A, vì A có trọng lượng 15 mà trọng lượng còn lại của balô chỉ còn 7 nên không thể chọn vật A. Xét vật D và ta thấy có thể chọn 1 vật D, khi đó trọng lượng còn lại của ba lô là 7-4 = 3. Cuối cùng ta chọn được một vật C.

Như vậy chúng ta đã chọn 3 cái loại B, một cái loại D và 1 cái loại C. Tổng trọng lương là 310 + 14 + 12 = 36 và tổng giá trị là 325+16+12 = 83.

Thuật toán

Nói chung, giải thuật tham lam có năm thành phần:

  • Một tập hợp các ứng viên (candidate), để từ đó tạo ra lời giải
  • Một hàm lựa chọn, để theo đó lựa chọn ứng viên tốt nhất để bổ sung vào lời giải
  • Một hàm khả thi (feasibility), dùng để quyết định nếu một ứng viên có thể được dùng để xây dựng lời giải
  • Một hàm mục tiêu, ấn định giá trị của lời giải hoặc một lời giải chưa hoàn chỉnh
  • Một hàm đánh giá, chỉ ra khi nào ta tìm ra một lời giải hoàn chỉnh.

Có hai thành phần quyết định nhất tới quyết định tham lam:

Tính chất lựa chọn tham lam

Chúng ta có thể lựa chọn giải pháp nào được cho là tốt nhất ở thời điểm hiện tại và sau đó giải bài toán con nảy sinh từ việc thực hiện lựa chọn vừa rồi. Lựa chọn của thuật toán tham lam có thể phụ thuộc vào các lựa chọn trước đó. Nhưng nó không thể phụ thuộc vào một lựa chọn nào trong tương lai hay phụ thuộc vào lời giải của các bài toán con. Thuật toán tiến triển theo kiểu thực hiện các chọn lựa theo một vòng lặp, cùng lúc đó thu nhỏ bài toán đã cho về một bài toán con nhỏ hơn. Đấy là khác biệt giữa thuật toán này và giải thuật Quy Hoạnh Động. Giải thuật quy hoạch động duyệt hết và luôn đảm bảo tìm thấy lời giải. Tại mỗi bước của thuật toán, quy hoạch động đưa ra quyết định dựa trên các quyết định của bước trước, và có thể xét lại đường đi của bước trước hướng tới lời giải. Giải thuật tham lam quyết định sớm và thay đổi đường đi thuật toán theo quyết định đó, và không bao giờ xét lại các quyết định cũ. Đối với một số bài toán, đây có thể là một thuật toán không chính xác.

Cấu trúc con tối ưu

Một bài toán được gọi là “có cấu trúc tối ưu”, nếu một lời giải tối ưu của bài toán con chứa lời giải tối ưu của bài toán lớn hơn.

Ta có thể thực hiện cài đặt bằng các thủ tục như sau:

  1. Tính đơn giá của các sản phẩm.

    CodeC
    struct DoVat {
    char Ten [20];
    float TrongLuong, GiaTri, DonGia; int PhuongAn;//so luong do vat chon
    };`
    
  2. Tính đơn giá của các sản phẩm. Độ phức tạp thuật toán là O(n)

    CodeC
    void TinhDonGia(DoVat sp[], int n)
    { for(int i = 1; i <= n; i++) sp[i].DonGia = sp[i].GiaTri / sp[i].TrongLuong;
    }
    
  3. Sắp xếp giảm dần theo đơn giá. Độ phức tạp thuật toán O(n2)

     CodeC void SapXep(DoVat sp[], int n) { for(int i = 1; i <= n - 1; i++) for(int j = i + 1; j <= n; j++) if (sp[i].DonGia < sp[j].DonGia) swap(sp[i], sp[j]); }
    
  4. Xác định sản phẩm cần lấy. Độ phức tạp thuật toán là O(n)

     CodeC void Greedy(DoVat sp[], int n, float W) { for (int i = 0; i < n; i++) { sp[i].PhuongAn = W / sp[i].TrongLuong; W -= sp[i].PhuongAn * sp[i].TrongLuong; } }
    

Vậy nhé ! Chúc các bạn một ngày làm việc hiệu quả.

Bình luận

Bài viết tương tự

- vừa được xem lúc

Giới thiệu Typescript - Sự khác nhau giữa Typescript và Javascript

Typescript là gì. TypeScript là một ngôn ngữ giúp cung cấp quy mô lớn hơn so với JavaScript.

0 0 502

- vừa được xem lúc

Cài đặt WSL / WSL2 trên Windows 10 để code như trên Ubuntu

Sau vài ba năm mình chuyển qua code trên Ubuntu thì thật không thể phủ nhận rằng mình đã yêu em nó. Cá nhân mình sử dụng Ubuntu để code web thì thật là tuyệt vời.

0 0 376

- vừa được xem lúc

Đặt tên commit message sao cho "tình nghĩa anh em chắc chắn bền lâu"????

. Lời mở đầu. .

1 1 701

- vừa được xem lúc

Tìm hiểu về Resource Controller trong Laravel

Giới thiệu. Trong laravel, việc sử dụng các route post, get, group để gọi đến 1 action của Controller đã là quá quen đối với các bạn sử dụng framework này.

0 0 335

- vừa được xem lúc

Phân quyền đơn giản với package Laravel permission

Như các bạn đã biết, phân quyền trong một ứng dụng là một phần không thể thiếu trong việc phát triển phần mềm, dù đó là ứng dụng web hay là mobile. Vậy nên, hôm nay mình sẽ giới thiệu một package có thể giúp các bạn phân quyền nhanh và đơn giản trong một website được viết bằng PHP với framework là L

0 0 421

- vừa được xem lúc

Bạn đã biết các tips này khi làm việc với chuỗi trong JavaScript chưa ?

Hi xin chào các bạn, tiếp tục chuỗi chủ đề về cái thằng JavaScript này, hôm nay mình sẽ giới thiệu cho các bạn một số thủ thuật hay ho khi làm việc với chuỗi trong JavaScript có thể bạn đã hoặc chưa từng dùng. Cụ thể như nào thì hãy cùng mình tìm hiểu trong bài viết này nhé (go).

0 0 414