public List <int> SelectPath()
        {
            rand = rand ?? new Random();
            if (map.Mines.Length == 0)
            {
                return(new List <int>());
            }
            if (map.Mines.Length == 1)
            {
                var mine       = map.Mines[0];
                var candidates = map.Sites.Where(s => Math.Abs(minDists.GetDist(mine, s.Id) - length) < length / 10).MaxListBy(f => graph.Vertexes[f.Id].Edges.Count);
                if (!candidates.Any())
                {
                    return(new List <int>());
                }

                var future = candidates[rand.Next(candidates.Count)].Id;
                return(minDists.GetReversedPath(mine, future).Reverse().ToList());
            }
            if (map.Mines.Length == 2)
            {
                var allPairs =
                    from m1 in map.Mines
                    from m2 in map.Mines
                    where m1 != m2
                    let p12 = minDists.GetReversedPath(m1, m2).Reverse().ToList()
                              select new { m1, m2, p12 };
                var closestTuple = allPairs.MinBy(t => t.p12.Count);
                return(closestTuple.p12.Take(length + 1).ToList());
            }
            else
            {
                var minesPaths    = map.Mines.Select(GreedyGrowPath).ToList();
                var bestMinesPath = minesPaths.MaxBy(EstimatePathByDinic);
                var fullPath      = bestMinesPath
                                    .Pairwise((a, b) => minDists.GetReversedPath(a, b).Reverse().Skip(1)).SelectMany(z => z)
                                    .Take(length)
                                    .ToList();
                fullPath.Insert(0, bestMinesPath[0]);
                return(fullPath.ToList());
            }
        }
Пример #2
0
        public Future[] GetFutures()
        {
            var minesOnPath    = path.Where(id => map.Mines.Contains(id)).ToList();
            var nonMinesOnPath = path.Where(id => !map.Mines.Contains(id)).ToList();

            return(minesOnPath
                   .Select(
                       mine => new Future(
                           mine,
                           nonMinesOnPath.MaxBy(site => minDists.GetDist(mine, site) + graph.Vertexes[site].Edges.Count / 10)))
                   .ToArray());
        }
Пример #3
0
        private static int CalculateCost(Future future, MineDistCalculator calculator)
        {
            var dist = 0;

            try
            {
                dist = calculator.GetDist(future.source, future.target);
            }
            catch (InvalidOperationException)
            {
                try
                {
                    dist = calculator.GetDist(future.target, future.source);
                }
                catch (InvalidOperationException)
                {
                    return(0);
                }
            }

            return(dist * dist * dist);
        }
        public ScoreData GetScoreData(int punter, Map map, Future[] futures)
        {
            var scoreData = new ScoreData();
            var graph     = new Graph(map);
            var distCalc  = new MineDistCalculator(graph);
            var minesCalc = new ConnectedCalculator(graph, punter);

            long res = 0;

            foreach (var vertex in graph.Vertexes)
            {
                var mines = minesCalc.GetConnectedMines(vertex.Key);
                foreach (var mine in mines)
                {
                    long dist = distCalc.GetDist(mine, vertex.Key);
                    res += dist * dist;
                }
            }
            scoreData.ScoreWithoutFutures = res;

            foreach (var future in futures)
            {
                var mines = minesCalc.GetConnectedMines(future.target);

                var dist = distCalc.GetDist(future.source, future.target);

                var futureScoreValue = dist * dist * dist;
                if (mines.Contains(future.source))
                {
                    scoreData.GainedFuturesScore += futureScoreValue;
                    scoreData.GainedFuturesCount++;
                }
                scoreData.PossibleFuturesScore += futureScoreValue;
                scoreData.TotalFuturesCount++;
            }

            return(scoreData);
        }
Пример #5
0
        public MeetingPointService(Graph graph, MineDistCalculator calculator, ServiceState serviceState, bool isSetupStage)
        {
            if (isSetupStage)
            {
                var bestPoint = -1;
                var bestValue = 0;
                var bestCount = 0;

                foreach (var vertex in graph.Vertexes)
                {
                    if (vertex.Value.IsMine)
                    {
                        continue;
                    }

                    var value = 0;
                    var count = 0;
                    foreach (var mine in graph.Mines)
                    {
                        var dist = calculator.GetDist(mine.Key, vertex.Key);
                        if (dist == -1)
                        {
                            continue;
                        }
                        count++;
                        value += dist;
                    }

                    if (bestPoint == -1 || bestCount < count || bestCount == count && value < bestValue)
                    {
                        bestPoint = vertex.Key;
                        bestCount = count;
                        bestValue = value;
                    }
                }
                serviceState.meetingPoint = bestPoint;
            }
            MeetingPoint = serviceState.meetingPoint;
        }
Пример #6
0
 private int CalcProperVertexScore(int vertexId, ICollection <int> claimedMineIds)
 {
     return(claimedMineIds.Select(
                mineId => MineDistCalculator.GetDist(mineId, vertexId))
            .Sum(x => GetScore(claimedMineIds, x, vertexId)));
 }