biểu cảm của Haskell cho phép chúng tôi thay vì dễ dàng xác định một hàm Powerset:Tạo trực tiếp các tập con cụ thể của một đại lý?
import Control.Monad (filterM)
powerset :: [a] -> [[a]]
powerset = filterM (const [True, False])
Để có thể thực hiện nhiệm vụ của tôi nó là rất quan trọng cho biết Powerset được sắp xếp theo một chức năng cụ thể, vì vậy thực hiện của tôi loại trông như thế này :
import Data.List (sortBy)
import Data.Ord (comparing)
powersetBy :: Ord b => ([a] -> b) -> [a] -> [[a]]
powersetBy f = sortBy (comparing f) . powerset
Bây giờ câu hỏi của tôi là liệu có một cách để chỉ tạo ra một tập hợp con của Powerset cho một cụ thể start
và end
điểm, nơi f(start) < f(end)
và |start| < |end|
. Ví dụ, tham số của tôi là một danh sách các số nguyên ([1,2,3,4,5]
) và chúng được sắp xếp theo tổng của chúng. Bây giờ tôi chỉ muốn trích xuất các tập hợp con trong một phạm vi nhất định, giả sử 3
đến 7
. Một cách để đạt được điều này sẽ được filter
các Powerset để chỉ bao gồm phạm vi của tôi, nhưng điều này dường như (và là) không hiệu quả khi đối phó với các tập con lớn hơn:
badFunction :: Ord b => b -> b -> ([a] -> b) -> [a] -> [[a]]
badFunction start end f = filter (\x -> f x >= start && f x <= end) . powersetBy f
badFunction 3 7 sum [1,2,3,4,5]
sản xuất [[1,2],[3],[1,3],[4],[1,4],[2,3],[5],[1,2,3],[1,5],[2,4],[1,2,4],[2,5],[3,4]]
.
Bây giờ câu hỏi của tôi là có cách tạo danh sách này trực tiếp, mà không phải tạo tất cả các tập hợp con 2^n
trước vì nó sẽ cải thiện hiệu suất mạnh mẽ bằng cách không phải kiểm tra tất cả các yếu tố mà là tạo chúng "nhanh" .
Đối với một chức năng đặt hàng tùy ý, bạn không thể thực sự làm tốt hơn. Hãy tìm cấu trúc trong hàm đặt hàng của bạn mà bạn có thể khai thác. – luqui
Chức năng đặt hàng là gì hoặc thuộc tính của nó là gì? Nếu không có một số kiến thức về hàm, bạn không thể làm tốt hơn - hãy xem xét ví dụ hàm này là [hàm băm mật mã funciton] (http://en.wikipedia.org/wiki/Cryptographic_hash_function). –