コード例 #1
0
        /// <summary>
        /// Computes all shortest distance between any vertices in a given graph.
        /// </summary>
        /// <param name="adjacence_matrix">Square adjacence matrix. The main diagonal
        /// is expected to consist of zeros, any non-existing edges should be marked
        /// positive infinity.</param>
        /// <returns>Two matrices D and P, where D[u,v] holds the distance of the shortest
        /// path between u and v, and P[u,v] holds the shortcut vertex on the way from
        /// u to v.</returns>
        public static Matrix[] Floyd(Matrix adjacence_matrix)
        {
            if (!adjacence_matrix.IsSquare())
                throw new ArgumentException("Expected square matrix.");
            else if (!adjacence_matrix.IsReal())
                throw new ArgumentException("Adjacence matrices are expected to be real.");

            int n = adjacence_matrix.RowCount;

            Matrix D = adjacence_matrix.Clone(); // distance matrix
            Matrix P = new Matrix(n);

            double buf;

            for (int k = 1; k <= n; k++)
                for (int i = 1; i <= n; i++)
                    for (int j = 1; j <= n; j++)
                    {
                        buf = D[i, k].Re + D[k, j].Re;
                        if (buf < D[i, j].Re)
                        {
                            D[i, j].Re = buf;
                            P[i, j].Re = k;
                        }
                    }

            return new Matrix[] { D, P };
        }
コード例 #2
0
        /// <summary>
        /// Returns the shortest path between two given vertices i and j as
        /// int array.
        /// </summary>
        /// <param name="P">Path matrix as returned from Floyd().</param>
        /// <param name="i">One-based index of start vertex.</param>
        /// <param name="j">One-based index of end vertex.</param>
        /// <returns></returns>
        public static ArrayList FloydPath(Matrix P, int i, int j)
        {
            if (!P.IsSquare())
                throw new ArgumentException("Path matrix must be square.");
            else if (!P.IsReal())
                throw new ArgumentException("Adjacence matrices are expected to be real.");

            ArrayList path = new ArrayList();
            path.Add(i);

            //int borderliner = 0;
            //int n = P.Size()[0] + 1; // shortest path cannot have more than n vertices!

            while (P[i, j] != 0)
            {
                i = Convert.ToInt32(P[i, j]);
                path.Add(i);

                //borderliner++;

                //if (borderliner == n)
                //    throw new FormatException("P was not a Floyd path matrix.");
            }

            path.Add(j);

            return path;
        }
コード例 #3
0
        /// <summary>
        /// Performs depth-first search for a graph given by its adjacence matrix.
        /// </summary>
        /// <param name="adjacence_matrix">A[i,j] = 0 or +infty, if there is no edge from i to j; any non-zero value otherwise.</param>
        /// <param name="root">The vertex to begin the search.</param>
        /// <returns>Adjacence matrix of the computed spanning tree.</returns>
        public static Matrix DFS(Matrix adjacence_matrix, int root)
        {
            if (!adjacence_matrix.IsSquare())
                throw new ArgumentException("Adjacence matrices are expected to be square.");
            else if (!adjacence_matrix.IsReal())
                throw new ArgumentException("Adjacence matrices are expected to be real.");

            int n = adjacence_matrix.RowCount;

            if (root < 1 || root > n)
                throw new ArgumentException("Root must be a vertex of the graph, e.i. in {1, ..., n}.");

            Matrix spanTree = new Matrix(n);

            bool[] marked = new bool[n + 1];

            Stack todo = new Stack();
            todo.Push(root);
            marked[root] = true;

            // adajacence lists for each vertex
            ArrayList[] A = new ArrayList[n + 1];

            for (int i = 1; i <= n; i++)
            {
                A[i] = new ArrayList();

                for (int j = 1; j <= n; j++)
                    if (adjacence_matrix[i, j].Re != 0 && adjacence_matrix[i, j].Im != double.PositiveInfinity)
                        A[i].Add(j);
            }

            int v, w;

            while (todo.Count > 0)
            {
                v = (int)todo.Peek();

                if (A[v].Count > 0)
                {
                    w = (int)A[v][0];

                    if (!marked[w])
                    {
                        marked[w] = true; // mark w
                        spanTree[v, w].Re = 1; // mark vw
                        todo.Push(w); // one more to search
                    }

                    A[v].RemoveAt(0);
                }
                else
                    todo.Pop();
            }

            return spanTree;
        }