package weightDistributing import ( "math" ) type Weight struct { Id string Weight int32 Replica int32 } func DistributeReplicas(weights []*Weight, replicas int32) { var weightSum int32 weightSum = 0 for _, w := range weights { weightSum += w.Weight } weightRatio := make([]float64, len(weights)) for i, w := range weights { weightRatio[i] = float64(w.Weight) / float64(weightSum) } var rest = replicas for i := 0; i < len(weights); i++ { var n = math.Round(float64(replicas) * weightRatio[i]) rest -= int32(n) weights[i].Replica = int32(n) } for { if rest == 0 { break } maxIdx := 0 minIdx := 0 if rest > 0 { for i, ratio := range weightRatio { if ratio > weightRatio[maxIdx] { maxIdx = i } } } else { for i, ratio := range weightRatio { if ratio < weightRatio[minIdx] { minIdx = i } } } if rest > 0 { weights[maxIdx].Replica++ weightRatio[maxIdx]-- rest-- } else { weights[minIdx].Replica-- weightRatio[minIdx]++ rest++ } } }