This problem stems from a musical training game where I must choose a random 3-note chord from the 12 available pitch-classes, but certain notes are more likely than others (so that the user can train more for weaker notes).

I thought this problem would be quite simple: consider each weight as a line segment, place all segments one after the other to make a long segment, pick a random point on this long segment, record which weight it lies on, rinse and repeat until we have k items.

The following Python code demonstrates that this technique doesn't produce the correct results:

```
# Choose k items from a set of weights
# return set of winning indices
def Choose(W,k):
    import random

    cumulative = [ sum(W[:i+1]) for i in xrange(len(W)) ]
    totalWeight = cumulative[-1]

    winners = set()
    while len(winners) < k:
        rnd = random.uniform(0.0, totalWeight)

        # Returns first element of cumulative that is >= rnd
        w = next( i for i in xrange(len(cumulative)) if cumulative[i] >= rnd )
        winners.add( w )

    return winners

def Test(N):
    x = [ list(Choose( [5,3,2], 2 )) for i in xrange(int(N/2))]
    y = sum(x, [])
    z = [y.count(i) for i in (0,1,2) ]

    print z

for i in range(10):
    Test(10000)

```

I generate 5000 random pairs from 3 weights [5,3,2]
The output logs the number of times each weight comes up
It should be 5000,3000,2000

For good measure I run the experiment 10 times:

```
python test.py 
[4173, 3331, 2496]
[4180, 3367, 2453]
[4193, 3393, 2414]
[4228, 3375, 2397]
[4207, 3388, 2405]
[4217, 3377, 2406]
[4173, 3438, 2389]
[4172, 3378, 2450]
[4174, 3371, 2455]
[4208, 3322, 2470]

```

So ~ 4200 vs 3300 vs 2400
Not 5000 vs 3000 vs 2000

Is there a simple way to understand why this doesn't work?

Is there some way of transforming the weights, maybe 'weight[i] -> ln(weight[i])' or something like this, that would give correct results?

How to achieve the correct result? (I'm more concerned about clarity of code than optimal efficiency)