Wouldn't an immutable PriorityQueue be an oxymoron under most
circumstances?
The whole point of a priority heap, after all, is
adding elements and then removing them in a defined order.
On Thu, Jul 21, 2011 at 2:12 PM, Matthew Pocock
<turingate...@gmail.com> wrote:
> Are there any plans to add immutable.PriorityQueue to the scala collections
> library?
We actually almost have an immutable priority queue with SortedSet:
import scala.collection.SortedSet
case class Item(name: String, importance: Int)
var pq = SortedSet.empty[A](Ordering by ((_: Item).importance))
pq += Item("Item 1", 5)
pq += Item("Item 2", 1)
pq += Item("Item 3", 7)
pq += Item("Item 4", 3)
println(pq.last) // prints: Item("Item 3"), 7)
pq = pq.init
println(pq.last) // prints: Item("Item 1"), 5)
pq = pq.init
There are of course issues with using this though since it is a set,
but it does show that it can work.
--
Derek Williams
Of course that 'A' should be 'Item'
--
Derek Williams
The whole point of a priority heap, after all, is
adding elements and then removing them in a defined order.Yes. I don't see why this implies mutability. The enqueue and dequeue operations would simply return new priority queues.
On 22/07/11 04:52, Donald McLean wrote:
> Wouldn't an immutable PriorityQueue be an oxymoron under most
> circumstances? The whole point of a priority heap, after all, is
> adding elements and then removing them in a defined order.
No, I can think of many possible implementations of a pure functional
priority queue. So can Chris Okasaki for that matter -- I recommend
him. Reader's exercise!
- --
Tony Morris
http://tmorris.net/
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
iEYEARECAAYFAk4olJkACgkQmnpgrYe6r63IDgCdEUIwhSHQ9UO2s0cZFh0nVeQg
R28AoJhxYVKxz2rt4t1GeLQGF6KNfa3q
=iLdh
-----END PGP SIGNATURE-----
Hi,I'm starting yet another project, and yet again it needs an immutable priority queue. Pretty please, can someone chalk this up as a class that needs adding to scala.collections.immutable?
On Thu, Sep 15, 2011 at 2:22 PM, Matthew Pocock <turingate...@gmail.com> wrote:
Hi,I'm starting yet another project, and yet again it needs an immutable priority queue. Pretty please, can someone chalk this up as a class that needs adding to scala.collections.immutable?
I need a high-performance, threadsafe, mutable non-blocking bi-map.
√
--Rex
2011/11/28 Rex Kerr <ich...@gmail.com>Primitive or generic? Block-on-write, nonblocking-on-read?2011/9/15 √iktor Ҡlang <viktor...@gmail.com>On Thu, Sep 15, 2011 at 2:22 PM, Matthew Pocock <turingate...@gmail.com> wrote:
Hi,I'm starting yet another project, and yet again it needs an immutable priority queue. Pretty please, can someone chalk this up as a class that needs adding to scala.collections.immutable?
I need a high-performance, threadsafe, mutable non-blocking bi-map.
√
Generic. Do you mean RW-lock semantics or do you means that writers block writers but readers never block?
2011/11/28 √iktor Ҡlang <viktor...@gmail.com>2011/11/28 Rex Kerr <ich...@gmail.com>Primitive or generic? Block-on-write, nonblocking-on-read?2011/9/15 √iktor Ҡlang <viktor...@gmail.com>On Thu, Sep 15, 2011 at 2:22 PM, Matthew Pocock <turingate...@gmail.com> wrote:
Hi,I'm starting yet another project, and yet again it needs an immutable priority queue. Pretty please, can someone chalk this up as a class that needs adding to scala.collections.immutable?
I need a high-performance, threadsafe, mutable non-blocking bi-map.
√
Generic. Do you mean RW-lock semantics or do you means that writers block writers but readers never block?
Well, I'm almost positive that what I have is so far away that it would be faster to start from scratch; it's primitive only (actually, small integers or mappable-to-small-integers only since it doesn't handle collisions); writers block writers (some of the time) and readers never block, but readers have no guarantee of the bidirectionality of the map: it is possible for them to see that a->b has appeared in the map but b->a has not (yet).
I think you need a tree-based rather than an array-based implementation to get apparently atomic bidirectionality without locking everyone on write.
--Rex
2011/11/28 Rex Kerr <ich...@gmail.com>2011/11/28 √iktor Ҡlang <viktor...@gmail.com>2011/11/28 Rex Kerr <ich...@gmail.com>Primitive or generic? Block-on-write, nonblocking-on-read?2011/9/15 √iktor Ҡlang <viktor...@gmail.com>On Thu, Sep 15, 2011 at 2:22 PM, Matthew Pocock <turingate...@gmail.com> wrote:
Hi,I'm starting yet another project, and yet again it needs an immutable priority queue. Pretty please, can someone chalk this up as a class that needs adding to scala.collections.immutable?
I need a high-performance, threadsafe, mutable non-blocking bi-map.
√
Generic. Do you mean RW-lock semantics or do you means that writers block writers but readers never block?
Well, I'm almost positive that what I have is so far away that it would be faster to start from scratch; it's primitive only (actually, small integers or mappable-to-small-integers only since it doesn't handle collisions); writers block writers (some of the time) and readers never block, but readers have no guarantee of the bidirectionality of the map: it is possible for them to see that a->b has appeared in the map but b->a has not (yet).
So you're keeping 2 mappings per entry?
I think you need a tree-based rather than an array-based implementation to get apparently atomic bidirectionality without locking everyone on write.
Yeah, I just have -3467264789234 time to do any researchy stuff right now.
The header comment describes it as follows:
/** An efficient, asymptotically optimal, implementation of priority
queues
* extended with support for efficient size.
*
* The implementation of 'Heap' is based on bootstrapped skew
binomial heaps
* as described by:
* G. Brodal and C. Okasaki , "Optimal Purely Functional Priority
Queues",
* Journal of Functional Programming 6:839-857 (1996),
*
* Based on the heaps Haskell library by Edward Kmett
*
*/
I saw someone else mentioned Scalaz's finger trees, but not this
PriorityQueue directly, which is not based on finger trees.
On Nov 28, 10:29 am, Matthew Pocock <turingatemyhams...@gmail.com>
wrote:
> Yeah, my implementation probably isn't so efficient. That's not really the
> point. It's just one of the reasons I'd prefer a priority queue to be in
> the standard lib. Others include having it fit into the collections
> framework and not having to maintain it myself, and that it is obviously
> missing.
>
> I did initially try to implement it over SortedSet, but that didn't work so
> well as I need to be able to enqueue the same item multiple times with
> independent priorities, and ensure that it it is only ever in the queue at
> most once, under the highest priority.
>
> Matthew
>
> >> mailto: turingatemyhams...@gmail.com
> >> gchat: turingatemyhams...@gmail.com
> >> msn: matthew_poc...@yahoo.co.uk
> >> irc.freenode.net: drdozer
> >> skype: matthew.pocock
> >> tel: (0191) 2566550
> >> mob: +447535664143
>
> --
> Dr Matthew Pocock
> Integrative Bioinformatics Group, School of Computing Science, Newcastle
> University
> mailto: turingatemyhams...@gmail.com
> gchat: turingatemyhams...@gmail.com
> msn: matthew_poc...@yahoo.co.uk
val x = "hallo"
var m = Map( 0 -> x )
m += 1 -> x
m // Map(0 -> hallo, 1 -> hallo)
why don't you just remove the item before re-inserting it with other priority?
best, -sciss-
but how would you expect a data-structure to find your item when you push it repeatedly with different priorities? that's like complaining that you get multiple entries in a map if you put a value under several keys
val x = "hallo"
var m = Map( 0 -> x )
m += 1 -> x
m // Map(0 -> hallo, 1 -> hallo)
why don't you just remove the item before re-inserting it with other priority?
import collection.immutable.SortedMap
type Prio[ A, B ] = (SortedMap[ A, B ], Map[ B, A ])
object Prio {
def empty[ A : Ordering, B ] : Prio[ A, B ] = (SortedMap.empty, Map.empty)
}
implicit def prioOps[ A, B ]( tup: Prio[ A, B ]) = new PrioOps( tup )
final class PrioOps[ A, B ]( peer: Prio[ A, B ]) {
type Pr = Prio[ A, B ]
def +( entry: (A, B) ) : Pr = {
(peer._2.get( entry._2 ).map( peer._1 - _ ).getOrElse( peer._1 ) + entry,
peer._2 + entry.swap)
}
def pop : (B, Pr) = {
val (k, v) = peer._1.last
(v, (peer._1 - k, peer._2 - v))
}
}
// test
var prio = Prio.empty[ Int, String ]
prio += 1 -> "hallo"
prio += 2 -> "welt"
prio += 3 -> "hallo"
val (max, prio1) = prio.pop
of course, if you require that several items can have the same priority, you would need to massage this a bit, like use SortedMap[ A, Set[ B]] instead.
best, -sciss-
If you look at the definition of a method in the scalaz Heap that
deletes all duplicate values, you'll notice that it expects equal
objects to be right next to each other in the heap, or, in other
words, to have the same priority.
def nub: Heap[A] = fold(Empty[A], (_, leq, t) => {
val x = t.rootLabel.value
val xs = deleteMin
val zs = xs.dropWhile(leq(_, x))
zs.nub.insertWith(leq, x)
})
Another thing to note about priority queues is that the they are
usually designed to be efficient at insertion and at removal of the
top value (top based on priority). On the other hand, they usually
don't support efficient removal of arbitrary elements, which would
make them infeasible to meet your need of deleting duplicate objects
with differing priorities on insertion.
It sounds like you need another data structure!
On Nov 29, 6:54 am, Matthew Pocock <turingatemyhams...@gmail.com>
wrote:
> Also, the scalaz heap doesn't do what I need. If you enque the same item
> multiple times under multiple priorities, it seems to be present in the
> queue at each of these priorities, not just the highest priority. This is
> fatal to my use-case.
>
> Matthew
>
> On 29 November 2011 12:50, Matthew Pocock <turingatemyhams...@gmail.com>wrote:
>
>
>
>
>
>
>
>
>
> > Hi,
>
> > I've had a try at using this heap implementation, but it has been
> > hard-going - I couldn't find any examples using Google, and there where no
> > use examples in the scaladoc. I'm confused by .insert taking an Order -
> > surely the same ordering must be used throughout the lifetime of the heap,
> > or very bad things will happen? Would it not make more sense for the Order
> > instance to be intimately associated with the heap?
>
> > Is there anything out there that shows real-world or tutorial examples?
>
> > Matthew
>
> > On 29 November 2011 05:20, sreque <seanre...@yahoo.com> wrote:
>
> >> What about the immutable priority queue implemented as part of scalaz?
>
> >>http://scalaz.github.com/scalaz/scalaz-2.9.1-6.0.2/doc.sxr/scalaz/Hea...