Ejemplo n.º 1
0
        // find shortest augmenting path and upate
        private void augment()
        {
            // build residual graph
            EdgeWeightedDigraph G = new EdgeWeightedDigraph(2 * N + 2);
            int s = 2 * N, t = 2 * N + 1;

            for (int i = 0; i < N; i++)
            {
                if (xy[i] == UNMATCHED)
                {
                    G.AddEdge(new DirectedEdge(s, i, 0.0));
                }
            }
            for (int j = 0; j < N; j++)
            {
                if (yx[j] == UNMATCHED)
                {
                    G.AddEdge(new DirectedEdge(N + j, t, py[j]));
                }
            }
            for (int i = 0; i < N; i++)
            {
                for (int j = 0; j < N; j++)
                {
                    if (xy[i] == j)
                    {
                        G.AddEdge(new DirectedEdge(N + j, i, 0.0));
                    }
                    else
                    {
                        G.AddEdge(new DirectedEdge(i, N + j, reducedCost(i, j)));
                    }
                }
            }

            // compute shortest path from s to every other vertex
            DijkstraSP spt = new DijkstraSP(G, s);

            // augment along alternating path
            foreach (DirectedEdge e in spt.PathTo(t))
            {
                int i = e.From, j = e.To - N;
                if (i < N)
                {
                    xy[i] = j;
                    yx[j] = i;
                }
            }

            // update dual variables
            for (int i = 0; i < N; i++)
            {
                px[i] += spt.DistTo(i);
            }
            for (int j = 0; j < N; j++)
            {
                py[j] += spt.DistTo(N + j);
            }
        }
Ejemplo n.º 2
0
        public static void MainTest(string[] args)
        {
            // create random DAG with V vertices and E edges; then add F random edges
            int V = int.Parse(args[0]);
            int E = int.Parse(args[1]);
            int F = int.Parse(args[2]);
            EdgeWeightedDigraph G = new EdgeWeightedDigraph(V);

            int[] vertices = new int[V];
            for (int i = 0; i < V; i++)
            {
                vertices[i] = i;
            }
            StdRandom.Shuffle(vertices);
            for (int i = 0; i < E; i++)
            {
                int v, w;
                do
                {
                    v = StdRandom.Uniform(V);
                    w = StdRandom.Uniform(V);
                } while (v >= w);
                double weight = StdRandom.Uniform();
                G.AddEdge(new DirectedEdge(v, w, weight));
            }

            // add F extra edges
            for (int i = 0; i < F; i++)
            {
                int    v      = StdRandom.Uniform(V);
                int    w      = StdRandom.Uniform(V);
                double weight = StdRandom.Uniform(0.0, 1.0);
                G.AddEdge(new DirectedEdge(v, w, weight));
            }

            Console.WriteLine(G);

            // find a directed cycle
            EdgeWeightedDirectedCycle finder = new EdgeWeightedDirectedCycle(G);

            if (finder.HasCycle)
            {
                Console.Write("Cycle: ");
                foreach (DirectedEdge e in finder.GetCycle())
                {
                    Console.Write(e + " ");
                }
                Console.WriteLine();
            }

            // or give topologial sort
            else
            {
                Console.WriteLine("No directed cycle");
            }
        }
Ejemplo n.º 3
0
Archivo: CPM.cs Proyecto: zzhi/Algs4Net
        public static void MainTest(string[] args)
        {
            TextInput StdIn = new TextInput();
            // number of jobs
            int N = StdIn.ReadInt();

            // source and sink
            int source = 2 * N;
            int sink   = 2 * N + 1;

            // build network
            EdgeWeightedDigraph G = new EdgeWeightedDigraph(2 * N + 2);

            for (int i = 0; i < N; i++)
            {
                double duration = StdIn.ReadDouble();
                G.AddEdge(new DirectedEdge(source, i, 0.0));
                G.AddEdge(new DirectedEdge(i + N, sink, 0.0));
                G.AddEdge(new DirectedEdge(i, i + N, duration));

                // precedence constraints
                int M = StdIn.ReadInt();
                for (int j = 0; j < M; j++)
                {
                    int precedent = StdIn.ReadInt();
                    G.AddEdge(new DirectedEdge(N + i, precedent, 0.0));
                }
            }

            // compute longest path
            AcyclicLP lp = new AcyclicLP(G, source);

            // print results
            Console.WriteLine(" job   start  finish");
            Console.WriteLine("--------------------");
            for (int i = 0; i < N; i++)
            {
                Console.Write("{0,4} {1,7:F1} {2,7:F1}\n", i, lp.DistTo(i), lp.DistTo(i + N));
            }
            Console.Write("Finish time: {0,7:F1}\n", lp.DistTo(sink));
        }
Ejemplo n.º 4
0
        // by finding a cycle in predecessor graph
        private void findNegativeCycle()
        {
            int V = edgeTo.Length;
            EdgeWeightedDigraph spt = new EdgeWeightedDigraph(V);

            for (int v = 0; v < V; v++)
            {
                if (edgeTo[v] != null)
                {
                    spt.AddEdge(edgeTo[v]);
                }
            }

            EdgeWeightedDirectedCycle finder = new EdgeWeightedDirectedCycle(spt);

            cycle = finder.GetCycle();
        }
Ejemplo n.º 5
0
        public static void MainTest(string[] args)
        {
            TextInput StdIn = new TextInput();
            // V currencies
            int V = StdIn.ReadInt();

            string[] name = new string[V];

            // create complete network
            EdgeWeightedDigraph G = new EdgeWeightedDigraph(V);

            for (int v = 0; v < V; v++)
            {
                name[v] = StdIn.ReadString();
                for (int w = 0; w < V; w++)
                {
                    double       rate = StdIn.ReadDouble();
                    DirectedEdge e    = new DirectedEdge(v, w, -Math.Log(rate));
                    G.AddEdge(e);
                }
            }

            // find negative cycle
            BellmanFordSP spt = new BellmanFordSP(G, 0);

            if (spt.HasNegativeCycle)
            {
                double stake = 1000.0;
                foreach (DirectedEdge e in spt.GetNegativeCycle())
                {
                    Console.Write("{0,10:F5} {1} ", stake, name[e.From]);
                    stake *= Math.Exp(-e.Weight);
                    Console.Write("= {0,10:F5} {1}\n", stake, name[e.To]);
                }
            }
            else
            {
                Console.WriteLine("No arbitrage opportunity");
            }
        }
Ejemplo n.º 6
0
 /// <summary>
 /// Returns a negative cycle, or <c>null</c> if there is no such cycle.</summary>
 /// <returns>a negative cycle as an iterable of edges,
 /// or <c>null</c> if there is no such cycle</returns>
 ///
 public IEnumerable <DirectedEdge> NegativeCycle()
 {
     for (int v = 0; v < distTo.Length; v++)
     {
         // negative cycle in v's predecessor graph
         if (distTo[v, v] < 0.0)
         {
             int V = edgeTo.Length;
             EdgeWeightedDigraph spt = new EdgeWeightedDigraph(V);
             for (int w = 0; w < V; w++)
             {
                 if (edgeTo[v, w] != null)
                 {
                     spt.AddEdge(edgeTo[v, w]);
                 }
             }
             EdgeWeightedDirectedCycle finder = new EdgeWeightedDirectedCycle(spt);
             Debug.Assert(finder.HasCycle);
             return(finder.GetCycle());
         }
     }
     return(null);
 }