I wondered what have I done wrong on the SimPy code? When I changed interarrivalTime_DR > 1.5, the code was hanged. If I changed interarrivalTime_DR < 1.5, it worked fine. Please help yourself to use the code. I was not able to find where is the problem caused the issue.
Can anyone assist?
import simpy
import numpy as np
import random
import math
class P:
externalToDRMean = 1/2
DRorderLotSize = 10
externalToBUMean = 5/60
BUorderLotSize = 20
BU_Q = 100
DR_Q = 20
ROP_BU = 20+(200/30)*7
ROP_DR = 10+(150/30)*`
BU_LT = 7
DR_LT = 2
simulationTimeMax = 1 * 30
class S:
Inv = None
DRwaits = []
BUwaits = []
nBUCustomers = 0
nDRCustomers = 0
BU_Dem_day = list(np.repeat(0, P.simulationTimeMax))
DR_Dem_day = list(np.repeat(0, P.simulationTimeMax))
class Inventory:
def __init__(self, env):
self.env = env
self.SP_inv = simpy.Container(env, init = 10000)
self.BU_inv = simpy.Container(env, init = P.ROP_BU)
self.DR_inv = simpy.Container(env, init = P.ROP_DR)
self.mon_procBU = env.process(self.monitor_BU_inv(env))
self.mon_procDR = env.process(self.monitor_DR_inv(env))
def monitor_BU_inv(self, env):
while True:
#print(f"BU_Inv level:{self.BU_inv.level}")
if self.BU_inv.level <= P.ROP_BU:
print("Time {0}: BU inventory reached ROP: BU places replenishment order to Supply".format(self.env.now))
yield self.SP_inv.get(P.BU_Q)
print("Time {0}: Supply fills BU replenishment request".format(self.env.now))
yield self.env.timeout(P.BU_LT)
print("Time {0}: BU replenishment inventory arrives".format(self.env.now))
yield self.BU_inv.put(P.BU_Q)
print("Time {0}: BU replenishment order is added to inventory".format(self.env.now))
yield self.env.timeout(1)
def monitor_DR_inv(self, env):
while True:
if self.DR_inv.level <= P.ROP_DR:
print("Time {0}: DR inventory reached ROP: DR places replenishment order to BU".format(self.env.now))
yield self.BU_inv.get(P.DR_Q)
print("Time {0}: BU fills DR replenishment request".format(self.env.now))
yield self.env.timeout(P.DR_LT)
print("Time {0}: DR replenishment inventory arrives from BU".format(self.env.now))
yield self.DR_inv.put(P.DR_Q)
print("Time {0}: DR replenishment order is added to inventory".format(self.env.now))
yield self.env.timeout(1)
class DRCustomer(object):
def __init__(self, env, name = ''):
self.env = env
self.action = self.env.process(self.ordertoDR())
if (name==''):
self.name = 'RandomDRCustomer' + str(random.randint(100))
else:
self.name = name
def DRorderToBU(self):
print("Time {1}: DR places order to BU to fill order for {0}".format(self.name, self.env.now))
yield S.Inv.BU_inv.get(P.DRorderLotSize)
yield self.env.timeout(P.DR_LT)
yield S.Inv.DR_inv.put(P.DRorderLotSize)
def ordertoDR(self):
startTime_DR = self.env.now
j = math.floor(self.env.now)
S.DR_Dem_day[j] += 1
print("Time {1}: {0} places order to DR".format(self.name, self.env.now))
if S.Inv.DR_inv.level < P.DRorderLotSize:
self.env.process( self.DRorderToBU() )
yield S.Inv.DR_inv.get(P.DRorderLotSize)
print("Time {1}: {0} receives order from DR".format(self.name, self.env.now ))
waitTime_DR = self.env.now - startTime_DR
print("{0} had to wait {1} days".format(self.name, waitTime_DR))
S.DRwaits.append( waitTime_DR )
class BUCustomer(object):
def __init__(self, env, name = ''):
self.env = env
self.action = self.env.process( self.ordertoBU() )
if (name == ''):
self.name = 'RandomBUCustomer' + str(random.randint(100))
else:
self.name = name
def BUorderToSupply(self):
print("Time {1}: BU places order to Supplier to fill order for {0}".format(self.name, self.env.now))
yield S.Inv.SP_inv.get(P.BUorderLotSize)
yield self.env.timeout(P.BU_LT)
yield S.Inv.BU_inv.put(P.BUorderLotSize)
def ordertoBU(self):
startTime_BU = self.env.now
i = math.floor(self.env.now)
S.BU_Dem_day[i] += 1
print("Time {1}: {0} places order to BU".format(self.name, self.env.now))
print(f"****** {S.Inv.BU_inv.level} ---- {P.BUorderLotSize}")
if S.Inv.BU_inv.level < P.BUorderLotSize:
self.env.process( self.BUorderToSupply() )
yield S.Inv.BU_inv.get(P.BUorderLotSize)
print("Time {1}: {0} receives order".format(self.name, self.env.now))
waitTime_BU = self.env.now - startTime_BU
print("{0} had to wait {1} days".format(self.name, waitTime_BU ))
S.BUwaits.append( waitTime_BU )
class DROrderProcessor(object):
def __init__(self, env, DRlambda):
self.env = env
self.action = env.process(self.DREntrance())
self.lam = DRlambda
def DREntrance(self):
while True:
interarrivalTime_DR = 1.6#np.random.exponential(1/P.externalToDRMean)
print(f"interarrivalTime_DR: {interarrivalTime_DR}")
print()
yield self.env.timeout( interarrivalTime_DR )
c = DRCustomer(self.env, name = "DRCustomer {0}".format(S.nDRCustomers))
S.nDRCustomers += 1
class BUOrderProcessor(object):
def __init__(self, env, BUlambda):
self.env = env
self.action = env.process(self.BUEntrance())
self.lam = BUlambda
def BUEntrance(self):
while True:
interarrivalTime_BU = 1#np.random.exponential(1/P.externalToBUMean)
yield self.env.timeout( interarrivalTime_BU )
c = BUCustomer(self.env, name = "BUCustomer {0}".format(S.nBUCustomers))
S.nBUCustomers += 1
randomSeed=123
random.seed(randomSeed)
S.DRwaits = []
S.BUwaits = []
envr = simpy.Environment()
BU = BUOrderProcessor(envr, BUlambda = P.externalToBUMean)
DR = DROrderProcessor(envr, DRlambda = P.externalToDRMean)
S.Inv = Inventory(envr)
envr.run(until = P.simulationTimeMax)
The indentation of the last line in the functions def monitor_BU_inv(self, env) and def monitor_DR_inv(self, env) is not correct. The line yield self.env.timeout(1) should not be inside the if-statement to avoid the endless loop when the if-statement evaluates to false.
def monitor_BU_inv(self, env):
while True:
if self.BU_inv.level <= P.ROP_BU:
print("Time {0}: BU inv...".format(self.env.now))
yield self.SP_inv.get(P.BU_Q)
print("Time {0}: Supply fills BU ...".format(self.env.now))
yield self.env.timeout(P.BU_LT)
print("Time {0}: BU replenishment...".format(self.env.now))
yield self.BU_inv.put(P.BU_Q)
print("Time {0}: BU replenishment ...".format(self.env.now))
yield self.env.timeout(1)
Related
I have 3 scala functions, working well, I have an errors just in the function
I did another function equals: compute the number of hours between 2 dates by calling the 3 functions above: toEnd, ToStart, jourOuvree.
I wrote all the function in a scala Object. But when I run the function equals, it gives me an errors, this following:
^
I should use the function and apply it on my dataframe to compute the number of hours between 2 dates.
I'm not excellent in java.time API.
Someone can help me please to resolve these errors ?
I rewrote your solution. See comments inline.
import java.time._
import java.time.temporal.ChronoUnit
import scala.annotation.tailrec
import scala.concurrent.duration._
object Demo extends App {
val start = LocalTime.of(9, 0)
val midEnd = LocalTime.of(13, 0)
val midStart = LocalTime.of(14, 0)
val end = LocalTime.of(18, 0)
val firstHalf = start.until(midEnd, ChronoUnit.MILLIS).millis
val secondHalf = midStart.until(end, ChronoUnit.MILLIS).millis
implicit class formatter(d: FiniteDuration) {
def withMinutes = {
val l = d.toMinutes
s"${l / 60}:${l % 60}"
}
def withSeconds = s"${d.toHours}:${d.toMinutes % 60}:${d.toSeconds % 60}"
}
// check if day is working. Could be easily adjusted to check not only weekend but holidays as well
def isWorkingDay(d: LocalDate) = !Set(DayOfWeek.SATURDAY, DayOfWeek.SUNDAY).contains(d.getDayOfWeek)
// check if current day is working day and if not switch to next start of day/previous end of day
// depending on ask parameter
#tailrec
def adjust(t: LocalDateTime, asc: Boolean = true): LocalDateTime = {
if (!isWorkingDay(t.toLocalDate) && asc) adjust(t.toLocalDate.plusDays(1).atTime(start), asc)
else if (!isWorkingDay(t.toLocalDate) && !asc) adjust(t.toLocalDate.minusDays(1).atTime(end), asc)
else t
}
def toEnd(t: LocalTime) = {
if (t.isBefore(start)) firstHalf + secondHalf
else if (t.isBefore(midEnd)) t.until(midEnd, ChronoUnit.MILLIS).millis + secondHalf
else if (t.isBefore(midStart)) secondHalf
else if (t.isBefore(end)) t.until(end, ChronoUnit.MILLIS).millis
else 0.hours
}
def toStart(t: LocalTime) = {
if (t.isBefore(start)) 0.hours
else if (t.isBefore(midEnd)) start.until(t, ChronoUnit.MILLIS).millis
else if (t.isBefore(midStart)) firstHalf
else if (t.isBefore(end)) firstHalf + midStart.until(t, ChronoUnit.MILLIS).millis
else firstHalf + secondHalf
}
// count amount of working days between two dates.
// if dates are the same - means 0 days
def jourOuvree(d1: LocalDate, d2: LocalDate): Int = {
#tailrec
def count(n: LocalDate, acc: Int): Int = {
if (n.isEqual(d2) || n.isAfter(d2)) acc
else if (!isWorkingDay(n)) count(n.plusDays(1), acc)
else count(n.plusDays(1), acc + 1)
}
count(d1, 0)
}
// evaluate duration of working time between to date/times
// take into account that start/end could be non-working and
// adjust
def toEquals(rd1: LocalDateTime, rd2: LocalDateTime) = {
val d1 = adjust(rd1)
val d2 = adjust(rd2, asc = false)
// if we are in the same day ==> I should compute just a difference between hours
if (d1.isAfter(d2)) 0.hours
else if (d1.toLocalDate.isEqual(d2.toLocalDate)) {
toEnd(d1.toLocalTime) - toEnd(d2.toLocalTime)
}
else {
toEnd(d1.toLocalTime) + jourOuvree(d1.toLocalDate.plusDays(1), d2.toLocalDate.minusDays(1)) * 8.hours + toStart(d2.toLocalTime)
}
}
val thursdayStart = LocalDate.of(2018, 3, 1).atTime(start)
val thursdayEnd = LocalDate.of(2018, 3, 1).atTime(end)
val fridayStart = LocalDate.of(2018, 3, 2).atTime(start)
val fridayEnd = LocalDate.of(2018, 3, 2).atTime(end)
val saturdayStart = LocalDate.of(2018, 3, 3).atTime(start)
val saturdayEnd = LocalDate.of(2018, 3, 3).atTime(end)
val sundayStart = LocalDate.of(2018, 3, 4).atTime(start)
val sundayEnd = LocalDate.of(2018, 3, 4).atTime(end)
val mondayStart = LocalDate.of(2018, 3, 5).atTime(start)
val mondayEnd = LocalDate.of(2018, 3, 6).atTime(end)
println(toEquals(thursdayStart, sundayStart).withSeconds)
println(toEquals(thursdayStart, saturdayStart).withSeconds)
println(toEquals(thursdayStart, mondayStart).withSeconds)
println(toEquals(thursdayStart, mondayEnd).withSeconds)
println(toEquals(thursdayStart, thursdayEnd).withSeconds)
// formatter to use to parse string input
import java.time.format.DateTimeFormatter
val DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
println(toEquals(LocalDateTime.parse("2018-03-01 11:22:33", DATE_TIME_FORMATTER), LocalDateTime.parse("2018-03-02 11:22:33", DATE_TIME_FORMATTER)).withSeconds)
}
I am trying to implement Haar Wavelet Transform in Scala. I am using this Python Code for reference Github Link to Python implementation of HWT
I am also giving here my Scala code version. I am new to Scala so forgive me for not-so-good-code.
/**
* Created by vipul vaibhaw on 1/11/2017.
*/
import scala.collection.mutable.{ListBuffer, MutableList,ArrayBuffer}
object HaarWavelet {
def main(args: Array[String]): Unit = {
var samples = ListBuffer(
ListBuffer(1,4),
ListBuffer(6,1),
ListBuffer(0,2,4,6,7,7,7,7),
ListBuffer(1,2,3,4),
ListBuffer(7,5,1,6,3,0,2,4),
ListBuffer(3,2,3,7,5,5,1,1,0,2,5,1,2,0,1,2,0,2,1,0,0,2,1,2,0,2,1,0,0,2,1,2)
)
for (i <- 0 to samples.length){
var ubound = samples(i).max+1
var length = samples(i).length
var deltas1 = encode(samples(i), ubound)
var deltas = deltas1._1
var avg = deltas1._2
println( "Input: %s, boundary = %s, length = %s" format(samples(i), ubound, length))
println( "Haar output:%s, average = %s" format(deltas, avg))
println("Decoded: %s" format(decode(deltas, avg, ubound)))
}
}
def wrap(value:Int, ubound:Int):Int = {
(value+ubound)%ubound
}
def encode(lst1:ListBuffer[Int], ubound:Int):(ListBuffer[Int],Int)={
//var lst = ListBuffer[Int]()
//lst1.foreach(x=>lst+=x)
var lst = lst1
var deltas = new ListBuffer[Int]()
var avg = 0
while (lst.length>=2) {
var avgs = new ListBuffer[Int]()
while (lst.nonEmpty) {
// getting first two element from the list and removing them
val a = lst.head
lst -= 1 // removing index 0 element from the list
val b = lst.head
lst -= 1 // removing index 0 element from the list
if (a<=b) {
avg = (a + b)/2
}
else{
avg = (a+b+ubound)/2
}
var delta = wrap(b-a,ubound)
avgs += avg
deltas += delta
}
lst = avgs
}
(deltas, avg%ubound)
}
def decode(deltas:ListBuffer[Int],avg:Int,ubound:Int):ListBuffer[Int]={
var avgs = ListBuffer[Int](avg)
var l = 1
while(deltas.nonEmpty){
for(i <- 0 to l ){
val delta = deltas.last
deltas -= -1
val avg = avgs.last
avgs -= -1
val a = wrap(math.ceil(avg-delta/2.0).toInt,ubound)
val b = wrap(math.ceil(avg+delta/2.0).toInt,ubound)
}
l*=2
}
avgs
}
def is_pow2(n:Int):Boolean={
(n & -n) == n
}
}
But Code gets stuck at "var deltas1 = encode(samples(i), ubound)" and doesn't give any output. How can I improve my implementation? Thanks in advance!
Your error is on this line:
lst -= 1 // removing index 0 element from the list.
This doesn't remove index 0 from the list. It removes the element 1 (if it exists). This means that the list never becomes empty. The while-loop while (lst.nonEmpty) will therefore never terminate.
To remove the first element of the list, simply use lst.remove(0).
I am trying to do the pagerank Basic example in flink with little bit of modification(only in reading the input file, everything else is the same) i am getting the error as Task not serializable and below is the part of the output error
atorg.apache.flink.api.scala.ClosureCleaner$.ensureSerializable(ClosureCleaner.scala:179)
at org.apache.flink.api.scala.ClosureCleaner$.clean(ClosureCleaner.scala:171)
Below is my code
object hpdb {
def main(args: Array[String]) {
val env = ExecutionEnvironment.getExecutionEnvironment
val maxIterations = 10000
val DAMPENING_FACTOR: Double = 0.85
val EPSILON: Double = 0.0001
val outpath = "/home/vinoth/bigdata/assign10/pagerank.csv"
val links = env.readCsvFile[Tuple2[Long,Long]]("/home/vinoth/bigdata/assign10/ppi.csv",
fieldDelimiter = "\t", includedFields = Array(1,4)).as('sourceId,'targetId).toDataSet[Link]//source and target
val pages = env.readCsvFile[Tuple1[Long]]("/home/vinoth/bigdata/assign10/ppi.csv",
fieldDelimiter = "\t", includedFields = Array(1)).as('pageId).toDataSet[Id]//Pageid
val noOfPages = pages.count()
val pagesWithRanks = pages.map(p => Page(p.pageId, 1.0 / noOfPages))
val adjacencyLists = links
// initialize lists ._1 is the source id and ._2 is the traget id
.map(e => AdjacencyList(e.sourceId, Array(e.targetId)))
// concatenate lists
.groupBy("sourceId").reduce {
(l1, l2) => AdjacencyList(l1.sourceId, l1.targetIds ++ l2.targetIds)
}
// start iteration
val finalRanks = pagesWithRanks.iterateWithTermination(maxIterations) {
// **//the output shows error here**
currentRanks =>
val newRanks = currentRanks
// distribute ranks to target pages
.join(adjacencyLists).where("pageId").equalTo("sourceId") {
(page, adjacent, out: Collector[Page]) =>
for (targetId <- adjacent.targetIds) {
out.collect(Page(targetId, page.rank / adjacent.targetIds.length))
}
}
// collect ranks and sum them up
.groupBy("pageId").aggregate(SUM, "rank")
// apply dampening factor
//**//the output shows error here**
.map { p =>
Page(p.pageId, (p.rank * DAMPENING_FACTOR) + ((1 - DAMPENING_FACTOR) / pages.count()))
}
// terminate if no rank update was significant
val termination = currentRanks.join(newRanks).where("pageId").equalTo("pageId") {
(current, next, out: Collector[Int]) =>
// check for significant update
if (math.abs(current.rank - next.rank) > EPSILON) out.collect(1)
}
(newRanks, termination)
}
val result = finalRanks
// emit result
result.writeAsCsv(outpath, "\n", " ")
env.execute()
}
}
Any help in the right direction is highly appreciated? Thank you.
The problem is that you reference the DataSet pages from within a MapFunction. This is not possible, since a DataSet is only the logical representation of a data flow and cannot be accessed at runtime.
What you have to do to solve this problem is to assign the val pagesCount = pages.count value to a variable pagesCount and refer to this variable in your MapFunction.
What pages.count actually does, is to trigger the execution of the data flow graph, so that the number of elements in pages can be counted. The result is then returned to your program.
when I use apache spark scala API run the KMeans cluster. my program as follow:
object KMeans {
def closestPoint(p: Vector, centers: Array[Vector]) = {
var index = 0
var bestIndex = 0
var closest = Double.PositiveInfinity
for(i <- 0 until centers.length) {
var tempDist = p.squaredDist(centers(i))
if(tempDist < closest) {
closest = tempDist
bestIndex = i
}
}
bestIndex
}
def parseVector(line: String): Vector = {
new Vector(line.split("\\s+").map(s => s.toDouble))
}
def main(args: Array[String]): Unit = {}
System.setProperty("hadoop.home.dir", "F:/OpenSoft/hadoop-2.2.0")
val sc = new SparkContext("local", "kmeans cluster",
"G:/spark-0.9.0-incubating-bin-hadoop2",
SparkContext.jarOfClass(this.getClass()))
val lines = sc.textFile("G:/testData/synthetic_control.data.txt") // RDD[String]
val count = lines.count
val data = lines.map(parseVector _) // RDD[Vector]
data.foreach(println)
val K = 6
val convergeDist = 0.1
val kPoint = data.takeSample(withReplacement = false, K, 42) // Array[Vector]
kPoint.foreach(println)
var tempDist = 1.0
while(tempDist > convergeDist) {
val closest = data.map(p => (closestPoint(p, kPoint), (p, 1)))
val pointStat = closest.reduceByKey{case ((x1, y1), (x2, y2)) =>
(x1+x2, y1+y2)}
val newKPoint = pointStat.map{pair => (
pair._1,pair._2._1/pair._2._2)}.collectAsMap()
tempDist = 0.0
for(i <- 0 until K) {
tempDist += kPoint(i).squaredDist(newKPoint(i))
}
for(newP <- newKPoint) {
kPoint(newP._1) = newP._2
}
println("Finish iteration (delta=" + tempDist + ")")
}
println("Finish centers: ")
kPoint.foreach(println)
System.exit(0)
}
when I apply run as local mode , the log info as follow:
..................
14/03/31 11:29:15 INFO HadoopRDD: Input split: hdfs://hadoop-01:9000/data/synthetic_control.data:0+288374
program begin block , no running continue........
Can anyone can help me???
I'm seeing some strange behavior with Scala's collection.mutable.PriorityQueue. I'm performing an external sort and testing it with 1M records. Each time I run the test and verify the results between 10-20 records are not sorted properly. I replace the scala PriorityQueue implementation with a java.util.PriorityQueue and it works 100% of the time. Any ideas?
Here's the code (sorry it's a bit long...). I test it using the tools gensort -a 1000000 and valsort from http://sortbenchmark.org/
def externalSort(inFileName: String, outFileName: String)
(implicit ord: Ordering[String]): Int = {
val MaxTempFiles = 1024
val TempBufferSize = 4096
val inFile = new java.io.File(inFileName)
/** Partitions input file and sorts each partition */
def partitionAndSort()(implicit ord: Ordering[String]):
List[java.io.File] = {
/** Gets block size to use */
def getBlockSize: Long = {
var blockSize = inFile.length / MaxTempFiles
val freeMem = Runtime.getRuntime().freeMemory()
if (blockSize < freeMem / 2)
blockSize = freeMem / 2
else if (blockSize >= freeMem)
System.err.println("Not enough free memory to use external sort.")
blockSize
}
/** Sorts and writes data to temp files */
def writeSorted(buf: List[String]): java.io.File = {
// Create new temp buffer
val tmp = java.io.File.createTempFile("external", "sort")
tmp.deleteOnExit()
// Sort buffer and write it out to tmp file
val out = new java.io.PrintWriter(tmp)
try {
for (l <- buf.sorted) {
out.println(l)
}
} finally {
out.close()
}
tmp
}
val blockSize = getBlockSize
var tmpFiles = List[java.io.File]()
var buf = List[String]()
var currentSize = 0
// Read input and divide into blocks
for (line <- io.Source.fromFile(inFile).getLines()) {
if (currentSize > blockSize) {
tmpFiles ::= writeSorted(buf)
buf = List[String]()
currentSize = 0
}
buf ::= line
currentSize += line.length() * 2 // 2 bytes per char
}
if (currentSize > 0) tmpFiles ::= writeSorted(buf)
tmpFiles
}
/** Merges results of sorted partitions into one output file */
def mergeSortedFiles(fs: List[java.io.File])
(implicit ord: Ordering[String]): Int = {
/** Temp file buffer for reading lines */
class TempFileBuffer(val file: java.io.File) {
private val in = new java.io.BufferedReader(
new java.io.FileReader(file), TempBufferSize)
private var curLine: String = ""
readNextLine() // prep first value
def currentLine = curLine
def isEmpty = curLine == null
def readNextLine() {
if (curLine == null) return
try {
curLine = in.readLine()
} catch {
case _: java.io.EOFException => curLine = null
}
if (curLine == null) in.close()
}
override protected def finalize() {
try {
in.close()
} finally {
super.finalize()
}
}
}
val wrappedOrd = new Ordering[TempFileBuffer] {
def compare(o1: TempFileBuffer, o2: TempFileBuffer): Int = {
ord.compare(o1.currentLine, o2.currentLine)
}
}
val pq = new collection.mutable.PriorityQueue[TempFileBuffer](
)(wrappedOrd)
// Init queue with item from each file
for (tmp <- fs) {
val buf = new TempFileBuffer(tmp)
if (!buf.isEmpty) pq += buf
}
var count = 0
val out = new java.io.PrintWriter(new java.io.File(outFileName))
try {
// Read each value off of queue
while (pq.size > 0) {
val buf = pq.dequeue()
out.println(buf.currentLine)
count += 1
buf.readNextLine()
if (buf.isEmpty) {
buf.file.delete() // don't need anymore
} else {
// re-add to priority queue so we can process next line
pq += buf
}
}
} finally {
out.close()
}
count
}
mergeSortedFiles(partitionAndSort())
}
My tests don't show any bugs in PriorityQueue.
import org.scalacheck._
import Prop._
object PriorityQueueProperties extends Properties("PriorityQueue") {
def listToPQ(l: List[String]): PriorityQueue[String] = {
val pq = new PriorityQueue[String]
l foreach (pq +=)
pq
}
def pqToList(pq: PriorityQueue[String]): List[String] =
if (pq.isEmpty) Nil
else { val h = pq.dequeue; h :: pqToList(pq) }
property("Enqueued elements are dequeued in reverse order") =
forAll { (l: List[String]) => l.sorted == pqToList(listToPQ(l)).reverse }
property("Adding/removing elements doesn't break sorting") =
forAll { (l: List[String], s: String) =>
(l.size > 0) ==>
((s :: l.sorted.init).sorted == {
val pq = listToPQ(l)
pq.dequeue
pq += s
pqToList(pq).reverse
})
}
}
scala> PriorityQueueProperties.check
+ PriorityQueue.Enqueued elements are dequeued in reverse order: OK, passed
100 tests.
+ PriorityQueue.Adding/removing elements doesn't break sorting: OK, passed
100 tests.
If you could somehow reduce the input enough to make a test case, it would help.
I ran it with five million inputs several times, output matched expected always. My guess from looking at your code is that your Ordering is the problem (i.e. it's giving inconsistent answers.)