问题
I am programming several search functions, for which I use the Node
datatype:
data Node a =
Node { [...]
, getPath :: [a] -- ^ Previous states this node has visited
}
That field, getPath
, is what I use to check if I have previously visited that state in that node: when expanding a new node, I check that by doing:
visited = `elem` path
It works, but it becomes incredibly costly when there are a lot of nodes expanded and the paths become too long. Is there a better way to keep track of the states I have visited? Maybe a different data structure (instead of a list) that performs better for this use?
回答1:
The answer depends on what constraints your elements have (or can be given).
If your elements have an Ord
constraint then you can use Data.Set from containers to get O(log n)
membership tests.
If your elements have a Hashable
constraint then you can use a HashSet from unordered-containers to get O(log n)
membership tests with better constant factors* and a large enough base that they are effectively constant time for most use cases.
If your elements only have an Eq
constraint then you can't do better than a list.
* Depending on the performance of the Hashable
instance. When in doubt, benchmark.
来源:https://stackoverflow.com/questions/44636042/keep-record-of-previously-visited-states-when-searching