Пример #1
0
        //Time: O(|v|^2)
        //Space: O(V)
        //The main function for doing dijkstra's algorithm and resurning the results.
        public List <double> dijkstras()
        {
            //Console.WriteLine("Inside array dijkstras");
            int max = Int32.MaxValue;

            //We start by adding all values to infinity
            for (int i = 0; i < points.Count; i++)
            {
                //Insert
                //Time: O(1) Beacuse your doing it for one point.
                //Space: O(1) Beacuse your making the queue.
                distance.Add(max);
                previous.Add(max);
                queue.Add(max);
            }
            distance[startIndex] = 0;
            queue[startIndex]    = 0;
            int minIndex = startIndex;
            //to compare and change indexes

            int minusOnes = 0;
            EuclideanDistanceImplementation edi = new EuclideanDistanceImplementation();

            while (minusOnes < queue.Count)
            {
                double minValue = max;
                //Console.WriteLine("minusOnes " + minusOnes);

                //the deleteMin function
                //Time: O(|v|) Because you have to iterate over every point to find the minimum.
                //Space: O(1) Nothing changed.
                for (int i = 0; i < queue.Count; i++)
                {
                    //Console.WriteLine("Dist is " + queue[i]);
                    if (queue[i] != -1 && queue[i] < minValue)
                    {
                        minIndex = i;
                        minValue = queue[i];
                        //Console.WriteLine("min index is " + i + " of " + queue[i]);
                    }
                }
                //Console.WriteLine("The current min Index is " + minIndex);
                //previous.Add(points[minIndex]);
                queue[minIndex] = -1;//set the value to -1 to take it out, basically

                //update the distances of each of this node's directed edges. O(3)
                for (int i = 0; i < adjacencyList[minIndex].Count; i++)
                {
                    int currAdj = adjacencyList[minIndex].ElementAt(i);
                    //Console.WriteLine("currAdj is " + currAdj + " of " + adjacencyList[minIndex]);
                    double dist = edi.calculate(points[minIndex], points[currAdj]);
                    //Console.WriteLine("dist path of " + currAdj +"  is " + distance[currAdj] + " versus " + (distance[minIndex] + dist));
                    if (distance[currAdj] > distance[minIndex] + dist)
                    {
                        distance[currAdj] = distance[minIndex] + dist;
                        //Console.WriteLine("Add " + currAdj + " from point " + minIndex);
                        //previous.Add(minIndex);
                        previous[currAdj] = minIndex;

                        //decreaseKey
                        //Time: O(1) Because you can directly access the index.
                        //Space: O(1) Because you change only one thing.
                        queue[currAdj] = distance[currAdj];
                    }
                }
                minusOnes++;
            }

            previous.Add(endIndex);
            return(previous);
        }
