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)