package main
import (
."fmt"
"math"
)
//决策因素结构 data
type Factor struct{
Id int ` json:"id" form:"id"`// 主键
Dishname string ` json:"dishname" form:"dishname"`//菜名
Culture float64 ` json:"culture" form:"culture"`//文化
Tradition float64 `json:"tradition"` //传统
Habit float64 `json:"habit"`//习惯
Budget float64 `json:"budget"`//预算
Curious float64 `json:"curious"`//好奇心
Aesthetic float64 `json:"aesthetic"`//审美
Bodybuilding float64 `json:"bodybuilding"`//健身
Health float64 `json:"health"`//健康
Distance_s float64 `json:"distance_s"`//距离
}//菜名 res 菜名 距离
type Dish struct{
Id int `json:"id"`//主键
Dishname string `json:"dishname"`//菜名
Value float64 `json:"value"`//权值
Distance_s float64 `json:"distance_s"`//距离
}//读取数据源
func ReadData() []Factor{
Printf("Read OK.")
factors := make([]Factor, 0)
return factors
}//将数据源分组 一部分33%测试 一部分66%训练
func SplitData(F []Factor) ([]Factor,[]Factor) {
Printf("Split OK.")
length:=len(F)
L1:=int(float64(length)*0.33)
return F[0:L1],F[L1:length]
}//开方
func InvSqrt(x float64) float64 {
var xhalf float64 = 0.5*x // get bits for floating VALUE
i := math.Float64bits(x) // gives initial guess y0
i = 0x5f375a86 - (i>>1) // convert bits BACK to float
x = math.Float64frombits(i) // Newton step, repeating increases accuracy
x = x*(1.5-xhalf*x*x)
x = x*(1.5-xhalf*x*x)
x = x*(1.5-xhalf*x*x)
return 1/x
}//求距离公式
func Distance(A Factor,B Factor) float64{
Printf("Distance OK.")
var sum float64
sum=0
sum=(A.Culture-B.Culture)*(A.Culture-B.Culture)+(A.Tradition-B.Tradition)*(A.Tradition-B.Tradition)
sum=sum+(A.Budget-B.Budget)*(A.Budget-B.Budget)+(A.Habit-B.Habit)*(A.Habit-B.Habit)
sum=sum+(A.Curious-B.Curious)*(A.Curious-B.Curious)+(A.Aesthetic-B.Aesthetic)*(A.Aesthetic-B.Aesthetic)
sum=sum+(A.Bodybuilding-B.Bodybuilding)*(A.Bodybuilding-B.Bodybuilding)+(A.Health-B.Health)*(A.Health-B.Health)
return InvSqrt(sum)
}//排序子算法
func quickSort(A []float64, p int, r int,B []Dish) {
if p < r {
q := partition(A, p, r,B)
Println(q)
quickSort(A, p, q-1,B)
quickSort(A, q+1, r,B)
}
}
func partition(A []float64, p int, r int,B []Dish) int {
x := A[r-1]
i := p - 1
for j := p; j < r-1; j++ {
if A[j] >= x {
i += 1
A[i], A[j] = A[j], A[i]
B[i], B[j] = B[j], B[i]
}
}
A[i+1], A[r-1] = A[r-1], A[i+1]
B[i+1], B[r-1] = B[r-1], B[i+1]
return i + 1
}//排序
func Sort(x []Dish) []Dish {
date:=make([]float64,len(x))
for index := 0; index < len(x); index++ {
date[index]=x[index].Value
}
quickSort(date, 0, len(date),x)
Printf("Sort OK.")
return x
}//排序权值
func SortEnd(x []Dish) []Dish {
date:=make([]float64,len(x))
for index := 0; index < len(x); index++ {
date[index]=x[index].Distance_s
}
quickSort(date, 0, len(date),x)
Printf("Sort OK.")
return x
}//取前K个
func Get(k int,A []Dish) []Dish {
Printf("Get OK.")
if len(A)<=k {
return A
}
return A[0:k]
}//加权平均 算出权值
func Averange(x[]Dish) []Dish {
Printf("Averange OK.")
var sum float64
for i := 0; i < len(x); i++ {
sum+=x[i].Distance_s
}
for i := 0; i < len(x); i++ {
x[i].Value=1-(x[i].Distance_s/sum)
}
return x
}//Knn汇总最终算法
func Knn(factors []Factor,data Factor) Dish {
Printf("Knn OK.")
length:=len(factors)
dish := make([]Dish, 20)
//1距离
for i := 0; i < length; i++ {
dish[i].Dishname=factors[i].Dishname
dish[i].Distance_s=Distance(data,factors[i])
}
//2排序---升序
dish1 := make([]Dish, 20)
dish1=Sort(dish)
//3取前k个
k:=5
dishEnd:=Get(k,dish1)
//4加权平均
dishEnd=Averange(dishEnd)
//5选出最大权值--得出结果
return SortEnd(dishEnd)[0]
}
func main() {
factors := make([]Factor, 100)
L1,L2:=SplitData(factors)
//var end Dish
end:=Knn(L2,L1[3])
Println(end)
// Println(len(L1))
// Println("OK")
// Println(len(L2))
}