示例#1
0
        /// <summary>
        /// Tworzy Liste wszystkich spojnych skladowych
        /// </summary>
        /// <param name="f">graf</param>
        /// <returns>lista spojnych</returns>
        public static List <List <int> > spojne(DirectedGraphMatrix f)
        {
            List <int> stark = new List <int>();

            bool[] visited = new bool[f.NodesNr];
            visited[0] = true;
            DirectedGraphList q = Converter.ConvertToSList(f);

            for (int i = 0; i < f.NodesNr; i++)
            {
                rek(q, i, stark, visited);
            }
            q = Converter.ConvertToSList(transpose(f));
            stark.Reverse();
            //tworzyc listy spojnosci OK
            List <List <int> > lista = new List <List <int> >();

            lista.Add(new List <int>());
            int ind = 0;

            bool[] visited2 = new bool[f.NodesNr];
            for (int i = 0; i < f.NodesNr; i++)
            {
                rek2(q, i, stark, visited2, lista, ref ind);
            }
            lista.Remove(lista[ind]);
            return(lista);
        }
示例#2
0
        private static void topologicSorting(DirectedGraphMatrix originalGraph, List <int> retList, List <int> Done)
        {
            DirectedGraphMatrix graph = new DirectedGraphMatrix(1);

            graph.Set(originalGraph);

            while (retList.Count != originalGraph.NodesNr)
            {
                //find node with 0 dim
                for (int i = 0; i < graph.NodesNr; ++i)
                {
                    if (Done.Contains(i))
                    {
                        continue;
                    }

                    var neighbours = graph.GetNeighbours(i);

                    if (neighbours.Count == 0)
                    {
                        //remove this node
                        retList.Add(i);
                        Done.Add(i);
                        foreach (var node in graph.GetConnectedToNodes(i))
                        {
                            graph.RemoveConnection(node, i);
                        }
                    }
                }
            }
        }
示例#3
0
        /// <summary>
        /// Szukanie cykli na grafie
        /// </summary>
        /// <param name="f">graf</param>
        /// <returns>Lista cykli(lista)</returns>
        public static List <List <int> > circuts(DirectedGraphMatrix f)
        {
            DirectedGraphList  li    = Converter.ConvertToSList(f);
            List <List <int> > cycle = new List <List <int> >();
            List <int>         white = new List <int>();

            for (int i = 0; i < f.NodesNr; i++)
            {
                white.Add(i);
            }
            List <int> grey  = new List <int>();
            List <int> black = new List <int>();
            List <int> temp  = new List <int>();

            for (int i = 0; i < li.NodesNr; i++)
            {
                rekc(li, white, grey, black, cycle, temp, i);
            }
            //formatowanie listy !!!
            for (int i = 0; i < cycle.Count; i++)
            {
                while (cycle[i][0] != cycle[i][cycle[i].Count - 1])
                {
                    cycle[i].Remove(cycle[i][0]);
                }
            }
            return(cycle);
        }
示例#4
0
        /// <summary>
        /// Tworzy graf skierowany na podstawie spójnego grafu nieskierowanego
        /// </summary>
        /// <param name="matrix">Spójny graf nieskierowany</param>
        /// <returns>Graf skierowany</returns>
        public static DirectedGraphMatrix CreateDirectional(GraphMatrix matrix)
        {
            Random r = new Random();
            DirectedGraphMatrix directedMatrix = new DirectedGraphMatrix(matrix.NodesNr);

            for (int i = 0; i < matrix.NodesNr; i++)
            {
                for (int j = 0; j <= i; j++)
                {
                    if (matrix.GetConnection(i, j))
                    {
                        switch (r.Next(3))
                        {
                        case 0:
                            directedMatrix.MakeConnection(i, j);
                            break;

                        case 1:
                            directedMatrix.MakeConnection(j, i);
                            break;

                        case 2:
                            directedMatrix.MakeConnection(i, j);
                            directedMatrix.MakeConnection(j, i);
                            break;
                        }
                    }
                }
            }
            return(directedMatrix);
        }
示例#5
0
        public static List <int> TopologicSorting(DirectedGraphMatrix Graph)
        {
            List <int> topologicList = new List <int>();
            List <int> done          = new List <int>();

            topologicSorting(Graph, topologicList, done);

            return(topologicList);
        }
