func (s *Submission) LoadFile(subFile string) error { subfile, err := os.Open(subFile) if err == nil { defer subfile.Close() reader := csv.NewReader(subfile) rec, err := reader.Read() reader.FieldsPerRecord = len(rec) for true { rec, err = reader.Read() if err != nil { break } gid, _ := strconv.Atoi(rec[0]) tid, _ := strconv.Atoi(rec[1]) t, exists := s.Trips[tid] if !exists { s.Trips[tid] = trip.TripNew(tid) t = s.Trips[tid] } t.AddGift(gid) } } return err }
func Cluster(gifts *map[int]gift.Gift) *submission.Submission { // Create SQT fmt.Println("Creating SQT....") s := sqt.NewSQT() for _, g := range *gifts { s.AddNode(g.Id, g.Weight, g.Location.Lat, g.Location.Lon) } // Split the SQT fmt.Println("Splitting SQT...") s.Split(func(tri *sqt.Triangle) bool { retval := false if (math.Ceil(tri.Weight/trip.WeightLimit) > 2) || (len(tri.Nodes) > 10) { retval = true } return retval }) // Iterate over triangles and cluster nodes fmt.Println("Clustering......") sub := submission.NewSubmission() tid := 1 for _, tri := range s.Triangles { if tri.NumNodes() == 0 { continue } if len(tri.Nodes) > 0 { k := int(math.Ceil(tri.Weight / trip.WeightLimit)) clusts := kmeans.Cluster(tri.Nodes, k, trip.WeightLimit) // Create a trip for each cluster for _, clust := range clusts { t := trip.TripNew(tid) for _, n := range clust { t.AddGift(n.Id) } sub.AddTrip(t) tid++ } } } return sub }
func Naive(gifts *map[int]gift.Gift) *submission.Submission { fmt.Println("Called Naive function") s := submission.NewSubmission() tid := 1 for _, g := range *gifts { t := trip.TripNew(tid) t.AddGift(g.Id) s.AddTrip(t) tid++ } fmt.Println("Last tid: ", tid) return s }
func (s *Submission) OptimizeTrips(gifts *map[int]gift.Gift) { // OPTIMIZE BY LATITUDE tripsByLon := map[int]TripOptList{} res := 0.5 for _, t := range s.Trips { t.OptimizeOrder(gifts) t.CalcWeight(gifts) t.CacheScore(gifts) l := t.GetLongitude(gifts) b := int(math.Floor(l / res)) tripsByLon[b] = append(tripsByLon[b], NewTripOpt(t, t.GetLatitude(gifts))) } MergedTrips := map[int]*trip.Trip{} for _, tol := range tripsByLon { sort.Sort(tol) skipTrip := map[*trip.Trip]bool{} for i := 0; i < len(tol); i++ { t1 := tol[i].T if skipTrip[t1] == true { continue } tnew := &trip.Trip{t1.Id, t1.Gifts, t1.Weight, t1.WRW} for j := i + 1; j < len(tol); j++ { t2 := tol[j].T if skipTrip[t2] == true { continue } if (tnew.Weight + t2.Weight) > trip.WeightLimit { continue } // Make sure to complete closest trip first ttest := trip.TripNew(-1) ttest.Gifts = append(ttest.Gifts, tnew.Gifts...) ttest.Gifts = append(ttest.Gifts, t1.Gifts...) newscore := ttest.Score(gifts) if newscore < (tnew.WRW + t2.WRW) { tnew.Gifts = append(t2.Gifts, tnew.Gifts...) skipTrip[t2] = true tnew.Score(gifts) tnew.CalcWeight(gifts) } } MergedTrips[tnew.Id] = tnew } } s.Trips = MergedTrips // OPTIMIZE BY SPACE AVAILABLE MergedTrips = map[int]*trip.Trip{} unfilledTrips := TripList{} for _, t := range s.Trips { t.CalcWeight(gifts) t.CacheScore(gifts) if (trip.WeightLimit - t.Weight) > 10 { unfilledTrips = append(unfilledTrips, t) } else { MergedTrips[t.Id] = t } } sort.Sort(unfilledTrips) skipTrip := map[*trip.Trip]bool{} for i := 0; i < len(unfilledTrips); i++ { t1 := unfilledTrips[i] if skipTrip[t1] == true { continue } tnew := &trip.Trip{t1.Id, t1.Gifts, t1.Weight, t1.WRW} for j := i + 1; j < len(unfilledTrips); j++ { t2 := unfilledTrips[j] if skipTrip[t2] == true { continue } if (tnew.Weight + t2.Weight) > trip.WeightLimit { continue } ttest := trip.TripNew(-1) ttest.Gifts = append(ttest.Gifts, t2.Gifts...) ttest.Gifts = append(ttest.Gifts, tnew.Gifts...) newscore := ttest.Score(gifts) if newscore <= (tnew.WRW + t2.WRW) { tnew.Gifts = append(t2.Gifts, tnew.Gifts...) skipTrip[t2] = true tnew.Score(gifts) tnew.CalcWeight(gifts) } } MergedTrips[tnew.Id] = tnew } s.Trips = MergedTrips }