Hi Leec, sorry for the delayed reply, I was on vacation.
I think your second proposition gets closer to a solution but would not give the expected result for several reasons. One being the for (i = 0; i<1; i++) statement that would be executed only once.
I believe it is more convenient to use two Lists instead of one KeyMap because it makes it easier to check if one value has already been choosen or not. And I would use another list (called blacklisted) to store the index of already choosen values and avoid choosing them again.
So if we consider that we already have one list of objects in lobj and a list of their corresponding weights in lweights, here is a proposed solution:
fix choosen = new List<Integer> // where we store the resulting choosen objects
fix blacklisted = new List<Integer> // already choosen index
while (choosen.size < 5) {
// compute the sum of all remaining weights
let wsum = 0.0
for (i : 0..lobj.size-1)
if (!blacklisted.contains(i)) wsum += lweight.get(i)
// Pick up one value that is not already choosen
let found = false
do {
fix r = random*wsum
let cursor = 0.0
let choiceindex = 0
while (r > cursor) {
cursor += lweight.get(choiceindex)
choiceindex++
}
if (!blacklisted.contains(choiceindex)) {
choosen.add(lobj.get(choiceindex))
blacklisted.add(choiceindex)
found = true
}
} while (!found)
}
println(choosen)