Skip to content

Instantly share code, notes, and snippets.

@volkanbicer
Created November 12, 2017 20:44
Show Gist options
  • Select an option

  • Save volkanbicer/38d617b1c282751862ed789ea2b403dd to your computer and use it in GitHub Desktop.

Select an option

Save volkanbicer/38d617b1c282751862ed789ea2b403dd to your computer and use it in GitHub Desktop.
Selection Sampling
func select<T>(from a: [T], count k: Int) -> [T] {
var a = a
for i in 0..<k {
let r = random(min: i, max: a.count - 1)
if i != r {
swap(&a[i], &a[r])
}
}
return Array(a[0..<k])
}
func reservoirSample<T>(from a: [T], count k: Int) -> [T] {
precondition(a.count >= k)
var result = [T]() // 1
for i in 0..<k {
result.append(a[i])
}
for i in k..<a.count { // 2
let j = random(min: 0, max: i)
if j < k {
result[j] = a[i]
}
}
return result
}
func select<T>(from a: [T], count requested: Int) -> [T] {
var examined = 0
var selected = 0
var b = [T]()
while selected < requested { // 1
let r = Double(arc4random()) / 0x100000000 // 2
let leftToExamine = a.count - examined // 3
let leftToAdd = requested - selected
if Double(leftToExamine) * r < Double(leftToAdd) { // 4
selected += 1
b.append(a[examined])
}
examined += 1
}
return b
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment