69 lines
1.8 KiB
Go
69 lines
1.8 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
po "github.com/Snider/Poindexter"
|
|
)
|
|
|
|
// BuildPingHop2D wraps poindexter.Build2D to construct 2D points from (ping_ms, hop_count).
|
|
func BuildPingHop2D[T any](
|
|
items []T,
|
|
id func(T) string,
|
|
ping func(T) float64,
|
|
hops func(T) float64,
|
|
weights [2]float64,
|
|
invert [2]bool,
|
|
) ([]po.KDPoint[T], error) {
|
|
return po.Build2D(items, id, ping, hops, weights, invert)
|
|
}
|
|
|
|
// BuildPingHopGeo3D wraps poindexter.Build3D for (ping_ms, hop_count, geo_km).
|
|
func BuildPingHopGeo3D[T any](
|
|
items []T,
|
|
id func(T) string,
|
|
ping func(T) float64,
|
|
hops func(T) float64,
|
|
geoKM func(T) float64,
|
|
weights [3]float64,
|
|
invert [3]bool,
|
|
) ([]po.KDPoint[T], error) {
|
|
return po.Build3D(items, id, ping, hops, geoKM, weights, invert)
|
|
}
|
|
|
|
// BuildPingHopGeoScore4D wraps poindexter.Build4D for (ping_ms, hop_count, geo_km, score).
|
|
// Typical usage sets invert for score=true so higher score => lower cost.
|
|
func BuildPingHopGeoScore4D[T any](
|
|
items []T,
|
|
id func(T) string,
|
|
ping func(T) float64,
|
|
hops func(T) float64,
|
|
geoKM func(T) float64,
|
|
score func(T) float64,
|
|
weights [4]float64,
|
|
invert [4]bool,
|
|
) ([]po.KDPoint[T], error) {
|
|
return po.Build4D(items, id, ping, hops, geoKM, score, weights, invert)
|
|
}
|
|
|
|
// Demo program that builds a small tree using the 2D helper and performs a query.
|
|
func main() {
|
|
type Peer struct {
|
|
ID string
|
|
PingMS, Hops float64
|
|
}
|
|
peers := []Peer{{"A", 20, 1}, {"B", 50, 2}, {"C", 10, 3}}
|
|
|
|
pts, err := BuildPingHop2D(peers,
|
|
func(p Peer) string { return p.ID },
|
|
func(p Peer) float64 { return p.PingMS },
|
|
func(p Peer) float64 { return p.Hops },
|
|
[2]float64{1.0, 0.7},
|
|
[2]bool{false, false},
|
|
)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
kdt, _ := po.NewKDTree(pts, po.WithMetric(po.EuclideanDistance{}))
|
|
best, dist, _ := kdt.Nearest([]float64{0, 0})
|
|
fmt.Println(best.ID, dist)
|
|
}
|