Ghi nhớ không có mảng


14

Trong phần Giới thiệu về thuật toán của Cormen và cộng sự , phần 15.3 Các yếu tố của lập trình động giải thích việc ghi nhớ như sau:

Một thuật toán đệ quy ghi nhớ duy trì một mục trong bảng cho giải pháp cho từng bài toán con. Mỗi mục nhập ban đầu chứa một giá trị đặc biệt để chỉ ra rằng mục nhập vẫn chưa được điền vào. Khi gặp vấn đề phụ lần đầu tiên khi thuật toán đệ quy mở ra, giải pháp của nó được tính toán và sau đó được lưu trữ trong bảng. Mỗi lần tiếp theo chúng ta gặp phải bài toán con này, chúng ta chỉ cần tra cứu giá trị được lưu trong bảng và trả về nó.

Và nó bổ sung, như một chú thích:

Cách tiếp cận này giả định rằng chúng ta biết tập hợp tất cả các tham số của bài toán con có thể và chúng ta đã thiết lập mối quan hệ giữa các vị trí bảng và các bài toán con. Một cách tiếp cận khác, tổng quát hơn, là ghi nhớ bằng cách sử dụng băm với các tham số của biểu đồ con làm khóa.

Có bất kỳ vấn đề DP nào được biết rõ đòi hỏi (hoặc làm cho nó dễ dàng hơn) để lưu trữ các giá trị ghi nhớ trong từ điển hơn là trong một mảng (đa chiều) không?


Bối cảnh: nếu điều này được sử dụng, lý do cho câu hỏi này là tôi đang cố gắng thúc đẩy khái niệm cây tìm kiếm nhị phân (tự cân bằng) cho những người vừa xem chương trình động.


Trong phần mềm thực tế mà tôi làm việc cùng, việc ghi nhớ có thể sử dụng thực tế là một hàm tương đối đắt tiền (như exp , log hoặc pow ) có thể được gọi từ nhiều nơi khác nhau trong mã và thường được gọi nhiều lần theo thứ tự cùng một giá trị từ mỗi vị trí mã cụ thể. Trong trường hợp đó, "từ điển" có thể là một giá trị được lưu trữ trong một biến cụ thể theo vị trí mã.
Mike Dunlavey

Câu trả lời:


5

Có thể có những ví dụ tốt hơn, nhưng đây là một ví dụ, ngoài đỉnh đầu của tôi:

S,Td>d


3

Tôi muốn cung cấp 2 ví dụ.

0-1 Vấn đề về chiếc ba lô

Trong trường hợp của Knapsack vấn đề 0-1 (trong đó W là công suất của ba lô và N là một khoản mục), đôi khi nó là tốt hơn để sử dụng từ trên xuống động Lập trình với memoization, thay vì liệt kê từ dưới lên có hệ thống của toàn bộ mảng 2D có kích thước WxN (đặc biệt là trong trường hợp công suất của chiếc ba lô W lớn, nhưng tính chính xác của tập hợp các tổ hợp trọng lượng cho phép của các vật phẩm nhỏ hơn nhiều so với W ).

Trong trường hợp này, vì lợi ích kinh tế của bộ nhớ, người ta có thể chọn sử dụng từ điển để ghi nhớ thay vì mảng 2D.

Thuật toán phân tích Earley

Thuật toán phân tích Earley có thể được sử dụng để phân tích cú pháp các câu lệnh, thuộc về ngữ pháp không ngữ cảnh. Trái ngược với thuật toán CYK (dựa trên cách tiếp cận DP từ dưới lên và sử dụng bảng 2D để ghi nhớ) - Trình phân tích Earley sử dụng phương pháp từ trên xuống kết hợp với biểu đồ phân tích cú pháp để ghi nhớ.

Biểu đồ phân tích cú pháp chứa các sản phẩm ngữ pháp được phân tích cú pháp một phần (ví dụ: được sản xuất X → AB và sau khi kết hợp thành công phần A của sản phẩm này, chúng tôi lưu trữ sản phẩm khớp một phần bên trong biểu đồ phân tích cú pháp: X → A • B , trong đó các điểm chấm đến phần đã khớp).

Số lượng cột bên trong biểu đồ phân tích bằng số lượng mã thông báo. Tuy nhiên, trong trường hợp chung có thể rất khó, để ước tính số lượng sản phẩm ngữ pháp được phân tích cú pháp một phần trên mỗi cột (nó phụ thuộc vào ngữ pháp và trình tự mã thông báo cụ thể).

Do đó, sẽ thuận tiện hơn khi thực hiện biểu đồ phân tích cú pháp dựa trên cấu trúc dữ liệu từ điển.

Trong miền Xử lý ngôn ngữ tự nhiên, thông thường Earley pareser là lựa chọn thuận tiện hơn, vì nó không yêu cầu dạng bình thường Chomsky cho ngữ pháp (và CYK có yêu cầu như vậy).


0

Theo kinh nghiệm của tôi từ lập trình cạnh tranh, sử dụng bảng băm (Python dicthoặc tương tự) thường thuận tiện hơn so với sử dụng một mảng, bởi vì bất kỳ loại dữ liệu có thể băm nào cũng có thể được sử dụng làm khóa, chẳng hạn như chuỗi, bộ ( frozensettrong Python) hoặc tuples như (string, int)v.v. Nếu sử dụng một mảng, bạn phải dịch thủ công tất cả các khóa thành số nguyên (bắt đầu từ 0), việc này cần thêm công việc và, như ghi chú nguồn của bạn, có thể không thực hiện được nếu bạn không biết trước khoảng trống của khóa. Vì vậy, từ điển là khá chung chung hơn mảng.

Tất nhiên, nếu bạn có thể thoát khỏi việc sử dụng mảng thì có thể nhanh hơn vì nó tránh được việc băm liên tục tính toán (mặt khác, nó yêu cầu khởi tạo toàn bộ mảng trước, mất thời gian và bộ nhớ), nhưng có thể mất nhiều thời gian hơn để viết mã bởi vì bạn phải làm thêm công việc dịch tất cả các khóa thành số nguyên.

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.