Пример #2
0
        private void solveButton_Clicked()
        {
            // *** Implement this method, use the variables "startNodeIndex" and "stopNodeIndex" as the indices for your start and stop points, respectively ***

            //Here we define the data objects we'll be using
            String s          = sourceNodeBox.Text;
            int    startIndex = Int32.Parse(s);

            s = targetNodeBox.Text;
            int endIndex = Int32.Parse(s);
            EuclideanDistanceImplementation edi = new EuclideanDistanceImplementation();
            Font     arialFont     = new Font("Arial", 11);
            Pen      p             = new Pen(Color.Black, 1);
            double   totalDistance = 0;
            DateTime startTime;
            double   arrayTime = 0;
            double   heapTime  = 0;
            double   elapsedMillisecondsTime = 0;

            if (arrayCheckBox.Checked == true)
            {
                //start the timer
                startTime = DateTime.Now;

                //compute dijkstra's algorithm with the data we have.
                ArrayImplementation ai       = new ArrayImplementation(startIndex, endIndex, points, adjacencyList);
                List <double>       previous = ai.dijkstras();//returns previous with all the indexes till the endIndex.

                int currIndex = endIndex;

                //Draw the shortest path with the costs backwards
                //Time: O(|v|) Because you may have to draw each point at worst.
                //Space: O(1) Beacuse you only change one point.
                while (currIndex != startIndex)
                {
                    //Console.WriteLine("Here");
                    //Console.WriteLine("Prev " + previous.ElementAt(currIndex));
                    //make sure that we can actually reach this thing
                    if (previous.ElementAt(currIndex) == 2147483647)
                    {
                        this.pathCostBox.Text = "unreachable";
                        return;
                    }

                    //draw the line
                    graphics.DrawLine(p, points[currIndex], points[(int)previous.ElementAt(currIndex)]);

                    //get and display length for every line drawn
                    double dist = edi.calculate(points[currIndex], points[(int)previous.ElementAt(currIndex)]);
                    totalDistance = totalDistance + dist;
                    string str = Convert.ToString((int)dist);

                    //calculation for the slope of the line and put it in the middle
                    RectangleF rectf = new RectangleF(70, 90, 80, 80);//x, y, width, height
                    rectf.X = Math.Abs(points[(int)previous.ElementAt(currIndex)].X + points[currIndex].X) / 2;
                    rectf.Y = Math.Abs(points[(int)previous.ElementAt(currIndex)].Y + points[currIndex].Y) / 2;
                    graphics.DrawString(str, arialFont, Brushes.Black, rectf);
                    currIndex = (int)previous.ElementAt(currIndex);

                    //Stop the timer and write the values to the forms
                    this.pathCostBox.Text   = Convert.ToString(totalDistance);
                    elapsedMillisecondsTime = (DateTime.Now - startTime).TotalMilliseconds;
                    arrayTime = elapsedMillisecondsTime / 10000;
                    this.arrayTimeBox.Text = Convert.ToString(arrayTime);
                }
            }


            //Now do the same thing with a Heap
            //O(log |v|))
            //start the timer
            startTime = DateTime.Now;

            HeapImplementation heapQueue = new HeapImplementation(points.Count);
            //ArrayQueue
            List <double> dist1 = new List <double>();
            List <int>    prev1 = new List <int>();
            List <double> dist2 = new List <double>();
            List <int>    prev2 = new List <int>();

            totalDistance = 0;

            for (int u = 0; u < points.Count; u++)
            {
                dist1.Add(Int16.MaxValue);
                prev1.Add(-1);
                dist2.Add(Int16.MaxValue);
                prev2.Add(-1);
            }
            dist1[startNodeIndex] = 0;
            dist2[startNodeIndex] = 0;

            //Heap implementation
            for (int u = 0; u < dist2.Count; u++)
            {
                Node node = new Node(u);
                heapQueue.Add(node, dist2[u]);
            }

            while (heapQueue.count > 0)
            {
                Node min = heapQueue.ExtractMin();
                foreach (int adj in adjacencyList[min.pointsIndex])
                {
                    double newDistance = dist2[min.pointsIndex] + edi.getMagnitude(min, adj, points);
                    if (dist2[adj] > newDistance)
                    {
                        dist2[adj] = newDistance;
                        prev2[adj] = min.pointsIndex;
                        heapQueue.DecreasePriority(adj, newDistance);
                    }
                }
            }

            //Draw the shortest path with the costs backwards
            //Time: O(|v|) Because you may have to draw each point at worst.
            //Space: O(1) Beacuse you only change one point.
            int currIndexToDraw = stopNodeIndex;

            while (currIndexToDraw != startNodeIndex)
            {
                int prevIndex = prev2[currIndexToDraw];

                //Console.WriteLine("Here");
                //Console.WriteLine("Prev " + points[currIndexToDraw]);
                //make sure that we can actually reach this thing
                if (prevIndex > points.Count - 1 || prevIndex < 0)
                {
                    this.pathCostBox.Text = "unreachable";
                    return;
                }

                graphics.DrawLine(p, points[currIndexToDraw], points[prevIndex]);

                double currDistance = edi.calculate(points[prevIndex], points[currIndexToDraw]);
                totalDistance += currDistance;

                String     text       = Convert.ToString((int)currDistance);
                RectangleF drawingBox = new RectangleF(Math.Abs(points[prevIndex].X + points[currIndexToDraw].X) / 2,
                                                       Math.Abs(points[prevIndex].Y + points[currIndexToDraw].Y) / 2, 80, 80);
                graphics.DrawString(text, new Font("Arial", 11), Brushes.Black, drawingBox);

                currIndexToDraw = prev2[currIndexToDraw];
            }
            this.pathCostBox.Text = Convert.ToString(totalDistance);

            //Now set the time it takes for all this to happen
            elapsedMillisecondsTime = (DateTime.Now - startTime).TotalMilliseconds;
            heapTime = elapsedMillisecondsTime / 10000;
            this.heapTimeBox.Text = Convert.ToString(heapTime);
            if (arrayCheckBox.Checked == true)
            {
                this.differenceBox.Text = Convert.ToString(arrayTime / heapTime);
            }
        }