Exemplo n.º 1
0
        object PartOne(string input)
        {
            CreateGraph();
            var pathing = _graph.ShortestPathsDijkstra(e => 1, _startingLocation);

            pathing(_goal, out var path);


            return(path.Count());
        }
Exemplo n.º 2
0
        object PartTwo(string input)
        {
            var vm            = new IntCode(input);
            var currentPos    = new Point(0, 0);
            var currentStatus = Status.Empty;
            var map           = new Dictionary <Point, Status>();

            map[currentPos] = currentStatus;
            var pointsToCheck = new Stack <Point>();

            pointsToCheck.Push(currentPos);

            var g = new BidirectionalGraph <Point, Edge <Point> >();

            g.AddVertex(currentPos);

            FloodFill(vm, ref currentPos, map, g);

            // Now we've got the complete map. Let's just see how far away all other points are from the system point.
            var systemPoint = map.First(kvp => kvp.Value == Status.System).Key;
            var tryFunc     = g.ShortestPathsDijkstra(e => 1, systemPoint);

            var maxDistance = map.Where(kvp => kvp.Value == Status.Empty)
                              .Select(kvp =>
            {
                tryFunc(kvp.Key, out var p);
                return(p.Count());
            })
                              .Max();

            return(maxDistance);
        }
Exemplo n.º 3
0
        public double GetPathDistanceBetweenStations(string from, string to)
        {
            if (from == to)
            {
                // if wanna look for shortest path from a vertex back to the same vertex
                // i.e. shortest cycle included a given vertex
                // use the Floyd-Warshall algorithm O(V^3)
                var distance = 0.0;
                if (ShortestCycleIncludedAGivenVertex.TryGetDistanceFloydWarshall(_graph, _costs, from, out distance))
                {
                    return distance;
                }

            }
            else // otherwise use Dijkstra
            {
                var edgeCost = AlgorithmExtensions.GetIndexer(_costs);
                var tryGetPath = _graph.ShortestPathsDijkstra(edgeCost, from);
                IEnumerable<Edge<string>> path;
                var isPathExists = tryGetPath(to, out path);
                if (isPathExists)
                {
                    var distance = path.Sum(edgeCost);
                    return distance;
                }
            }

            return -1;
        }
Exemplo n.º 4
0
 /// <summary>
 /// Returns a possible implicit cast chain.
 /// </summary>
 /// <param name="original"></param>
 /// <param name="destinationType"></param>
 /// <returns></returns>
 public IEnumerable <CoercionRule> GetImplicitlyCastChain(System.Type original, System.Type destinationType)
 {
     if (implicitCoercionRules.ContainsVertex(original) && implicitCoercionRules.ShortestPathsDijkstra(t => 1, original)(destinationType, out IEnumerable <TaggedEdge <Type, CoercionRule> > result))
     {
         return(result.Select(e => e.Tag).ToArray());
     }
     return(Enumerable.Empty <CoercionRule>());
 }
Exemplo n.º 5
0
        object PartOne(string input)
        {
            //var vm = new IntCode(input);
            //var currentPos = new Point(0, 0);
            //var currentStatus = Status.Empty;
            //var map = new Dictionary<Point, Status>();
            ////var wayBack = new Dictionary<Point, Direction>();
            //var shortestDistance = new Dictionary<Point, int>();
            //shortestDistance[currentPos] = 0;
            //map[currentPos] = currentStatus;
            //var pointsToCheck = new Stack<Point>();
            //pointsToCheck.Push(currentPos);

            //var g = new QuickGraph.BidirectionalGraph<Point, Edge<Point>>();
            //g.AddVertex(currentPos);

            //FloodFill(vm, currentPos, shortestDistance, map, g);

            //var system = map.First(kvp => kvp.Value == Status.System).Key;
            //return shortestDistance[system];

            var vm            = new IntCode(input);
            var currentPos    = new Point(0, 0);
            var currentStatus = Status.Empty;
            var map           = new Dictionary <Point, Status>();

            map[currentPos] = currentStatus;
            var pointsToCheck = new Stack <Point>();

            pointsToCheck.Push(currentPos);

            var g = new BidirectionalGraph <Point, Edge <Point> >();

            g.AddVertex(currentPos);

            FloodFill(vm, ref currentPos, map, g);

            var systemPoint = map.First(kvp => kvp.Value == Status.System).Key;

            g.ShortestPathsDijkstra(e => 1, new Point(0, 0))(systemPoint, out var path);
            return(path.Count());
        }