示例#6
0
        /// <summary>
        /// Wyznacza wage polaczenia
        /// przydatne do Bellmana forda
        /// </summary>
        /// <param name="g">graf</param>
        /// <param name="list">sciezka z elementem poczatkowym /reszta/ koniec</param>
        /// <returns></returns>
        public static int pathWeight(DirectedGraphMatrix g, List <int> list)
        {
            int sum = 0;

            for (int i = 0; i < list.Count - 1; i++)
            {
                sum += g.getWeight(list[i], list[i + 1]);
                //Console.Write(list[i] + "->" + list[i + 1] + ":" + g.getWeight(list[i], list[i + 1]) + ";  ");
            }
            //Console.WriteLine();
            return(sum);
        }
示例#7
0
文件: MaxFlow1.cs 项目: shoter/Graphs
        public MaxFlow1(DirectedGraphMatrix g)
        {
            int nodes = g.NodesNr;

            FlowMatrix   = new int[nodes, nodes];
            weightMatrix = new int[nodes, nodes];
            for (int i = 0; i < nodes; ++i)
            {
                for (int j = 0; j < nodes; ++j)
                {
                    weightMatrix[i, j] = g.getWeight(i, j);
                }
            }
        }
示例#8
0
        public DirectedWindow()
        {
            InitializeComponent();

            Graph = GraphGenerator.CreateDirectional(GraphGenerator.generatorGER(10, 11));

            Renderer = new DirectionalGraphRenderer(Graph, GraphControl, VM);

            Graph.OnChange                   += onGraphChange;
            GraphControl.OnLineClick         += createWeight;
            GraphControl.OnTwoNodeClickEvent += ConnectTwoNodes;
            Graph.OnChange();

            DataContext = VM;
        }
示例#9
0
        /// <summary>
        /// Implementacja algorytmu Floyda-Warshalla
        /// </summary>
        /// <param name="g"></param> Graf ktory jest spojny. Ten algorytm dziala takze dla grafow niespojnych w przeciwienstwie do johnsona
        /// <returns></returns> Macierz odleglosci miedzy wszystkimi wierzcholkami
        public static int[,] FloydWarshall(DirectedGraphMatrix graph)
        {
            int nodes = graph.NodesNr;

            int[,] distances = new int[nodes, nodes];
            int       w   = 0;
            const int INF = int.MaxValue - 10000;

            for (int i = 0; i < nodes; ++i)
            {
                for (int j = 0; j < nodes; ++j)
                {
                    distances[i, j] = INF;
                    if (graph.GetConnection(i, j))
                    {
                        distances[i, j] = graph.getWeight(i, j);
                    }
                }
                distances[i, i] = 0;
            }

            for (int k = 0; k < nodes; ++k)
            {
                for (int i = 0; i < nodes; ++i)
                {
                    for (int j = 0; j < nodes; ++j)
                    {
                        if (k == i || k == j || i == j)
                        {
                            continue;
                        }
                        if ((distances[i, k] == INF) || (distances[k, j] == INF))
                        {
                            continue;
                        }
                        w = distances[i, k] + distances[k, j];
                        if (distances[i, j] > w)
                        {
                            distances[i, j] = w;
                        }
                    }
                }
            }

            return(distances);
        }
示例#10
0
        /// SKIEROWANE KONWERSJE

        public static DirectedGraphMatrix ConvertToSMatrix(DirectedGraphMatrixInc from)
        {
            DirectedGraphMatrix x = new DirectedGraphMatrix(from.NodesNr);

            for (int i = 0; i < from.NodesNr; i++)
            {
                for (int j = 0; j < from.NodesNr; j++)
                {
                    if (from.GetConnection(i, j))
                    {
                        x.MakeConnection(i, j);
                    }
                    x.setWeight(i, j, from.getWeight(i, j));
                }
            }
            return(x);
        }
示例#11
0
        public static DirectedGraphMatrix CreateRandomDirectedWeights(DirectedGraphMatrix f, int minWeight = -5, int maxWeight = 20)
        {
            Random r = new Random();
            DirectedGraphMatrix ret = new DirectedGraphMatrix(f.NodesNr);

            for (int k = 0; k < f.NodesNr; k++)
            {
                for (int p = 0; p < f.NodesNr; p++)
                {
                    if (f.GetConnection(k, p))
                    {
                        ret.MakeConnection(k, p, r.Next(minWeight, maxWeight + 1));
                    }
                }
            }
            return(ret);
        }
