我有一个优先级队列,它包含多个任务,每个任务都有一个数字非唯一优先级,如下所示:
import scala.collection.mutable
class Task(val name: String, val priority: Int) {
override def toString = s"Task(name=$name, priority=$priority)"
}
val task_a = new Task("a", 5)
val task_b = new Task("b", 1)
val task_c = new Task("c", 5)
val pq: mutable.PriorityQueue[Task] =
new mutable.PriorityQueue()(Ordering.by(_.priority))
pq.enqueue(task_a)
pq.enqueue(task_b)
pq.enqueue(task_c)
我想接下来的任务:
pq.dequeue()
但是这样,即使还有任务c 具有相同的优先级,我总会回来任务a 。
答案 0 :(得分:1)
这应该是一个很好的起点:
abstract class ProbPriorityQueue[V] {
protected type K
protected implicit def ord: Ordering[K]
protected val impl: SortedMap[K, Set[V]]
protected val priority: V => K
def isEmpty: Boolean = impl.isEmpty
def dequeue: Option[(V, ProbPriorityQueue[V])] = {
if (isEmpty) {
None
} else {
// I wish Scala allowed us to collapse these operations...
val k = impl.lastKey
val s = impl(k)
val v = s.head
val s2 = s - v
val impl2 = if (s2.isEmpty)
impl - k
else
impl.updated(k, s2)
Some((v, ProbPriorityQueue.create(impl2, priority)))
}
}
}
object ProbPriorityQueue {
def apply[K: Ordering, V](vs: V*)(priority: V => K): ProbPriorityQueue = {
val impl = vs.foldLeft(SortedMap[K, Set[V]]()) {
case (acc, v) =>
val k = priority(v)
acc get k map { s => acc.updated(k, s + v) } getOrElse (acc + (k -> Set(v)))
}
create(impl, priority)
}
private def create[K0:, V](impl0: SortedMap[K0, Set[V]], priority0: V => K0)(implicit ord0: Ordering[K0]): ProbPriorityQueue[V] =
new ProbPriorityQueue[V] {
type K = K0
def ord = ord0
val impl = impl0
val priority = priority0
}
}
我没有实现select
函数,它会产生加权概率值,但这不应该太难。为了实现该功能,您需要一个额外的映射函数(类似于priority
),其类型为K => Double
,其中Double
是附加到特定密钥桶的概率权重。这使得一切都变得更加混乱,因此似乎不值得为此烦恼。
此外,这似乎是一组非常具体的要求。你要么对分布式调度或家庭作业感兴趣。