예제 #1
0
        public List <int> dijkstra(int xf, int yf, int xt, int yt)    //col , row ->> source , destination
        {
            // Data holders
            double inf = helper.infinty();

            int []         path = new int[size + 2];
            double []      dis  = new double[size + 2];
            Priority_Queue q    = new Priority_Queue(10);
            int            node = helper.flatten(xf, yf, width); // col , row
            int            to   = helper.flatten(xt, yt, width); //col , row

            //initialize
            for (int i = 0; i <= size; i++)
            {
                dis[i] = inf;
            }
            dis[node]  = 0;
            path[node] = -1;
            q.insert(node, 0);

            while (!q.empty())
            {
                // pick clossest
                node = q.top().id;
                double dnode = q.top().w;
                // delete
                q.pop();
                pixel tmp_pixel = helper.un_flatten(node, width);
                // update the node that I relax from
                xf = tmp_pixel.y; // col
                yf = tmp_pixel.x; // row

                if (node == to)
                {
                    break;
                }
                if (dis[node] < dnode)
                {
                    continue;
                }

                List <Tuple <int, double> > neighbours = new List <Tuple <int, double> >();

                // build neghbours  4 connectivity
                Vector2D v = ImageOperations.CalculatePixelEnergies(xf, yf, MainForm.ImageMatrix);
                int      tmp_id;              // hold my child that I will add
                double   w;
                if (helper.valid(xf, yf + 1)) // bellow
                {
                    w      = v.Y;
                    w      = (double)1 / w;
                    w      = helper.remove_infinty(w);
                    tmp_id = helper.flatten(xf, yf + 1, width);
                    neighbours.Add(Tuple.Create(tmp_id, w));
                }
                if (helper.valid(xf + 1, yf))  // to the right
                {
                    w      = v.X;
                    w      = (double)1 / w;
                    w      = helper.remove_infinty(w);
                    tmp_id = helper.flatten(xf + 1, yf, width);
                    neighbours.Add(Tuple.Create(tmp_id, w));
                }
                if (helper.valid(xf, yf - 1))  // above me
                {
                    v      = ImageOperations.CalculatePixelEnergies(xf, yf - 1, MainForm.ImageMatrix);
                    w      = v.Y;
                    w      = (double)1 / w;
                    w      = helper.remove_infinty(w);
                    tmp_id = helper.flatten(xf, yf - 1, width);
                    neighbours.Add(Tuple.Create(tmp_id, w));
                }
                if (helper.valid(xf - 1, yf)) // to the left
                {
                    v      = ImageOperations.CalculatePixelEnergies(xf - 1, yf, MainForm.ImageMatrix);
                    w      = v.X;           // energy
                    w      = (double)1 / w; // weight
                    w      = helper.remove_infinty(w);
                    tmp_id = helper.flatten(xf - 1, yf, width);
                    neighbours.Add(Tuple.Create(tmp_id, w));
                }

                // relax
                for (int i = 0; i < neighbours.Count; i++)
                {
                    int    child = neighbours[i].Item1;
                    double cost  = neighbours[i].Item2;
                    if (dis[child] > dnode + cost)
                    {
                        dis[child]  = dnode + cost;
                        path[child] = node; // your current parent
                        q.insert(child, dis[child]);
                    }
                }
            }

            // build the path  ,   we are always sure that we will reach our distination
            List <int> shp = new List <int>();

            shp.Add(to);
            while (path[to] != -1)
            {
                shp.Add(path[to]);
                to = path[to];
            }
            shp.Reverse();
            return(shp);
        }
예제 #2
0
        /*
         * shortest path algorithm ->>> Dijkstra
         * scource is -> current_anchor_point
         * destination is -> free_point
         *
         * we will use our p_q_min_heap as DS for selecting the clossest node
         */

        public List <int> dijkstra(int f, int to)
        {
            // infinity
            double inf = helper.infinty();

            Priority_Queue q    = new Priority_Queue(10); // size is number of nodes in the graph
            int            node = f;
            int            dist = to;

            double[] distance = new double[size + 2];
            int[]    path     = new int[size + 2];

            // initialize
            for (int i = 0; i < size; i++)
            {
                distance[i] = inf;
            }
            distance[node] = 0;
            path[node]     = -1; // no parent
            q.insert(node, 0);
            // end
            while (!q.empty())
            {
                // pick clossest  node
                node = q.top().id;
                double dnode = q.top().w;
                // delete
                q.pop();

                // prunning
                if (node == dist)
                {
                    break;
                }
                if (dnode > distance[node])
                {
                    continue;
                }

                // relax
                for (int i = 0; i < g[node].Count; i++)
                {
                    int    child = g[node][i].Item1;
                    double cost  = g[node][i].Item2;
                    if (distance[child] > dnode + cost)
                    {
                        distance[child] = dnode + cost;
                        path[child]     = node;
                        q.insert(child, distance[child]);
                    }
                }
            }

            /*
             * construct the path
             * order of the path don't matter
             * cut it just draw throw them
             */

            List <int> l = new List <int>();

            l.Add(dist);
            int tid = dist;

            while (path[tid] != -1)
            {
                l.Add(path[tid]);
                tid = path[tid]; // go back
            }
            //l.Reverse();
            return(l);
        }