示例#12
0
        /// <summary>
        /// Czy w grafie wystepuje ujemny cykl
        /// </summary>
        /// <param name="x"></param>
        /// <param name="w"></param>
        /// <returns></returns>
        public static bool ujemnyCykl(DirectedGraphMatrix x, int[,] w)
        {
            List <List <int> > l = circuts(x);

            for (int i = 0; i < l.Count; i++)
            {
                int sum = 0;
                for (int j = 0; j < l[i].Count - 1; j++)
                {
                    sum += w[l[i][j], l[i][j + 1]];
                }
                if (sum < 0)
                {
                    return(true);
                }
            }
            return(false);
        }
示例#13
0
        private DirectedGraphMatrix createGraphFromRows(List <Row> rows)
        {
            DirectedGraphMatrix graph = new DirectedGraphMatrix(Node.Indexer);

            for (int i = 0; i < rows.Count; ++i)
            {
                var row = rows[i];
                foreach (var node in row)
                {
                    graph.AddToColumn(i);
                    foreach (var connectedTo in node.JoinedTo)
                    {
                        graph.MakeConnection(node.Index, connectedTo.Index);
                    }
                }
            }

            return(graph);
        }
示例#14
0
 /// <summary>
 /// Transpozycja macierzy sasiedztwa
 /// potrzebna do algorytmu Kosaraju
 /// </summary>
 /// <param name="from"></param>
 /// <returns>Graf z transponowana macierza sasiedztwa</returns>
 public static DirectedGraphMatrix transpose(DirectedGraphMatrix from)
 {
     int[,] t = new int[from.NodesNr, from.NodesNr];
     for (int i = 0; i < from.NodesNr; i++)
     {
         for (int j = 0; j < from.NodesNr; j++)
         {
             if (from.GetConnection(i, j))
             {
                 t[j, i] = 1;
             }
             else
             {
                 t[j, i] = 0;
             }
         }
     }
     return(new DirectedGraphMatrix(from.NodesNr, t));
 }
示例#15
0
        /// <summary>
        /// Tworzy graf maxymalnie spojny
        /// </summary>
        /// <param name="f">graf</param>
        /// <returns>max spojny graf</returns>
        public static DirectedGraphMatrix Directedmaxspojny(DirectedGraphMatrix f)
        {
            List <List <int> > sp = spojne(f);
            int k = 0;

            for (int i = 0; i < sp.Count; i++)
            {
                if (sp[i].Count >= sp[k].Count)
                {
                    k = i;
                }
            }
            List <int> q = sp[k];

            int[,] t = new int[q.Count, q.Count];
            k        = 0;
            int l;

            for (int i = 0; i < f.NodesNr; i++)
            {
                l = 0;
                if (!q.Contains(i))
                {
                    continue;
                }
                for (int j = 0; j < f.NodesNr; j++)
                {
                    if (!q.Contains(j))
                    {
                        continue;
                    }
                    if (f.GetConnection(i, j))
                    {
                        t[k, l] = 1;
                    }
                    l++;
                }
                k++;
            }
            return(new DirectedGraphMatrix(q.Count, t));
        }
示例#16
0
        private DirectedGraphMatrix createGraphFromRows(List <Row> rows)
        {
            DirectedGraphMatrix graph = new DirectedGraphMatrix(Node.Indexer);

            for (int i = 0; i < rows.Count; ++i)
            {
                var row = rows[i];
                foreach (var node in row)
                {
                    graph.AddToColumn(i);
                    foreach (var connectedTo in node.JoinedTo)
                    {
                        var flow = flows.First(f => f.Item1.Index == node.Index && f.Item2.Index == connectedTo.Index);

                        graph.MakeConnection(node.Index, connectedTo.Index);
                        graph.setWeight(node.Index, connectedTo.Index, flow.Item3);
                    }
                }
            }

            return(graph);
        }
示例#17
0
        public int findMaxFlow(DirectedGraphMatrix g)
        {
            int        size = g.nodesNr;
            int        max;
            int        min;
            List <int> tempList = new List <int>();

            int[,] tempWeightMatrix = new int[nodes, nodes];
            for (int i = 0; i < nodes; ++i)
            {
                for (int j = 0; j < nodes; ++j)
                {
                    tempWeightMatrix[i, j] = weightMatrix[i, j];
                }
            }

            do
            {
                tempList = createFlowRoute(tempWeightMatrix, size);
                if (tempList.Count > 1)
                {
                    min = findMinWeight(tempList);
                    if (tempList.Count > 1)
                    {
                        turnRoute(tempList, min);
                    }
                    odejmijWageOdTrasy(tempList, min);
                    max += min;
                }
                else
                {
                    break;
                }
            } while (tempList.Count != 0);

            createFlowMatrix(weightMatrix, tempWeightMatrix, size);

            return(max);
        }
