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()); } }
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()); }
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); }
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; }
private int CalcProperVertexScore(int vertexId, ICollection <int> claimedMineIds) { return(claimedMineIds.Select( mineId => MineDistCalculator.GetDist(mineId, vertexId)) .Sum(x => GetScore(claimedMineIds, x, vertexId))); }