1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
| package main
import ( "fmt" "math" "math/rand" )
var r = rand.New(rand.NewSource(0))
func abs(num int) int { if num < 0 { return -num } return num }
func calculateScore(nums []int) int { sum, res := 0, 0 for i := 0; i < len(nums); i++ { sum += nums[i] for j := i + 1; j < len(nums); j++ { res += abs(nums[j] - nums[i]) } } sum /= len(nums) for i := 0; i < len(nums); i++ { res += abs(sum - nums[i]) } return res }
func dispatch(nums []int, m int) { T, minT, ratio := 100.0, 0.0001, 0.99
tmp := append([]int{}, nums...) fix := initial(len(nums), m) for i := 0; i < len(nums); i++ { tmp[i] += fix[i] } s1 := calculateScore(tmp) bestNum := append([]int{}, tmp...) fmt.Println(bestNum)
for T > minT { iter := 500 for iter > 0 { pre := append([]int{}, tmp...)
localSearch(nums, pre) s2 := calculateScore(pre) if s2 < s1 { bestNum = append([]int{}, pre...) tmp, s1 = append([]int{}, pre...), s2 } else if math.Exp(-float64(s2-s1)/T) < r.Float64() { tmp, s1 = append([]int{}, pre...), s2 } iter-- } T *= ratio } for i := 0; i < len(nums); i++ { nums[i] = bestNum[i] } fmt.Println(bestNum) }
func initial(cnt, m int) []int { var res []int for i := 0; i < cnt-1; i++ { num := r.Intn(m) m -= num res = append(res, num) } res = append(res, m) return res }
func findMaxMin(nums []int) (int, int) { min, max := 1<<32-1, -1<<32 ind1, ind2 := 0, 0
for ind, num := range nums { if num > max { max, ind2 = num, ind } if num < min { min, ind1 = num, ind } } return ind1, ind2 }
func localSearch(nums, tmp []int) { minInd, maxInd := findMaxMin(tmp) if nums[minInd] > tmp[minInd] || nums[maxInd] > tmp[maxInd] { tmp = append([]int{}, nums...) return } if tmp[maxInd] > nums[maxInd] { m := r.Intn(tmp[maxInd] - nums[maxInd]) tmp[minInd] += m tmp[maxInd] -= m } }
func calculateSum(nums []int) int { sum := 0 for i := 0; i < len(nums); i++ { sum += nums[i] } return sum }
func main() { nums := []int{1, 200, 3, 4, 50} m := 200 sum := m + calculateSum(nums) fmt.Println(nums, sum)
dispatch(nums, m) fmt.Println(nums, calculateSum(nums)) }
------------------- [1 200 3 4 50] 458 初始值 [75 272 16 28 67] [75 201 55 60 67] [75 201 55 60 67] 458 最终分配结果
|