Quyết định các vấn đề phụ cho lập trình động


39

Tôi đã sử dụng kỹ thuật lập trình động nhiều lần, tuy nhiên hôm nay một người bạn hỏi tôi về cách xác định các vấn đề phụ của mình, tôi nhận ra rằng tôi không có cách nào đưa ra câu trả lời chính thức khách quan. Làm thế nào để bạn chính thức xác định một vấn đề phụ cho một vấn đề mà bạn sẽ giải quyết bằng lập trình động?


Có vẻ như không có câu trả lời nào hiện có (kể từ tháng 4 năm 2019) là đủ tốt, đặc biệt là cho người mới bắt đầu. Tôi muốn giới thiệu hướng dẫn trên các trang web khác.
Apass.Jack

Câu trả lời:


35

Nguyên tắc của lập trình động là suy nghĩ từ trên xuống (tức là đệ quy) nhưng giải quyết từ dưới lên. Vì vậy, một chiến lược tốt để thiết kế DP là xây dựng vấn đề theo cách đệ quy và tạo ra các vấn đề phụ theo cách đó.


14
Tôi khẳng định đó là chiến lược duy nhất .
JeffE

2
@JeffE Vâng, tôi đã đọc và sử dụng các ghi chú của bạn khi dạy các lớp thuật toán của tôi và nó rất hiệu quả. Trích dẫn: "Năng động không phải là về việc điền vào các bảng. Đó là về đệ quy thông minh!"
Đại

2
Sự hiểu biết của tôi về cách dạy DP bị ảnh hưởng mạnh mẽ bởi các ghi chú của @ JeffE :)
Suresh

3
Cũng có thể tự động biến một thủ tục đệ quy từ trên xuống thành một thuật toán lập trình động. Khi bạn sắp trở lại, lưu trữ câu trả lời trong bảng băm. Khi bắt đầu mỗi cuộc gọi, hãy kiểm tra xem câu trả lời đã có trong bảng băm chưa và nếu có, hãy trả lại ngay lập tức. Nhiều thuật toán trở nên dễ dàng với ý tưởng này. Ví dụ với một bảng như vậy, các thuật toán đệ quy trên các lần thử tự động hoạt động trên các DAWG. Bằng cách lưu trữ giá trị sentinel trong bảng khi bắt đầu cuộc gọi, các thuật toán tương tự có thể hoạt động ngay cả trên các DFA. Các thuật toán trên BDD trở nên rất dễ dàng để chỉ định đệ quy.
Jules

1
Cuối cùng nhưng không kém phần quan trọng, điều này có thể có lợi thế hiệu suất rất lớn. Ví dụ, thuật toán tổng hợp tập hợp từ dưới lên truyền thống có thể tính toán hàng tấn các mục trong bảng không cần thiết. Với phương pháp này, chỉ các mục trong bảng cần thiết sẽ được tính toán.
Jules

4

Như @Suresh đã chỉ ra, một khi bạn biết rằng vấn đề của bạn có thể được giải quyết bằng DP (tức là nó thể hiện cấu trúc tối ưu và các bài toán con chồng chéo), bạn có thể nghĩ đến một giải pháp đệ quy và chinh phục.

Tất nhiên, phân chia và chinh phục sẽ rất kém hiệu quả vì mọi bài toán con gặp phải trong cây đệ quy liên quan sẽ được giải quyết lại ngay cả khi nó đã được tìm thấy và giải quyết. Đây là nơi DP khác biệt: mỗi lần bạn gặp một bài toán con, bạn giải quyết nó và lưu trữ giải pháp của nó trong một bảng. Sau này, khi bạn gặp lại bài toán con đó, bạn truy cập vào thời gian giải pháp của nó thay vì giải quyết lại. Vì số lượng các bài toán con chồng chéo thường được giới hạn bởi một đa thức và thời gian cần thiết để giải một bài toán con là đa thức (nếu không DP không thể cung cấp giải pháp hiệu quả chi phí), nói chung bạn đạt được một giải pháp đa thức.O(1)

Do đó, suy nghĩ về một giải pháp phân chia và chinh phục sẽ cung cấp cho bạn cái nhìn sâu sắc về những gì một vấn đề con có thể cho vấn đề cụ thể của bạn.


1
"cấu trúc tối ưu" (bất kể điều đó có nghĩa là gì) có lẽ không phải là điều kiện đủ cho khả năng thanh toán DP. "Các bài toán con chồng chéo" chắc chắn không phải là một điều cần thiết.
Raphael

1
Cấu trúc tối ưu và các siêu biểu tượng chồng chéo đều được thể hiện bằng các vấn đề có thể được giải quyết hiệu quả bởi DP. Tất nhiên cấu trúc tối ưu một mình là không đủ cho khả năng thanh toán DP. Tuy nhiên, nếu bạn không có các bài toán con chồng chéo, thì bạn có thể giải quyết vấn đề bằng cách chia và chinh phục thông thường với cùng một chi phí: thực sự, lợi thế của DP so với chia một chinh phục là mỗi bài toán con được giải quyết chính xác một lần khi gặp trong cây đệ quy .
Massimo Cafaro

1
Đây không phải là công thức của tôi: bạn sẽ tìm thấy nó trong "Giới thiệu về thuật toán" của Cormen, Leiserson, Rivest và Stein và trên nhiều sách giáo khoa khác về thuật toán.
Massimo Cafaro

1
Jup, và hầu hết đều sai một phần. Tôi rất vui để giải thích nếu bạn đăng một câu hỏi phù hợp.
Raphael

1
Tôi không chắc chắn tôi hiểu chính xác bình luận cuối cùng của bạn. Để chỉ ra rằng loại đặc tính này là sai (nó không thể sai một phần: đúng hoặc sai), bạn chỉ có thể hiển thị dưới dạng mẫu, một vấn đề không thể hiện cả cấu trúc con tối ưu và các biểu tượng con chồng chéo, tuy nhiên là tuân theo giải pháp DP đa thức. Nhưng lưu ý rằng, trong bối cảnh này, điều đó có nghĩa là một giải pháp tốt hơn hẳn so với sự phân chia và chinh phục thông thường.
Massimo Cafaro

2

Kinh nghiệm của tôi là tìm ra cách "cắt giảm việc liệt kê dự phòng với sự giúp đỡ của việc lưu trữ giá trị hữu ích đã được liệt kê". Nhân tiện, Lập trình động thực sự phổ biến trong ICPC (Cuộc thi lập trình trường đại học quốc tế. Bất kỳ ai cũng có thể có cảm nhận của riêng mình về DP sau khi thực hành một số vấn đề về ICPC.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.