I can write both Prim's and Kruskal's algorithms to find a minimum spanning tree in C++ or Java, but I want to know how to implement them in Haskell with O(mlogm) or O(mlogn) (pure functional programs is better). Thanks a lot.
相关问题
- Understanding do notation for simple Reader monad:
- Making Custom Instances of PersistBackend
- Haskell: What is the differrence between `Num [a]
- applying a list to an entered function to check fo
- Haskell split a list into two by a pivot value
相关文章
- Is it possible to write pattern-matched functions
- Haskell underscore vs. explicit variable
- Top-level expression evaluation at compile time
- Stuck in the State Monad
- foldr vs foldr1 usage in Haskell
- List of checkboxes with digestive-functors
- How does this list comprehension over the inits of
- Replacing => in place of -> in function type signa
Here is a crude Kruskal implementation.
The first step is sorting the edges, which is O(n log n). The problem is to find a faster lookup for the vertex sets in the extract function. I couldn't find a faster solution for this, maybe someone has an idea...
[Update]
For a Scala implementation I used a map-like data-structure for (hopefully) better performance, but unfortunately it uses mutable sets, and I have no clue how to translate this into Haskell. The code is in my blog (sorry, description is in German): http://dgronau.wordpress.com/2010/11/28/nochmal-kruskal/
As svenningsson suggests, priority search queue is well suited for both Kruskal's and Prim's (atleast the author proclaims it in his paper.) The problem with Kruskal is that it requires that you have an O(log n) union-find algorithm. A union-find datastructure with a purely functional interface is described here, but it uses mutable state internally, and a purely functional implementation might be impossible and in fact, there are several problems where an efficient purely functional solution is not known, as discussed in this related SO question.
A non-pure alterenative is to implement union-find algorithm in the ST monad. A search on Hackage finds that the equivalence package suits our needs. Following is an implementation of Kruskal using Data.Equivalence.Monad from the equivalence package:
It can be used like this:
and running test gives:
It should be noted that the running time is dependent on weights running in O(1) time, however
fromL
creates a weight function running in O(log(n)) time, this can be improved to O(1) time by using arrays or just keeping track of the weight in the input list, but it's not really part of the algorithm.I think a priority search queue is what you're looking for. It can be implemented optimally in a functional language as demonstrated by Ralf Hinze in a paper. It seems like the paper is only available via acm's library at a cost.