mirror of
https://github.com/gonum/gonum.git
synced 2025-10-05 15:16:59 +08:00
188 lines
3.9 KiB
Go
188 lines
3.9 KiB
Go
// Copyright ©2019 The Gonum Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package kdtree
|
|
|
|
import (
|
|
"sort"
|
|
"testing"
|
|
|
|
"golang.org/x/exp/rand"
|
|
)
|
|
|
|
type ints []int
|
|
|
|
func (a ints) Len() int { return len(a) }
|
|
func (a ints) Less(i, j int) bool { return a[i] < a[j] }
|
|
func (a ints) Slice(s, e int) SortSlicer { return a[s:e] }
|
|
func (a ints) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
|
|
|
func TestPartition(t *testing.T) {
|
|
rnd := rand.New(rand.NewSource(1))
|
|
|
|
for p := 0; p < 100; p++ {
|
|
list := make(ints, 1e5)
|
|
for i := range list {
|
|
list[i] = rnd.Int()
|
|
}
|
|
pi := Partition(list, rnd.Intn(list.Len()))
|
|
for i := 0; i < pi; i++ {
|
|
if list[i] > list[pi] {
|
|
t.Errorf("unexpected partition sort order p[%d] > p[%d]: %d > %d", i, pi, list[i], list[pi])
|
|
}
|
|
}
|
|
for i := pi + 1; i < len(list); i++ {
|
|
if list[i] <= list[pi] {
|
|
t.Errorf("unexpected partition sort order p[%d] <= p[%d]: %d <= %d", i, pi, list[i], list[pi])
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestPartitionCollision(t *testing.T) {
|
|
rnd := rand.New(rand.NewSource(1))
|
|
|
|
for p := 0; p < 10; p++ {
|
|
list := make(ints, 10)
|
|
for i := range list {
|
|
list[i] = rnd.Intn(5)
|
|
}
|
|
pi := Partition(list, p)
|
|
for i := 0; i < pi; i++ {
|
|
if list[i] > list[pi] {
|
|
t.Errorf("unexpected partition sort order p[%d] > p[%d]: %d > %d", i, pi, list[i], list[pi])
|
|
}
|
|
}
|
|
for i := pi + 1; i < len(list); i++ {
|
|
if list[i] <= list[pi] {
|
|
t.Errorf("unexpected partition sort order p[%d] <= p[%d]: %d <= %d", i, pi, list[i], list[pi])
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func sortSelection(list ints, k int) int {
|
|
sort.Sort(list)
|
|
return list[k]
|
|
}
|
|
|
|
func TestSelect(t *testing.T) {
|
|
rnd := rand.New(rand.NewSource(1))
|
|
|
|
for k := 0; k < 2121; k++ {
|
|
list := make(ints, 2121)
|
|
for i := range list {
|
|
list[i] = rnd.Intn(1000)
|
|
}
|
|
Select(list, k)
|
|
sorted := append(ints(nil), list...)
|
|
want := sortSelection(sorted, k)
|
|
if list[k] != want {
|
|
t.Errorf("unexpected result from Select(..., %d): got:%v want:%d", k, list[k], want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestMedianOfMedians(t *testing.T) {
|
|
rnd := rand.New(rand.NewSource(1))
|
|
|
|
list := make(ints, 1e4)
|
|
for i := range list {
|
|
list[i] = rnd.Int()
|
|
}
|
|
p := MedianOfMedians(list)
|
|
med := list[p]
|
|
sort.Sort(list)
|
|
var found bool
|
|
for _, v := range list[len(list)*3/10 : len(list)*7/10+1] {
|
|
if v == med {
|
|
found = true
|
|
break
|
|
}
|
|
}
|
|
if !found {
|
|
t.Error("failed to find median")
|
|
}
|
|
}
|
|
|
|
func TestMedianOfRandoms(t *testing.T) {
|
|
rnd := rand.New(rand.NewSource(1))
|
|
|
|
list := make(ints, 1e4)
|
|
for i := range list {
|
|
list[i] = rnd.Int()
|
|
}
|
|
p := MedianOfRandoms(list, randoms)
|
|
med := list[p]
|
|
sort.Sort(list)
|
|
var found bool
|
|
for _, v := range list[len(list)*3/10 : len(list)*7/10+1] {
|
|
if v == med {
|
|
found = true
|
|
break
|
|
}
|
|
}
|
|
if !found {
|
|
t.Error("failed to find median")
|
|
}
|
|
}
|
|
|
|
var benchSink int
|
|
|
|
func BenchmarkMedianOfMedians(b *testing.B) {
|
|
rnd := rand.New(rand.NewSource(1))
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
b.StopTimer()
|
|
list := make(ints, 1e4)
|
|
for i := range list {
|
|
list[i] = rnd.Int()
|
|
}
|
|
b.StartTimer()
|
|
benchSink = MedianOfMedians(list)
|
|
}
|
|
}
|
|
|
|
func BenchmarkPartitionMedianOfMedians(b *testing.B) {
|
|
rnd := rand.New(rand.NewSource(1))
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
b.StopTimer()
|
|
list := make(ints, 1e4)
|
|
for i := range list {
|
|
list[i] = rnd.Int()
|
|
}
|
|
b.StartTimer()
|
|
benchSink = Partition(list, MedianOfMedians(list))
|
|
}
|
|
}
|
|
|
|
func BenchmarkMedianOfRandoms(b *testing.B) {
|
|
rnd := rand.New(rand.NewSource(1))
|
|
|
|
b.StopTimer()
|
|
list := make(ints, 1e4)
|
|
for i := range list {
|
|
list[i] = rnd.Int()
|
|
}
|
|
b.StartTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
benchSink = MedianOfRandoms(list, list.Len()/1e3)
|
|
}
|
|
}
|
|
|
|
func BenchmarkPartitionMedianOfRandoms(b *testing.B) {
|
|
rnd := rand.New(rand.NewSource(1))
|
|
|
|
b.StopTimer()
|
|
list := make(ints, 1e4)
|
|
for i := range list {
|
|
list[i] = rnd.Int()
|
|
}
|
|
b.StartTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
benchSink = Partition(list, MedianOfRandoms(list, list.Len()/1e3))
|
|
}
|
|
}
|