Example #1
0
 public Satellite(Satellite s)
     : this(s.Pos.Lat, s.Pos.Lon, s.Speed, s.RotSpeed, s.MaxRot, s.Id)
 {
     CurrentRot = new Coords(s.CurrentRot);
     CurrentTurn = s.CurrentTurn;
     Range = new Range(s.Range);
 }
Example #2
0
 public PartialSolution(float val, Range range, List<Snapshot> snaps, BitArray taken)
 {
     EstimatedValue = val;
     CurrentRange = range;
     Snapshots = snaps;
     PicturesTaken = taken;
 }
Example #3
0
 /// <summary>
 /// assumes satellite is already at the right position
 /// </summary>
 public Snapshot TakePicture(Coords pict)
 {
     CurrentRot.Lat = pict.Lat - Pos.Lat;
     CurrentRot.Lon = pict.Lon - Pos.Lon;
     Range = new Range {DeltaLatMin = CurrentRot.Lat, DeltaLatMax = CurrentRot.Lat, DeltaLonMin = CurrentRot.Lon, DeltaLonMax = CurrentRot.Lon}; //reset range to zero around current direction
     return new Snapshot(pict.Lat, pict.Lon, CurrentTurn, Id);
 }
Example #4
0
        public static Solution Solve(Input input)
        {
            var tree = BuildTree(input);
            var satellites = input.Satellites.OrderBy(s => s.MaxRot).ToArray();
            var totalNbPic = tree.Count;
            var solution = new List<Snapshot>();

            var picturesConfirmed = new BitArray(totalNbPic);
            for (int s = 0; s < satellites.Length; s++)
            {
                var satellite = satellites[s];
                Console.WriteLine($"satellite {s+1}/{satellites.Length} (#{satellite.Id})");

                var state = new List<PartialSolution> {new PartialSolution(picturesConfirmed)};

                for (int t = 1; t < input.NbTurns; t++)
                {
                    if (t % 20000 == 0) Console.WriteLine(t);

                    Step(state, satellite);
                    SimplifyRanges(state);

                    //look for pictures to take
                    var candidates = tree.RadialSearch(new float[] {satellite.Pos.Lat, satellite.Pos.Lon}, satellite.MaxRot*SQRT2, 150); //TOO SLOW !
                    Helper.Assert(() => candidates.Length < 145, candidates.Length);
                    candidates = candidates.Where(node => !picturesConfirmed.Get(node.Value.Item1 + node.Value.Item2.BasePicId) && node.Value.Item2.PictureCanBeTaken(t)).ToArray();

                    var stopIdx = state.Count; //we're gonna add more, but we don't want to browse'em
                    for (int st = 0; st < stopIdx; st++)
                    {
                        var sol = state[st];
                        var range = sol.CurrentRange;
                        foreach (var candidate in candidates)
                        {
                            var collec = candidate.Value.Item2;
                            var picIdx = candidate.Value.Item1;
                            if(sol.PicturesTaken.Get(collec.BasePicId + picIdx))
                                continue;

                            var picLoc = collec.Locations[picIdx];
                            if (picLoc.IsInRange(range, satellite.Pos))
                            {
                                var newScore = sol.EstimatedValue + Score(collec, sol);
                                var newRange = new Range(satellite.Pos, picLoc);
                                if (!WorthTaking(newScore, newRange, state))
                                    continue;

                                var newCommands = new List<Snapshot>(sol.Snapshots);
                                newCommands.Add(new Snapshot(picLoc.Lat, picLoc.Lon, t, satellite.Id));
                                var taken = new BitArray(sol.PicturesTaken);
                                taken.Set(collec.BasePicId + picIdx, true);
                                state.Add(new PartialSolution (newScore, newRange, newCommands, taken));
                            }
                        }
                    }
                }

                PartialSolution best = null;
                foreach (var partialSolution in state)
                {
                    if (best == null || partialSolution.EstimatedValue > best.EstimatedValue)
                        best = partialSolution;
                }
                solution.AddRange(best.Snapshots);
                picturesConfirmed.Or(best.PicturesTaken); //union
            }

            int score = 0;
            foreach (var picCollection in input.Collections)
            {
                bool complete = true;
                var stop = picCollection.BasePicId + picCollection.Locations.Count;
                for (int i = picCollection.BasePicId; i < stop; i++)
                {
                    if (!picturesConfirmed.Get(i))
                    {
                        complete = false;
                        break;
                    }
                }
                if (complete)
                    score += picCollection.Value;
            }
            return new Solution(solution, score);
        }
Example #5
0
 public PartialSolution(BitArray taken)
 {
     CurrentRange = new Range();
     Snapshots = new List<Snapshot>();
     PicturesTaken = taken;
 }
Example #6
0
 static bool WorthTaking(float newScore, Range newRange, List<PartialSolution> state)
 {
     bool take = true;
     Parallel.ForEach(state, (sol, loop) =>
     {
         if (newScore <= sol.EstimatedValue && sol.CurrentRange.Contains(newRange))
         {
             take = false;
             loop.Stop();
         }
     });
     return take;
 }
Example #7
0
 public Range(Range range)
 {
     DeltaLatMin = range.DeltaLatMin;
     DeltaLatMax = range.DeltaLatMax;
     DeltaLonMin = range.DeltaLonMin;
     DeltaLonMax = range.DeltaLonMax;
 }
Example #8
0
 public bool Contains(Range other)
 {
     return other.DeltaLatMin >= DeltaLatMin
            && other.DeltaLatMax <= DeltaLatMax
            && other.DeltaLonMin >= DeltaLonMin
            && other.DeltaLonMax <= DeltaLonMax;
 }