示例#18
0
 public DirectionalGraphRenderer(DirectedGraphMatrix Graph, GraphControl GraphControl, DirectedWindowViewModel vm)
 {
     this.GraphControl     = GraphControl;
     this.Graph            = Graph;
     this.DirectedWindowVM = vm;
 }
示例#19
0
        /// <summary>
        /// Bellman ford
        /// </summary>
        /// <param name="g"></param>
        /// <param name="start">skad</param>
        /// <param name="finish">dokad</param>
        /// <returns>lista wierzcholkow po ktorych otrzymamy najkrotsza sciezke start /rest/ finish</returns>
        public static List <int> BellmanFord(DirectedGraphMatrix g, int start, int finish)
        {
            const int INF = int.MaxValue - 1000;                       //uzywam jako nieskonczonosci
            var       map = new Dictionary <int, Tuple <int, int> >(); //nr wierzch. < odleglosc, skad przyszedl >

            for (int i = 0; i < g.NodesNr; i++)
            {
                if (i == start)
                {
                    map.Add(i, new Tuple <int, int>(0, -1));
                }
                else
                {
                    map.Add(i, new Tuple <int, int>(INF, -1));
                }
            }

            var con = new List <Tuple <int, int, int> >();//lista polaczen skad / dokad / waga

            for (int i = 0; i < g.NodesNr; i++)
            {
                for (int j = 0; j < g.NodesNr; j++)
                {
                    if (g.GetConnection(i, j))
                    {
                        con.Add(new Tuple <int, int, int>(i, j, g.getWeight(i, j)));
                    }
                }
            }

            for (int i = 0; i < g.NodesNr - 1; i++)
            {
                for (int j = 0; j < con.Count; j++)
                {
                    if (map[con[j].Item2].Item1 == INF && map[con[j].Item1].Item1 == INF)//pozbywam sie operacji na nieskonczonosciach
                    {
                        continue;
                    }
                    if (map[con[j].Item2].Item1 > map[con[j].Item1].Item1 + con[j].Item3)//relaksacja
                    {
                        map[con[j].Item2] = new Tuple <int, int>(map[con[j].Item1].Item1 + con[j].Item3, con[j].Item1);
                    }
                }
            }

            //sprawdzenie czy istnieje cykl ujemny
            //jesli wykona sie warunek istnieje ujemny
            for (int j = 0; j < con.Count; j++)
            {
                if (map[con[j].Item2].Item1 > map[con[j].Item1].Item1 + con[j].Item3) //relaksacja
                {
                    return(null);                                                     //jesli relaksacja jest możliwa po V-1 przejściach istnieje cykl ujemny
                }
            }
            //sciezka wynikowa
            List <int> path = new List <int>();
            recBellman(map, path, start, finish); //sciezke otrzymamy od konca
            if (path.Count == 1)                  //brak sciezki
            {
                return(null);
            }
            path.Reverse();
            return(path);
        }
示例#20
0
        /// <summary>
        /// Tworzenie macierzy odleglosci pomiedzy wszystkimi parami wierzcholkow w grafie spojnym skierowanym, wykorzystuje algorytm Dijkstry
        /// </summary>
        /// <param name="from"></param> Graf skierowany, w ktorym liczymy odleglosci miedzy wszystkimi parami wierzcholkow
        /// <returns></returns> distances - Macierz odleglosci miedzy wszystkimi parami wierzcholkow
        public static int[,] distancesDirectedMatrix(DirectedGraphMatrix graph)
        {
            int nodes = graph.NodesNr;

            int[,] distances = new int[nodes, nodes];
            List <int> path       = new List <int>();
            int        total_dist = 0;
            int        dist       = 0;
            const int  INF        = int.MaxValue - 10000;


            for (int i = 0; i < nodes; ++i)
            {
                for (int j = 0; j < nodes; ++j)
                {
                    if (i == j)
                    {
                        distances[i, j] = 0;
                    }
                    else
                    {
                        distances[i, j] = INF;
                    }
                }
            }

            for (int i = 0; i < nodes; ++i)
            {
                for (int j = 0; j < nodes; ++j)
                {
                    if (i == j)
                    {
                        continue;
                    }
                    else
                    {
                        path = PathFinding.Dijkstra(graph, i, j);

                        if (path.Count == 0)
                        {
                            continue;
                        }
                        else if (path.Count == 1)
                        {
                            distances[i, j] = graph.getWeight(i, path[0]);

                            path.Clear();
                        }
                        else
                        {
                            for (int k = 0; k < path.Count - 1; ++k)
                            {
                                dist += graph.getWeight(path[k], path[k + 1]);
                            }
                            total_dist      = dist + graph.getWeight(i, path[0]);
                            distances[i, j] = total_dist;
                            total_dist      = dist = 0;
                            path.Clear();
                        }
                    }
                }
            }
            return(distances);
        }
