func (t *Trip) Score(gifts *map[int]gift.Gift) float64 { // NB - compute cost in reverse for efficiency lastPos := location.NorthPole tripWeight := sleighWeight tripWRW := 0.0 giftWeight := 0.0 if len(t.Gifts) == 0 { fmt.Println("Warning, empty trip") os.Exit(1) } gids := t.Gifts for i := len(gids) - 1; i >= 0; i-- { g := (*gifts)[gids[i]] tripWRW += location.Dist(g.Location, lastPos) * tripWeight lastPos = g.Location tripWeight += g.Weight giftWeight += g.Weight } if (t.Id >= 0) && (giftWeight > WeightLimit) { fmt.Println("Warning: Trip ", t.Id, " over weight limit") } tripWRW += location.Dist(location.NorthPole, (*gifts)[gids[0]].Location) * tripWeight return tripWRW }
func (t *Trip) OptimizeOrder(gifts *map[int]gift.Gift) { // Find the gift with the highest cost heaviestGid := -1 maxCost := 0.0 gids := t.Gifts tripWeight := 0.0 for _, gid := range gids { g := (*gifts)[gid] tripWeight += g.Weight cost := location.Dist(location.NorthPole, g.Location) * g.Weight if cost > maxCost { heaviestGid = gid maxCost = cost } } // Start new list and identify remaining gifts newGids := []int{heaviestGid} remGifts := make(map[int]bool) for _, gid := range gids { if gid != heaviestGid { remGifts[gid] = true } } // Loop until no remaining gifts lastGid := heaviestGid tripWeight -= (*gifts)[lastGid].Weight for len(remGifts) > 0 { bestGid := -1 bestCost := math.Inf(0) lastG := (*gifts)[lastGid] for gid, _ := range remGifts { g := (*gifts)[gid] cost := location.Dist(lastG.Location, g.Location) * tripWeight if cost < bestCost { bestGid = gid bestCost = cost } } // Add to new list and remove from map newGids = append(newGids, bestGid) tripWeight -= (*gifts)[bestGid].Weight delete(remGifts, bestGid) } t.Gifts = newGids }