void AssembleChildren(SolarixGrammarEngineNET.SyntaxTreeNode root, List <NodeDistance> children, int distance)
    {
        foreach (SolarixGrammarEngineNET.SyntaxTreeNode subnode in root.leafs)
        {
            NodeDistance n = new NodeDistance();
            n.distance = distance;
            n.token    = subnode;
            children.Add(n);
            AssembleChildren(subnode, children, distance + 1);
        }

        return;
    }
    void FillDistanceMatrix(SolarixGrammarEngineNET.SyntaxTreeNode node)
    {
        List <List <NodeDistance> > node_clouds = new List <List <NodeDistance> >();

        foreach (SolarixGrammarEngineNET.SyntaxTreeNode subnode in node.leafs)
        {
            List <NodeDistance> d = new List <NodeDistance>();

            NodeDistance n = new NodeDistance();
            n.token    = subnode;
            n.distance = 1;
            d.Add(n);

            AssembleChildren(subnode, d, 2);
            node_clouds.Add(d);

            foreach (NodeDistance nn in d)
            {
                AddDistance(node, nn.token, nn.distance);
            }
        }

        for (int i = 0; i < node_clouds.Count() - 1; ++i)
        {
            for (int j = i + 1; j < node_clouds.Count(); ++j)
            {
                List <NodeDistance> cloud1 = node_clouds[i];
                List <NodeDistance> cloud2 = node_clouds[j];

                foreach (NodeDistance d1 in cloud1)
                {
                    foreach (NodeDistance d2 in cloud2)
                    {
                        AddDistance(d1.token, d2.token, d1.distance + d2.distance);
                    }
                }
            }
        }

        foreach (SolarixGrammarEngineNET.SyntaxTreeNode subnode in node.leafs)
        {
            FillDistanceMatrix(subnode);
        }

        return;
    }
    public int CompareTo(object obj)
    {
        if (obj == null)
        {
            return(1);
        }

        NodeDistance other = obj as NodeDistance;

        if (other != null)
        {
            return(this.distance.CompareTo(other.distance));
        }
        else
        {
            throw new ArgumentException("Object is not valid");
        }
    }
    private static void Main()
    {
        string[] inputs = Console.ReadLine().Split(' ');
        int      starty = int.Parse(inputs[0]);
        int      startx = int.Parse(inputs[1]);

        inputs = Console.ReadLine().Split(' ');
        int endy = int.Parse(inputs[0]);
        int endx = int.Parse(inputs[1]);

        inputs = Console.ReadLine().Split(' ');
        int h = int.Parse(inputs[0]);
        int w = int.Parse(inputs[1]);

        var m = new Map();

        for (int mY = 0; mY < h; mY++)
        {
            var line = Console.ReadLine().ToCharArray();
            for (int mX = 0; mX < w; mX++)
            {
                if (line[mX] == '#')
                {
                    continue;
                }
                if (line[mX] == '.')
                {
                    Node n = new Node(new Point(mX, mY), ".");
                    m.Nodes.Add(n);
                    var northernNode =
                        m.Nodes.Find(
                            x =>
                            x.Coordinate.X == mX && x.Coordinate.Y == mY - 1 &&
                            new List <string> {
                        "|", "."
                    }.Contains(x.Type));
                    if (northernNode != null)
                    {
                        var l = new Link(n, northernNode);
                        n.Links.Add(l);
                        northernNode.Links.Add(l);
                        n.Neighbors.Add(northernNode);
                        northernNode.Neighbors.Add(n);
                    }

                    Node westernNode =
                        m.Nodes.Find(
                            x =>
                            x.Coordinate.X == mX - 1 && x.Coordinate.Y == mY &&
                            new List <string> {
                        "-", "."
                    }.Contains(x.Type));
                    if (westernNode != null)
                    {
                        var l = new Link(n, westernNode);
                        n.Links.Add(l);
                        westernNode.Links.Add(l);
                        n.Neighbors.Add(westernNode);
                        westernNode.Neighbors.Add(n);
                    }
                }
                else if (line[mX] == '+')
                {
                    Node n = new Node(new Point(mX, mY), "+");
                    m.Nodes.Add(n);
                    var northernNode =
                        m.Nodes.Find(
                            x =>
                            x.Coordinate.X == mX && x.Coordinate.Y == mY - 1 &&
                            new List <string> {
                        "|", "+", "X"
                    }.Contains(x.Type));
                    if (northernNode != null)
                    {
                        var l = new Link(n, northernNode);
                        n.Links.Add(l);
                        northernNode.Links.Add(l);
                        n.Neighbors.Add(northernNode);
                        northernNode.Neighbors.Add(n);
                    }

                    Node westernNode =
                        m.Nodes.Find(
                            x =>
                            x.Coordinate.X == mX - 1 && x.Coordinate.Y == mY &&
                            new List <string> {
                        "-", "+", "X"
                    }.Contains(x.Type));
                    if (westernNode != null)
                    {
                        var l = new Link(n, westernNode);
                        n.Links.Add(l);
                        westernNode.Links.Add(l);
                        n.Neighbors.Add(westernNode);
                        westernNode.Neighbors.Add(n);
                    }
                }
                else if (line[mX] == '|')
                {
                    Node n = new Node(new Point(mX, mY), "|");
                    m.Nodes.Add(n);
                    var northernNode =
                        m.Nodes.Find(
                            x =>
                            x.Coordinate.X == mX && x.Coordinate.Y == mY - 1 &&
                            new List <string> {
                        ".", "+"
                    }.Contains(x.Type));
                    if (northernNode != null)
                    {
                        var l = new Link(n, northernNode);
                        n.Links.Add(l);
                        northernNode.Links.Add(l);
                        n.Neighbors.Add(northernNode);
                        northernNode.Neighbors.Add(n);
                    }
                }
                else if (line[mX] == '-')
                {
                    Node n = new Node(new Point(mX, mY), "-");
                    m.Nodes.Add(n);

                    Node westernNode =
                        m.Nodes.Find(
                            x =>
                            x.Coordinate.X == mX - 1 && x.Coordinate.Y == mY &&
                            new List <string> {
                        "+", "."
                    }.Contains(x.Type));
                    if (westernNode != null)
                    {
                        var l = new Link(n, westernNode);
                        n.Links.Add(l);
                        westernNode.Links.Add(l);
                        n.Neighbors.Add(westernNode);
                        westernNode.Neighbors.Add(n);
                    }
                }
                else if (line[mX] == 'X')
                {
                    Node n1 = new Node(new Point(mX, mY), "X");
                    m.Nodes.Add(n1);
                    var northernNode =
                        m.Nodes.Find(
                            x =>
                            x.Coordinate.X == mX && x.Coordinate.Y == mY - 1 &&
                            new List <string> {
                        "+", "X"
                    }.Contains(x.Type));
                    if (northernNode != null)
                    {
                        var l = new Link(n1, northernNode);
                        n1.Links.Add(l);
                        northernNode.Links.Add(l);
                        n1.Neighbors.Add(northernNode);
                        northernNode.Neighbors.Add(n1);
                    }

                    Node westernNode =
                        m.Nodes.Find(
                            x =>
                            x.Coordinate.X == mX - 1 && x.Coordinate.Y == mY &&
                            new List <string> {
                        "+", "X"
                    }.Contains(x.Type));
                    if (westernNode != null)
                    {
                        var l = new Link(n1, westernNode);
                        n1.Links.Add(l);
                        westernNode.Links.Add(l);
                        n1.Neighbors.Add(westernNode);
                        westernNode.Neighbors.Add(n1);
                    }

                    Node n2 = new Node(new Point(mX, mY), ".");
                    m.Nodes.Add(n2);
                    northernNode =
                        m.Nodes.Find(
                            x =>
                            x.Coordinate.X == mX && x.Coordinate.Y == mY - 1 &&
                            new List <string> {
                        "."
                    }.Contains(x.Type));
                    if (northernNode != null)
                    {
                        var l = new Link(n2, northernNode);
                        n2.Links.Add(l);
                        northernNode.Links.Add(l);
                        n2.Neighbors.Add(northernNode);
                        northernNode.Neighbors.Add(n2);
                    }

                    westernNode =
                        m.Nodes.Find(
                            x =>
                            x.Coordinate.X == mX - 1 && x.Coordinate.Y == mY &&
                            new List <string> {
                        "."
                    }.Contains(x.Type));
                    if (westernNode != null)
                    {
                        var l = new Link(n2, westernNode);
                        n2.Links.Add(l);
                        westernNode.Links.Add(l);
                        n2.Neighbors.Add(westernNode);
                        westernNode.Neighbors.Add(n2);
                    }
                }
            }
        }

        BreadthFirstSearch breadthFirstSearch = new BreadthFirstSearch();

        breadthFirstSearch.CalculateDistances(m.Nodes.Find(x => x.Coordinate.X == startx && x.Coordinate.Y == starty));
        NodeDistance exitNode = breadthFirstSearch.NodeDistances.First(x => x.Node.Coordinate.X == endx && x.Node.Coordinate.Y == endy);

        Console.WriteLine(exitNode.Distance);
    }
