I'm using a scala.collection.mutable.TreeSet and I'm running into a problem, where it fails to remove an element when -=
is called.
My code:
val discovered = new TreeSet[Position]()(Ordering by { position => estimation(position) })
//Position is defined as: type Position = (Int, Int)
discovered += start
var x = 0
while(!discovered.isEmpty){
val current = discovered.head
println(discovered)
discovered -= current
println(discovered)
x += 1
println(s"$x $current")
[...] //Code to process current and discover new positions
}
The following example shows, that (18,46) is not removed. Up until that point the removing worked perfectly. I have other test cases, which work perfecly and other cases where this problem does not happen until about 100 iterations are reached. I've got the same result with the immutable implementation of TreeSet
.
Part of the output:
TreeSet((22,42), (18,46), (21,44), (24,46), (22,47), (21,43), (21,47), (23,47), (24,47))
TreeSet((18,46), (21,44), (24,46), (22,47), (21,43), (21,47), (23,47), (24,47))
14 (22,42)
TreeSet((18,46), (21,44), (22,41), (24,46), (22,47), (21,43), (21,47), (23,47), (24,47))
TreeSet((18,46), (21,44), (22,41), (24,46), (22,47), (21,43), (21,47), (23,47), (24,47))
15 (18,46)
TreeSet((18,46), (21,44), (22,41), (24,46), (22,47), (21,43), (21,47), (23,47), (24,47), (17,46))
TreeSet((18,46), (21,44), (22,41), (24,46), (22,47), (21,43), (21,47), (23,47), (24,47), (17,46))
16 (18,46)
Thanks to everyone for your answers! The ordering was related to the problem, so it helped a lot to find the error.
Clarification:
I'm implementing a lot of my code base fully functional. For this algorithm it was not possible for several reasons. Also: If there was a PriorityQueue, that had an updateElement() function, I would have used that instead of the TreeSet for better performance and to avoid the problem I ran into.
My solution:
As said: I have to implement it mutable and mostly imperative. The problem was in those lines of code
estimation(somePosition) = newScore
if(alreadyDiscovered){ discovered -= somePosition }
discovered += somePosition
Removing somePosition
from discovered
is making use of the ordering, which was changed in the line above. So when the RB tree tries to delete the element it does not find it anymore. The following code is working for all test cases
if(alreadyDiscovered){ discovered -= somePosition }
estimation(somePosition) = newScore
discovered += somePosition
If there is a better data structure than TreeSet in vanilla scala for this task I would love to switch to that.