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
                       ));
        }
Beispiel #3
0
        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);
                }
            }
        }