Пример #1
0
        public Edmonds_Karp(WeightGraph weightGraph, int s, int t)
        {
            _weightGraph = weightGraph;
            _s           = s;
            _t           = t;
            if (!weightGraph.Directed)
            {
                throw new Exception("directed graph can be supported");
            }
            if (_weightGraph.V < 2)
            {
                throw new Exception("vertex must be more than 2");
            }
            _weightGraph.ValidateNumber(s);
            _weightGraph.ValidateNumber(t);
            if (s == t)
            {
                throw new Exception("source point and sink point can't be same");
            }
            _residualQuantityGraph = new WeightGraph(_weightGraph.V, true);

            for (int v = 0; v < _weightGraph.V; v++)
            {
                foreach (var w in _weightGraph.GetAllContiguousEdge(v))
                {
                    int weight = _weightGraph.GetWeight(v, w);
                    _residualQuantityGraph.AddEdge(v, w, weight);
                    _residualQuantityGraph.AddEdge(w, v, 0);
                }
            }

            while (true)
            {
                List <int> path = GetArgumentingPath();
                if (path.Count == 0)
                {
                    break;
                }
                int f = int.MaxValue;
                for (int i = 1; i < path.Count; i++)
                {
                    int v = path[i - 1];
                    int w = path[i];
                    f = Math.Min(f, _residualQuantityGraph.GetWeight(v, w));
                }
                MaxFlow += f;
                for (int i = 1; i < path.Count; i++)
                {
                    int v                = path[i - 1];
                    int w                = path[i];
                    int weight           = _residualQuantityGraph.GetWeight(v, w);
                    int residualQuantity = _residualQuantityGraph.GetWeight(w, v);
                    _residualQuantityGraph.SetWeight(v, w, weight - f);
                    _residualQuantityGraph.SetWeight(w, v, residualQuantity + f);
                }
            }
        }
        public MinCreateTreeUseKruskal(WeightGraph weightGraph)
        {
            _weightGraph = weightGraph;
            _result      = new List <WeightEdge>();

            //cc检测是否联通

            List <WeightEdge> list = new List <WeightEdge>();

            for (int i = 0; i < _weightGraph.V; i++)
            {
                foreach (var w in _weightGraph.GetAllContiguousEdge(i))
                {
                    if (i > w)
                    {
                        continue;
                    }
                    int weight = _weightGraph.GetWeight(i, w);
                    list.Add(new WeightEdge(i, w, weight));
                }
            }
            list.Sort();
            UnionFindAggregate uf = new UnionFindAggregate(_weightGraph.V);

            foreach (var e in list)
            {
                if (uf.IsConnected(e.V, e.W))
                {
                    continue;
                }
                _result.Add(e);
                uf.Union(e.V, e.W);
            }
        }
Пример #3
0
        public Dijkstra(WeightGraph weightGraph, int s)
        {
            this._weightGraph = weightGraph;
            this._s           = s;
            _pre     = new int[_weightGraph.V];
            _visited = new bool[_weightGraph.V];
            _dirs    = new int[_weightGraph.V];

            for (int i = 0; i < _weightGraph.V; i++)
            {
                _dirs[i] = int.MaxValue;
            }

            _dirs[_s] = 0;

            while (true)
            {
                int curDis = Int32.MaxValue;
                int cur    = -1;
                for (int i = 0; i < _weightGraph.V; i++)
                {
                    if (!_visited[i] && _dirs[i] < curDis)
                    {
                        curDis = _dirs[i];
                        cur    = i;
                    }
                }

                if (cur == -1)
                {
                    break;
                }

                _visited[cur] = true;

                foreach (var w in _weightGraph.GetAllContiguousEdge(cur))
                {
                    if (!_visited[w] && _dirs[w] > _dirs[cur] + _weightGraph.GetWeight(cur, w))
                    {
                        _dirs[w] = _dirs[cur] + _weightGraph.GetWeight(cur, w);
                        _pre[w]  = cur;
                    }
                }
            }
        }
Пример #4
0
        private List <int> GetArgumentingPath()
        {
            Queue <int> queue = new Queue <int>();

            queue.Enqueue(_s);

            int[] pre = new int[_residualQuantityGraph.V];

            for (int i = 0; i < _residualQuantityGraph.V; i++)
            {
                pre[i] = -1;
            }

            pre[_s] = _s;
            while (queue.Count > 0)
            {
                int v = queue.Dequeue();
                foreach (var w in _residualQuantityGraph.GetAllContiguousEdge(v))
                {
                    if (pre[w] == -1 && _residualQuantityGraph.GetWeight(v, w) > 0)
                    {
                        pre[w] = v;
                        queue.Enqueue(w);
                    }
                }
            }

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

            if (pre[_t] == -1)
            {
                return(path);
            }
            int cur = _t;

            while (cur != _s)
            {
                path.Add(cur);
                cur = pre[cur];
            }
            path.Add(_s);
            path.Reverse();
            return(path);
        }
