示例#1
0
 public void AddFlowRespectsMinimumCapacityInPath()
 {
     Vertex c = new Vertex();
     Edge f = Edge.AddEdge(b,c,1000d,1000d);
     a.AddFlowTo(c);
     Assert.AreEqual(f.ResidualCapacity(b),999d);
 }
示例#2
0
 public void CanMakeNontrivialCut()
 {
     Vertex vert1 = new Vertex();
     Vertex vert2 = new Vertex();
     Vertex vert3 = new Vertex();
     Vertex vert4 = new Vertex();
     Vertex vert5 = new Vertex();
     Vertex vert6 = new Vertex();
     /*   o:o-o6
      *   |\:
      * o-o-o
      * 1
      * Where : is a weak edge
      */
     Edge.AddEdge(vert1,vert2,1d,1d);
     Edge.AddEdge(vert2,vert3,1d,1d);
     Edge.AddEdge(vert2,vert4,1d,1d);
     Edge.AddEdge(vert3,vert4,1d,1d);
     Edge.AddEdge(vert3,vert5,0.1d,0.1d);
     Edge.AddEdge(vert4,vert5,0.1d,0.1d);
     Edge.AddEdge(vert5,vert6,1d,1d);
     while(vert1.AddFlowTo(vert6));
     vert1.ResidualCapacityConnectedNodes();
     bool all_on_that_should_be = vert1.tagged_as_one && vert2.tagged_as_one && vert3.tagged_as_one && vert4.tagged_as_one;
     bool all_off_that_should_be = !(vert5.tagged_as_one) && !(vert6.tagged_as_one);
     Assert.IsTrue(all_off_that_should_be && all_on_that_should_be);
 }
示例#3
0
 public static Edge AddEdge(Vertex v1, Vertex v2, double capacity_1_to_2, double capacity_2_to_1)
 {
     Edge toReturn = new Edge(v1,v2,capacity_1_to_2,capacity_2_to_1);
     v1.AddEdge(toReturn);
     v2.AddEdge(toReturn);
     return toReturn;
 }
示例#4
0
 public Edge(Vertex v1, Vertex v2, double capacity_1_to_2, double capacity_2_to_1)
 {
     this.v1 = v1;
     this.v2 = v2;
     this.capacity_1_to_2 = capacity_1_to_2;
     this.capacity_2_to_1 = capacity_2_to_1;
     this.flow_1_to_2 = 0.0;
 }
示例#5
0
 public Vertex Traverse(Vertex origin_vertex)
 {
     if (origin_vertex == this.v1)
     {
         return this.v2;
     }
     else
     {
         return this.v1;
     }
 }
示例#6
0
 public double ResidualCapacity(Vertex origin_vertex)
 {
     if (origin_vertex == this.v1)
     {
         return this.capacity_1_to_2 - this.flow_1_to_2;
     }
     else
     {
         return this.capacity_2_to_1 + this.flow_1_to_2;
     }
 }
示例#7
0
 /// <summary>
 /// Modifies the amount of flow currently carried by this edge.
 /// </summary>
 /// <param name='origin_vertex'>
 /// </param>
 /// <param name='flow'>
 /// The flow parameter should always be positive here. This is the amount
 /// of flow we are trying to send across the edge starting from origin_vertex.
 /// </param>
 public void AddFlow(Vertex origin_vertex, double flow)
 {
     if (flow > this.ResidualCapacity(origin_vertex))
     {
         throw new System.ArgumentException("Parameter exceeds allowable bounds.", "flow");
     }
     if (origin_vertex == this.v1)
     {
         this.flow_1_to_2 += flow;
     }
     else
     {
         this.flow_1_to_2 -= flow;
     }
 }
示例#8
0
 public double AddFlowTo(List<Vertex> traversed, Vertex target, double max_capacity)
 {
     if(max_capacity <= 0d) return 0d;
     if(this == target)
         return max_capacity;
     traversed.Add(this);
     foreach(Edge e in edges)
     {
         Vertex eTo = e.Traverse(this);
         if(traversed.Contains(eTo)) continue;
         double flow_added = eTo.AddFlowTo(traversed, target, Math.Min(e.ResidualCapacity(this),max_capacity));
         if(flow_added > 0d) //If we've added any flow, the path is viable. Travel up the stack actually adding the flow.
         {
             e.AddFlow(this,flow_added);
             return flow_added;
         }
     }
     //If none of the edges returned any flow or were viable, then there is
     //no path with positive capacity from this vertex to the target through
     //as yet untraversed nodes.
     return 0d;
 }
