Пример #1
0
 private void dfs(EdgeWeightDigraph G, int v)
 {
     onStack[v] = true; marked[v] = true;
     foreach (DirectedEdge e in G.Adj(v))
     {
         if (this.HasCycle())
         {
             return;
         }
         else if (!marked[e.To()])
         {
             edgeTo[e.To()] = e;
             dfs(G, e.To());
         }
         else if (onStack[e.To()])
         {
             cycle = new Stack <DirectedEdge>();
             DirectedEdge x = e;
             for (; x.From() != e.To(); x = edgeTo[x.From()])
             {
                 cycle.Push(x);
             }
             cycle.Push(x);
             return;  //??
         }
     }
     onStack[v] = false;
 }
Пример #2
0
 public DijkstraAllPairsSP(EdgeWeightDigraph G)
 {
     all = new DijkstraSP[G.Vnums()];
     for (int v = 0; v < G.Vnums(); v++)
     {
         all[v] = new DijkstraSP(G, v);
     }
 }
Пример #3
0
        public void CreatNewGraph(string path)
        {
            StreamReader In = new StreamReader(path);
            int          N  = int.Parse(In.ReadLine());

            nTask = N;
            S     = 2 * N; T = 2 * N;
            EdgeWeightDigraph G = new EdgeWeightDigraph(2 * N + 2);
        }
Пример #4
0
        public EWDGraphTopological(EdgeWeightDigraph G)
        {
            EdgeWeightedCycle cycleFind = new EdgeWeightedCycle(G);

            if (!cycleFind.HasCycle())
            {
                DFOrder dfs = new DFOrder(G);
                order = dfs.ReversePost();
            }
        }
Пример #5
0
        public double MaxFlow(EdgeWeightDigraph G, int s, int t, int MethodType)    //G 中 w 现在代表边的容量
        {
            V      = G.Vnums();
            AEPath = new List <ArrayList>();
            //MethodType:1-EK,2-
            if (MethodType == 1)     //BFS
            {
                int u, v;
                residual = new double[G.Vnums(), G.Vnums()];    //残余网络,实际存储的是 两点间的流量
                prev     = new int[V];

                //初始化
                for (u = 0; u < G.Vnums(); u++)
                {
                    for (v = 0; v < G.Vnums(); v++)
                    {
                        residual[u, v] = 0;    //为0,不存在该边
                    }
                }
                foreach (var arc in G.Edges())
                {
                    residual[arc.From(), arc.To()] = arc.Weight();    //将其设为边的容量
                }

                int p = 0;                        //记录增广路数量
                while (BFS(residual, s, t, prev)) //不断寻路,直至找不到
                {
                    double pathFlow = double.MaxValue;
                    AEPath.Add(new ArrayList());

                    AEPath[p].Add(t);

                    for (v = t; v != s; v = prev[v])
                    {
                        u        = prev[v];
                        pathFlow = pathFlow < residual[u, v] ? pathFlow : residual[u, v];
                        AEPath[p].Insert(0, u);
                    }

                    AEPath[p].Add(" delta: " + pathFlow);
                    p++;

                    //调整更新
                    for (v = t; v != s; v = prev[v])
                    {
                        u = prev[v];
                        residual[u, v] -= pathFlow;    //前向弧流量 +1,即以它的容量 -1 来表示
                        residual[v, u] += pathFlow;
                    }
                    maxFlow += pathFlow;
                }
            }
            return(maxFlow);
        }
Пример #6
0
 public EdgeWeightedCycle(EdgeWeightDigraph G)
 {
     marked  = new bool[G.Vnums()]; edgeTo = new DirectedEdge[G.Vnums()];
     onStack = new bool[G.Vnums()];
     for (int v = 0; v < G.Vnums(); v++)
     {
         if (!marked[v])
         {
             dfs(G, v);
         }
     }
 }
Пример #7
0
 private void relax(EdgeWeightDigraph G, int v)
 {
     foreach (DirectedEdge e in G.Adj(v))
     {
         int w = e.To();
         if (distTo[w] < distTo[v] + e.Weight())
         {
             distTo[w] = distTo[v] + e.Weight();
             edgeTo[w] = e;
         }
     }
 }
Пример #8
0
 private void dfs(EdgeWeightDigraph G, int v)  //重载
 {
     pre.Enqueue(v);
     marked[v] = true;
     foreach (DirectedEdge w in G.Adj(v))
     {
         if (!marked[w.To()])
         {
             dfs(G, w.To());
         }
         post.Enqueue(v);
         reversePost.Push(v);
     }
 }
Пример #9
0
 //重载
 public DFOrder(EdgeWeightDigraph G)
 {
     pre         = new Queue <int>();
     post        = new Queue <int>();
     reversePost = new Stack <int>();
     marked      = new bool[G.Vnums()];
     for (int v = 0; v < G.Vnums(); v++)
     {
         if (!marked[v])
         {
             dfs(G, v);
         }
     }
 }
Пример #10
0
        public AcycWeDiGLP(EdgeWeightDigraph G, int s)
        {
            edgeTo = new DirectedEdge[G.Vnums()]; distTo = new double[G.Vnums()];
            for (int v = 0; v < G.Vnums(); v++)
            {
                distTo[v] = Double.NegativeInfinity;
            }
            distTo[s] = .0;

            //对 G 先进行拓扑排序
            EWDGraphTopological top = new EWDGraphTopological(G);

            //then, Relax
            foreach (int v in top.Order())
            {
                relax(G, v);
            }
        }
Пример #11
0
        private IndexMinPQ <double> pq;   //存放需要被放松的顶点 并确定下一个被放松的顶点;实质就是临时标记的点

        public DijkstraSP(EdgeWeightDigraph G, int s)
        {
            edgeTo = new DirectedEdge[G.Vnums()];
            distTo = new double[G.Vnums()];
            pq     = new IndexMinPQ <double>(G.Vnums());
            //将 除起点外的点 的distTo 设为 Infinity
            for (int v = 0; v < G.Vnums(); v++)
            {
                distTo[v] = double.PositiveInfinity;
            }
            distTo[s] = 0.0;

            pq.Insert(s, .0);
            while (!pq.isEmpty())
            {
                Relax(G, pq.DelMin());                          //删去pq中的min,即min由临时标记变为永久标记
            }
        }
Пример #12
0
 private void Relax(EdgeWeightDigraph G, int v)
 {
     foreach (DirectedEdge e in G.Adj(v))
     {
         int w = e.To();
         if (distTo[w] > distTo[v] + e.Weight())
         {
             distTo[w] = distTo[v] + e.Weight();
             edgeTo[w] = e;
             //若e.to()还未在优先队列中,则Insert it;若在其中 且 优先级需被降低(即找到了比它有更短距离的顶点,也就是先于它被永久标记的顶点),则Change it
             if (pq.Contains(w))
             {
                 pq.Change(w, distTo[w]);
             }
             else
             {
                 pq.Insert(w, distTo[w]);
             }
         }
     }
 }