Пример #5
0
        public Bellman_Ford(WeightGraph weightGraph, int s)
        {
            this._weightGraph = weightGraph;
            this._s           = s;
            _pre = new int[_weightGraph.V];

            _dirs = new int[_weightGraph.V];
            for (int i = 0; i < _weightGraph.V; i++)
            {
                _dirs[i] = Int32.MaxValue;
            }
            _dirs[s] = 0;

            for (int i = 0; i < _weightGraph.V - 1; i++)
            {
                for (int j = 0; j < _weightGraph.V; j++)
                {
                    foreach (var w in _weightGraph.GetAllContiguousEdge(j))
                    {
                        if (_dirs[j] != int.MaxValue && _dirs[j] + _weightGraph.GetWeight(j, w) < _dirs[w])
                        {
                            _dirs[w] = _dirs[j] + _weightGraph.GetWeight(j, w);
                            _pre[w]  = j;
                        }
                    }
                }
            }

            for (int j = 0; j < _weightGraph.V; j++)
            {
                foreach (var w in _weightGraph.GetAllContiguousEdge(j))
                {
                    if (_dirs[j] != int.MaxValue && _dirs[j] + _weightGraph.GetWeight(j, w) < _dirs[w])
                    {
                        IsHaveCircle = true;
                    }
                }
            }
        }
Пример #6
0
        public Floyed(WeightGraph weightGraph)
        {
            this._weightGraph = weightGraph;
            _dirs             = new int[_weightGraph.V][];
            _pre = new int[_weightGraph.V, _weightGraph.V];
            for (int i = 0; i < _weightGraph.V; i++)
            {
                for (int j = 0; j < _weightGraph.V; j++)
                {
                    _pre[i, j] = i;
                }
            }

            for (int i = 0; i < _weightGraph.V; i++)
            {
                _dirs[i] = new int[_weightGraph.V];
                Array.Fill(_dirs[i], int.MaxValue);
            }

            for (int v = 0; v < _weightGraph.V; v++)
            {
                foreach (var w in _weightGraph.GetAllContiguousEdge(v))
                {
                    _dirs[v][w] = _weightGraph.GetWeight(v, w);
                }
            }

            //Floyed
            for (int t = 0; t < _weightGraph.V; t++)
            {
                for (int v = 0; v < _weightGraph.V; v++)
                {
                    for (int w = 0; w < _weightGraph.V; w++)
                    {
                        if (_dirs[v][t] != Int32.MaxValue && _dirs[t][w] != Int32.MaxValue && _dirs[v][t] + _dirs[t][w] < _dirs[v][w])
                        {
                            _dirs[v][w] = _dirs[v][t] + _dirs[t][w];
                            _pre[v, w]  = _pre[t, w];
                        }
                    }
                }
            }

            for (int i = 0; i < _weightGraph.V; i++)
            {
                if (_dirs[i][i] < 0)
                {
                    IsHaveNegativeCircle = true;
                }
            }
        }
Пример #7
0
        public MinCreateTreeUsePrim(WeightGraph weightGraph)
        {
            this._weightGraph = weightGraph;
            _result           = new List <WeightEdge>();

            //cc 的联通分量个数==1

            bool[] visited = new bool[_weightGraph.V];
            visited[0] = true;
            for (int i = 0; i < _weightGraph.V - 1; i++)
            {
                WeightEdge min = new WeightEdge(-1, -1, int.MaxValue);
                for (int j = 0; j < visited.Length; j++)
                {
                    if (visited[j] == false)
                    {
                        continue;
                    }
                    foreach (var w in _weightGraph.GetAllContiguousEdge(j))
                    {
                        if (visited[w])
                        {
                            continue;
                        }
                        int        weight = _weightGraph.GetWeight(j, w);
                        WeightEdge cur    = new WeightEdge(j, w, weight);
                        if (cur.CompareTo(min) < 0)
                        {
                            min = cur;
                        }
                    }
                }
                _result.Add(min);
                visited[min.W] = true;
                visited[min.V] = true;
            }
        }