Beispiel #5
0
 public void Enqueue(NodeDistance nd)
 {
     list.Add(nd);
 }
Beispiel #6
0
    public static void ShortestPath(SqlInt64 startNode, SqlInt64 endNode, SqlInt32 maxNodesToCheck, out SqlString pathResult, out SqlDouble distResult)
    {
        Dictionary <long, double> distance  = new Dictionary <long, double>(); // curr shortest distance (double) from startNode to (key) node
        Dictionary <long, long>   previous  = new Dictionary <long, long>();   // predecessor values to construct the actual path when done
        Dictionary <long, bool>   beenAdded = new Dictionary <long, bool>();   // has node been added to the queue yet? Once added, we don't want to add again

        long startNodeAsLong      = (long)startNode;
        long endNodeAsLong        = (long)endNode;
        int  maxNodesToCheckAsInt = (int)maxNodesToCheck;

        MyPriorityQueue PQ = new MyPriorityQueue();

        //initialize start node
        distance[startNodeAsLong] = 0.0;                    // distance from start node to itself is 0
        previous[startNodeAsLong] = -1;                     // -1 is the code for undefined.
        PQ.Enqueue(new NodeDistance(startNodeAsLong, 0.0)); // the queue holds distance information because Enqueue and Dequeue need it to keep queue ordered by priority. alt approach would be to store only node IDs and then do a distance lookup
        beenAdded[startNodeAsLong] = true;

        double alt = 0.0; //'test distance'

        try
        {
            while (PQ.Count() > 0 && beenAdded.Count < maxNodesToCheckAsInt)
            {
                NodeDistance u = PQ.Dequeue();// node with shortest distance from start
                if (u.nodeID == endNode)
                {
                    break;// found the target end node
                }
                //fetch all neighbors (v) of u

                List <Tuple <long, double> > neighbors = new List <Tuple <long, double> >();
                neighbors = FetchNeighbors(u.nodeID);


                foreach (var v in neighbors)                                    // if there are no neighbors, this loop will exit immediately
                {
                    if (beenAdded.ContainsKey(v.Item1) == false)                //first appearance of node v
                    {
                        distance[v.Item1] = double.MaxValue;                    //stand-in for infinity
                        previous[v.Item1] = -1;                                 //undefined
                        PQ.Enqueue(new NodeDistance(v.Item1, double.MaxValue)); //maxValue is a dummy value
                        beenAdded[v.Item1] = true;
                    }

                    //alt = distance[u.nodeID] + 1.0;  // if all edge weights are just hops can simplify to this
                    alt = distance[u.nodeID] + v.Item2; // alt = dist(start-to-u) + dist(u-to-v), so alt is total distance from start to v

                    if (alt < distance[v.Item1])        // is alt a new, shorter distance from start to v?
                    {
                        distance[v.Item1] = alt;
                        previous[v.Item1] = u.nodeID;
                        PQ.ChangePriority(v.Item1, alt);  // this will change the distance/priority
                    }
                }
            }

            // extract the shortest path as a string from the previous[] array
            pathResult = "NOTREACHABLE";                     // default result string
            distResult = -1.0;                               // distance result defaults to -1 == unreachable

            if (distance.ContainsKey(endNodeAsLong) == true) // endNode was encountered at some point in the algorithm
            {
                double sp = distance[endNodeAsLong];         // shortest path distance
                if (sp != double.MaxValue)                   // we have a reachable path
                {
                    pathResult = "";
                    long currNode = endNodeAsLong;
                    while (currNode != startNodeAsLong)  // construct the path as  semicolon delimited string
                    {
                        pathResult += currNode.ToString() + ";";
                        currNode    = previous[currNode];
                    }
                    pathResult += startNode.ToString();   // tack on the start node
                    distResult  = sp;                     // the distance result
                }
            }
        }
        catch (Exception ex) // typically Out Of Memory or a Command TimeOut
        {
            pathResult = ex.ToString();
            distResult = -1.0;
        }
    }