示例#21
0
        /// <summary>
        /// Implementacja algorytmu Johnsona, korzysta z algorytmow Bellmana-Forda i Dijkstry
        /// </summary>
        /// <param name="g"></param> Musi to byc graf skierowany ktory ma juz randomowe wagi i musi byc on spojny(WAŻNE)!!!!
        /// Mozna np stworzyc graf skierowany, wydobyc z niego skladowa maksymalnie spojna i nadać jej randomowe wagi
        /// <returns></returns> Macierz odleglosci miedzy wszystkimi wierzcholkami


        public static int[,] Johnson(DirectedGraphMatrix graph)
        {
            try
            {
                int nodes = graph.NodesNr;
                int[,] distances = new int[nodes, nodes];
                int[]     d   = new int[nodes];
                const int INF = int.MaxValue - 10000;
                int[,] wagi = new int[nodes, nodes];

                int q = nodes + 1;
                int[,] new_connect = new int[q, q];
                for (int i = 0; i < nodes; ++i)
                {
                    for (int j = 0; j < nodes; ++j)
                    {
                        new_connect[i, j] = graph.getConnect(i, j);
                        wagi[i, j]        = graph.getWeight(i, j);
                    }
                }

                DirectedGraphMatrix dgraph = new DirectedGraphMatrix(q, new_connect);

                for (int i = 0; i < q - 1; ++i)
                {
                    dgraph.MakeConnection(q - 1, i, 0);
                    dgraph.setWeight(i, q - 1, INF);
                    for (int j = 0; j < q - 1; ++j)
                    {
                        dgraph.setWeight(i, j, graph.getWeight(i, j));
                    }
                }

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

                for (int i = 0; i < nodes; ++i)
                {
                    bellman.Add(BellmanFord(dgraph, q - 1, i));
                    d[i] = pathWeight(dgraph, bellman[i]);
                    if (ujemnyCykl(graph, wagi))
                    {
                        throw new Exception("Algorytm Johnsona zostal zatrzymany.");
                    }
                }

                for (int i = 0; i < q - 1; ++i)
                {
                    for (int j = 0; j < q - 1; ++j)
                    {
                        if (dgraph.GetConnection(i, j))
                        {
                            dgraph.setWeight(i, j, dgraph.getWeight(i, j) + d[i] - d[j]);
                        }
                    }
                }

                int[,] last_connect = new int[nodes, nodes];
                for (int i = 0; i < nodes; ++i)
                {
                    for (int j = 0; j < nodes; ++j)
                    {
                        last_connect[i, j] = dgraph.getConnect(i, j);
                    }
                }

                DirectedGraphMatrix lgraph = new DirectedGraphMatrix(nodes, last_connect);

                for (int i = 0; i < nodes; ++i)
                {
                    for (int j = 0; j < nodes; ++j)
                    {
                        lgraph.setWeight(i, j, dgraph.getWeight(i, j));
                    }
                }

                distances = distancesDirectedMatrix(lgraph);
                for (int i = 0; i < nodes; ++i)
                {
                    for (int j = 0; j < nodes; ++j)
                    {
                        distances[i, j] = distances[i, j] - d[i] + d[j];
                    }
                }
                return(distances);
            }
            catch (Exception)
            {
                Console.WriteLine("Algorytm Johnsona zatrzymany z powodu ujemnego cyklu w grafie.");
                return(new int[5, 5]);
            }
        }