Exemplo n.º 6
0
        private IEnumerable <(Point point, char key)> ReachableUncollectedKeys(Point currentPos, BidirectionalGraph <Point, Edge <Point> > graph, Dictionary <Point, char> doors, List <char> ownedKeys, Dictionary <Point, char> keys)
        {
            var tryFunc = graph.ShortestPathsDijkstra(e => 1, currentPos);

            foreach (var point in keys.Where(kvp => !ownedKeys.Contains(kvp.Value)).Select(kvp => kvp.Key))
            {
                if (tryFunc(point, out var edges))
                {
                    var isReachable = true;
                    foreach (var edge in edges)
                    {
                        if (doors.ContainsKey(edge.Target) && !ownedKeys.Contains(doors[edge.Target]))
                        {
                            // Impassable at the moment.
                            isReachable = false;
                            break;
                        }
                    }

                    if (isReachable)
                    {
                        yield return(point, keys[point]);
Exemplo n.º 7
0
        private void MoveTo(Point target, ref Point currentPos, BidirectionalGraph <Point, Edge <Point> > g, IntCode vm, string because)
        {
            if (target == currentPos)
            {
                return;
            }

            var startingPoint = currentPos;
            var tryFunc       = g.ShortestPathsDijkstra(e => 1, currentPos);

            if (!tryFunc(target, out var path))
            {
                throw new Exception($"Unable to find path between {currentPos} and {target}.");
            }

            foreach (var edge in path)
            {
                var direction = edge.Source.GetDirectionTo(edge.Target);
                if (Move(ref currentPos, direction, vm, because) == Status.Wall)
                {
                    throw new Exception("Simulation is wrong somewhere.");
                }
            }
        }
Exemplo n.º 8
0
        public List <string> getShortestPath(string startElem, string endElem)
        {
            List <string> vPath = new List <string>();
            IEnumerable <TaggedEdge <int, int> > computedPath = new List <TaggedEdge <int, int> >();

            try
            {
                Func <TaggedEdge <int, int>, double> edgeCost = e => 1; // constant cost
                if (ElemIDToNodeIDDict.ContainsKey(startElem))
                {
                    int startNode = ElemIDToNodeIDDict[startElem];
                    TryFunc <int, IEnumerable <TaggedEdge <int, int> > > tryGetPaths = biDirGraph.ShortestPathsDijkstra(edgeCost, startNode);

                    if (ElemIDToNodeIDDict.ContainsKey(endElem))
                    {
                        int endNode = ElemIDToNodeIDDict[endElem];
                        if (tryGetPaths(endNode, out computedPath))
                        {
                            foreach (var edge in computedPath)
                            {
                                vPath.Add(edge.Source + " -> " + edge.Target + " : " + edge.Tag);
                            }
                        }
                    }
                    else
                    {
                        // can't find end node entry
                        vPath.Add("Can't find the end node entry in the graph!");
                    }
                }
                else
                {
                    // can't find start node entry
                    vPath.Add("Can't find the start node entry in the graph!");
                }
            }
            catch (SystemException e)
            {
                string excStr = "%%Error - " + e.Message + "\n\t";
                refBimrlCommon.StackPushError(excStr);
                throw;
            }

            return(vPath);
        }
Exemplo n.º 9
0
        public static void Create(List <Node> Nodes, List <Way> Ways)
        {
            //create the graph
            var Graph = new BidirectionalGraph <int, CompEdge>();

            //add each node referenced by a way
            foreach (Way Path in Ways)
            {
                for (int i = 0; i < Path.References.Count; i++)
                {
                    int Id = (int)Path.References[i].Id;

                    // make sure the node was not already added
                    if (!Graph.Vertices.Contains(Id))
                    {
                        Graph.AddVertex(Id);

                        short Altitude = AltitudeMap.AltitudeAtPosition(Path.References[i].Location);

                        NodeAltitudes.Add(Id, (int)Altitude);
                    }
                }
            }


            //create an altitude map
            Bitmap AltitudeImage = new Bitmap(64, 64, System.Drawing.Imaging.PixelFormat.Format24bppRgb);

            List <double> LongitudeGradient = Gradient(Program.LowerBound.Longitude, Program.UpperBound.Longitude, 64);
            List <double> LatitudeGradient  = Gradient(Program.LowerBound.Latitude, Program.UpperBound.Latitude, 64);



            //iterate over altitudes
            for (int longitudeindex = 0; longitudeindex < LongitudeGradient.Count; longitudeindex++)
            {
                for (int latitudeindex = 0; latitudeindex < LatitudeGradient.Count; latitudeindex++)
                {
                    short Altitude = AltitudeMap.AltitudeAtPosition(new GeoCoordinate(LatitudeGradient[latitudeindex], LongitudeGradient[longitudeindex]));

                    AltitudeImage.SetPixel(longitudeindex, latitudeindex, Color.FromArgb(Altitude, Altitude, Altitude));
                }
            }


            // setup the bitmap that all of the data will be saved to
            AltitudeImage.Save("RegionalAltitudeImage.bmp");

            //add each edge
            foreach (Way Path in Ways)
            {
                //add all of the edges
                for (int i = 1; i < Path.References.Count; i++)
                {
                    Node FirstNode  = Path.References[i - 1];
                    Node SecondNode = Path.References[i];

                    //add the edge
                    Graph.AddEdge(new CompEdge((int)FirstNode.Id, (int)SecondNode.Id));
                    Graph.AddEdge(new CompEdge((int)SecondNode.Id, (int)FirstNode.Id));

                    //add the distance edge
                    double Distance = DistanceBetweenPlaces(FirstNode.Location, SecondNode.Location);

                    //add both distances
                    Distances.Add(new CompEdge((int)FirstNode.Id, (int)SecondNode.Id), Distance);
                    Distances.Add(new CompEdge((int)SecondNode.Id, (int)FirstNode.Id), Distance);

                    //get the altitudes
                    double FirstNodeAltitude  = NodeAltitudes[(int)FirstNode.Id];
                    double SecondNodeAltitude = NodeAltitudes[(int)SecondNode.Id];

                    //if we don't know either of the altitudes, assume 0 change
                    if (FirstNodeAltitude != -1 || SecondNodeAltitude != -1)
                    {
                        AltitudeChange.Add(new CompEdge((int)FirstNode.Id, (int)SecondNode.Id), FirstNodeAltitude - SecondNodeAltitude);
                        AltitudeChange.Add(new CompEdge((int)SecondNode.Id, (int)FirstNode.Id), SecondNodeAltitude - FirstNodeAltitude);
                    }
                    else
                    {
                        AltitudeChange.Add(new CompEdge((int)FirstNode.Id, (int)SecondNode.Id), 0);
                        AltitudeChange.Add(new CompEdge((int)SecondNode.Id, (int)FirstNode.Id), 0);
                    }
                }
            }

            //calcuate costs for each edge
            var Costs = new Dictionary <CompEdge, double>();

            //cycle through each edge and calculate its cost
            foreach (Edge <int> Edge in Graph.Edges)
            {
                CompEdge Key = new CompEdge(Edge.Source, Edge.Target);

                double DistanceCost = Distances[Key] * 1000;            //convert to meters
                double AltitudeCost = Math.Pow(AltitudeChange[Key], 2); //square the altitude (in meters)

                double Weight = DistanceCost;
                Costs.Add(Key, Weight);
            }


            //create arrays that the data will be stored in
            string[] NodeLines = new string[Graph.Vertices.Count()];
            string[] EdgeLines = new string[Graph.Edges.Count()];

            //save nodes to a .csv file
            for (int i = 0; i < Graph.Vertices.Count(); i++)
            {
                int Id = Graph.Vertices.ElementAt(i);

                NodeLines[i] = Id + "," + Node.GetById(Id).Location.Latitude + "," + Node.GetById(Id).Location.Longitude;
            }

            //save edges to a .csv file
            for (int i = 0; i < Graph.Edges.Count(); i++)
            {
                int Source = Graph.Edges.ElementAt(i).Source;
                int Target = Graph.Edges.ElementAt(i).Target;

                EdgeLines[i] = Source + "," + Target + "," + Costs[new CompEdge(Source, Target)];
            }

            File.WriteAllLines("nodes.csv", NodeLines);
            File.WriteAllLines("edges.csv", EdgeLines);


            int From = 0;
            int To   = 5;


            var CostIndexer = AlgorithmExtensions.GetIndexer(Costs);
            var tryGetPath  = Graph.ShortestPathsDijkstra(CostIndexer, From);

            IEnumerable <CompEdge> path;

            if (tryGetPath(To, out path))
            {
                string ToWrite = "";

                foreach (CompEdge Edge in path)
                {
                    ToWrite += Convert.ToString(Edge.Source) + ",";
                }

                File.WriteAllText("chosenpath.csv", ToWrite.Remove(ToWrite.Length - 1)); // remove the last comma
            }

            //create a visualizer for the graph
            //GraphvizAlgorithm<int, CompEdge> graphviz = new GraphvizAlgorithm<int, CompEdge>(Graph);
            //string output = "output.dot";
            //graphviz.Generate(new FileDotEngine(), output);

            // assumes dot.exe is on the path:
            //var args = string.Format(@"{0} -Tjpg -O", output);
            //System.Diagnostics.Process.Start(@"C:\Program Files (x86)\Graphviz2.38\bin\dot.exe", args);
        }
Exemplo n.º 10
0
 private int Distance(Point p1, Point p2, BidirectionalGraph <Point, Edge <Point> > graph)
 {
     graph.ShortestPathsDijkstra(e => 1, p1)(p2, out var edges);
     return(edges.Count());
 }