示例#9
0
 public void TwoVertexGraph()
 {
     a = new Vertex();
     b = new Vertex();
     e = Edge.AddEdge(a,b,1d,1d);
 }
示例#10
0
        public Classification MaximumAPosterioriInfer(ImageData test_input)
        {
            Vertex[,] site_nodes = new Vertex[test_input.XSites, test_input.YSites];
            for(int i = 0; i < test_input.XSites; i++) for(int j = 0; j < test_input.YSites; j++)
            {
                site_nodes[i,j] = new Vertex();
            }
            Vertex source = new Vertex();
            Vertex target = new Vertex();

            for(int j = 0; j < test_input.YSites; j++)
            {
                for(int i = 0; i < test_input.XSites; i++)
                {
                    Vertex t = site_nodes[i,j];
                    //Add the edge with capacity lambda_t from the source, or the edge with capacity -lambda_t to the target.
                    //Lambda_t is the log-likelihood ratio: log( p(y | x = 1) / p(y | x = 0) ).
                    //Using Bayes' law, we have
                    //Posterior Odds = P(x = 1 | y)/P(x = 0 | y) = Likelihood Ratio * Prior Odds = (P(y | x = 1) / P(y | x = 0))*(P(x=1)/P(x=0)) = e^(lambda_t)*1
                    //So lambda_t should be log(Posterior Odds) + log(Prior Odds) = log(P(x=1|y))-log(P(x=0|y)) + possibly 0?

                    //Now, P(x=1|y) is modeled as sigma(w^T * h(y)), so this should be
                    //log(sigma(w^T * h(y))) - log(1-sigma(w^T * h(y))).
                    //However, all these calculations were done at roughly 5:50 AM and I hadn't slept yet, so...
                    //I could totally be wrong.
                    //-Jesse Selover
                    double modeled_prob_of_one = MathWrapper.Sigma(W.DotProduct(Transformer.Transform(test_input[i,j])));
                    /*double prob_one = ((double)Ons_seen)/((double) Sites_seen);
                    double prob_zero = 1d - prob_one;
                    double lambda = MathWrapper.Log(modeled_prob_of_one) - MathWrapper.Log (1 - modeled_prob_of_one) + MathWrapper.Log (prob_one/prob_zero);*/
                    Edge.AddEdge(source,t,-MathWrapper.Log(modeled_prob_of_one),0);
                    Edge.AddEdge(t,target,-MathWrapper.Log(1-modeled_prob_of_one),0);
                    Console.WriteLine("Edge to target with strength {0}",-MathWrapper.Log(1-modeled_prob_of_one));
                    //Add an edge from the source with the modeled probability of 1, and an edge to the target with the modeled probability of 0.
                    //Console.WriteLine(ImageData.GetNewConnections(i,j).Count);
                    foreach(Tuple<int,int> other in test_input.GetNewConnections(i,j))
                    {
                        Vertex u = site_nodes[other.Item1,other.Item2];
                        //Add the edge with capacity Beta_{t,u} in both directions between t and u.
                        //DRFS (2006) says that the data dependent smoothing term is max(0,v^T * mu_{i,j}y)
                        DenseVector mu;
                        if(ImageData.IsEarlier(i,j,other.Item1,other.Item2))mu = Crosser.Cross(test_input[i,j],test_input[other.Item1,other.Item2]);
                        else mu = Crosser.Cross(test_input[other.Item1,other.Item2], test_input[i,j]);
                        double capacity = Math.Max(0,V.DotProduct(mu));
                        Console.WriteLine ("\tInternode edge with strength {0}",capacity);
                        Edge.AddEdge(t,u,capacity,capacity);
                    }
                }
            }
            double flow_added = 0;

            while(true)
            {
                flow_added = source.AddFlowTo(new List<Vertex>(), target, 400000000d);
                if(flow_added <= 0.0000001d) break;
            }; //Find the maximum flow
            source.ResidualCapacityConnectedNodes(); //Find the source end of the minimum cut

            Label[,] toReturn = new Label[test_input.XSites, test_input.YSites];
            for(int i = 0; i < test_input.XSites; i++) for(int j = 0; j < test_input.YSites; j++)
            {
                if(site_nodes[i,j].tagged_as_one) toReturn[i,j] = Label.ON;
            }
            return new Classification(toReturn);
        }
示例#11
0
 public bool AddFlowTo(Vertex target)
 {
     return AddFlowTo(new List<Vertex>(),target,30000000d)>0d;//Hack
 }