private IEnumerable <Edge <Vector2D> > genMinEdges(Graph <Vector2D> graph, IEnumerable <Vertex <Vector2D> > homeNodes, Vertex <Vector2D> stareaterMain) { var criticalNodes = new HashSet <Vertex <Vector2D> > { stareaterMain }; foreach (var home in homeNodes) { var path = Methods.AStar(home, stareaterMain, x => (x.Data - stareaterMain.Data).Length, (a, b) => (a.Data - b.Data).Length, x => graph.GetNeighbours(x)) ?? new List <Move <Vertex <Vector2D> > >(); foreach (var move in path) { criticalNodes.Add(move.FromNode); yield return(graph.GetEdge(move.FromNode, move.ToNode)); } } var treeNodes = new HashSet <Vertex <Vector2D> >(criticalNodes); var potentialEdges = new Dictionary <Edge <Vector2D>, double>(); var critPathDistance = new Dictionary <Vertex <Vector2D>, double>(); foreach (var node in criticalNodes) { critPathDistance[node] = 0; } while (treeNodes.Count < graph.VertexCount) { potentialEdges.Clear(); foreach (var node in treeNodes) { var edges = graph.GetEdges(node). Where(e => !treeNodes.Contains(e.FirstEnd) || !treeNodes.Contains(e.SecondEnd)); foreach (var edge in edges) { potentialEdges[edge] = (edge.FirstEnd.Data - edge.SecondEnd.Data).Length + critPathDistance[node]; } } var currentEdge = potentialEdges.Aggregate((a, b) => a.Value < b.Value ? a : b).Key; yield return(currentEdge); var fromNode = treeNodes.Contains(currentEdge.FirstEnd) ? currentEdge.FirstEnd : currentEdge.SecondEnd; var toNode = treeNodes.Contains(currentEdge.FirstEnd) ? currentEdge.SecondEnd : currentEdge.FirstEnd; var length = (currentEdge.FirstEnd.Data - currentEdge.SecondEnd.Data).Length; treeNodes.Add(toNode); critPathDistance[toNode] = critPathDistance[fromNode] + length; } }
public IEnumerable <Move <StarData> > ShortestPathTo(StarData fromStar, StarData toStar, double baseSpeed, MainGame game) { var wormholeSpeed = game.Statics.ShipFormulas.WormholeSpeed.Evaluate(new Var("speed", baseSpeed).Get); //TODO(later) cache result return(Methods.AStar( fromStar, toStar, x => (x.Position - toStar.Position).Length / wormholeSpeed, (a, b) => (a.Position - b.Position).Length / (this.VisibleWormholeAt(a, b, game) != null ? wormholeSpeed : baseSpeed), x => game.States.Stars )); }
public IEnumerable <Move <StarData> > ShortestPathTo(StarData fromStar, StarData toStar, Dictionary <Design, long> shipGroups, MainGame game) { var speedFormula = game.Statics.ShipFormulas.GalaxySpeed; var voidSpeed = speedFormula.Evaluate(FleetProcessor.SpeedVars(game.Statics, this, shipGroups, false).Get); var laneSpeed = speedFormula.Evaluate(FleetProcessor.SpeedVars(game.Statics, this, shipGroups, true).Get); //TODO(later) cache result return(Methods.AStar( fromStar, toStar, x => (x.Position - toStar.Position).Length / laneSpeed, (a, b) => (a.Position - b.Position).Length / (this.VisibleWormholeAt(a, b, game) != null ? laneSpeed : voidSpeed), x => game.States.Stars )); }
private void removeOutliers(Graph <Vector2D> graph) { var orderedEdges = graph.Edges.OrderByDescending(e => e.Weight).ToList(); foreach (var e in orderedEdges) { graph.RemoveEdge(e); var path = Methods.AStar(e.FirstEnd, e.SecondEnd, x => (x.Data - e.SecondEnd.Data).Length, (a, b) => (a.Data - b.Data).Length, x => graph.GetNeighbours(x)) ?? new List <Move <Vertex <Vector2D> > >(); var strideLenghts = path.Select(x => (x.ToNode.Data - x.FromNode.Data).Length).ToList(); if (strideLenghts.Count <= 2 || strideLenghts.Max() > e.Weight || strideLenghts.Sum() > e.Weight * 1.5) { graph.AddEdge(e); } } }