Esempio n. 1
0
 public override double GetArea()
 {
     return(theRegion.GetKnownArea());
 }
        //
        // Graph traversal to find shapes and thus the resulting equation (solution).
        //
        // Dynamic Programming: return the first solution found (which will be the shortest)
        //
        private KeyValuePair <ComplexRegionEquation, double> DynamicVisit(int startIndex, bool[] visited, KnownMeasurementsAggregator known)
        {
            // The actual Region object for this node.
            Region thisRegion = graph.vertices[startIndex].data;

            // Cut off search if we've been here before.
            if (visited[startIndex])
            {
                return(new KeyValuePair <ComplexRegionEquation, double>(memoizedSolutions[startIndex], thisRegion.GetKnownArea()));
            }

            // We've been here now.
            visited[startIndex] = true;

            //
            // Can we compute the area of this node directly?
            //
            double area = thisRegion.GetArea(known);

            if (area > 0)
            {
                thisRegion.SetKnownArea(area);
                memoizedSolutions[startIndex] = new ComplexRegionEquation(thisRegion, thisRegion);
                return(new KeyValuePair <ComplexRegionEquation, double>(memoizedSolutions[startIndex], thisRegion.GetKnownArea()));
            }

            //
            // Does any of the edges satisfy this equation? Investigate dynamically.
            //
            // Complex equation resulting from each outgoing edge.
            ComplexRegionEquation shortestEq = null;

            area = 0;
            foreach (Hypergraph.HyperEdge <SimpleRegionEquation> edge in graph.vertices[startIndex].targetEdges)
            {
                KeyValuePair <ComplexRegionEquation, double> src1Eq = DynamicVisit(edge.sourceNodes[0], visited, known);
                KeyValuePair <ComplexRegionEquation, double> src2Eq = DynamicVisit(edge.sourceNodes[1], visited, known);

                // Success, we found a valid area expression for edge.
                if (src1Eq.Key != null && src2Eq.Key != null)
                {
                    // Create a copy of the anootation for a simple region equation for this edge.
                    SimpleRegionEquation simpleEdgeEq = new SimpleRegionEquation(edge.annotation);

                    //
                    // Make one complex equation performing substitutions.
                    //
                    ComplexRegionEquation complexEdgeEq = new ComplexRegionEquation(simpleEdgeEq);
                    complexEdgeEq.Substitute(src1Eq.Key.target, src1Eq.Key.expr);
                    complexEdgeEq.Substitute(src2Eq.Key.target, src2Eq.Key.expr);

                    // Pick the shortest equation possible.
                    if (shortestEq == null)
                    {
                        shortestEq = complexEdgeEq;
                    }
                    else if (shortestEq.Length > complexEdgeEq.Length)
                    {
                        shortestEq = complexEdgeEq;
                    }

                    if (edge.annotation.op == OperationT.ADDITION)
                    {
                        area = src1Eq.Value + src2Eq.Value;
                    }
                    else if (edge.annotation.op == OperationT.SUBTRACTION)
                    {
                        area = src1Eq.Value - src2Eq.Value;
                    }
                }
            }

            //if (shortestEq != null)
            //{
            //    thisRegion.SetKnownArea(area);
            //    memoizedSolutions[startIndex] = new ComplexRegionEquation(thisRegion, thisRegion);
            //    return new KeyValuePair<ComplexRegionEquation, double>(memoizedSolutions[startIndex], area);
            //}

            memoizedSolutions[startIndex] = shortestEq;

            return(new KeyValuePair <ComplexRegionEquation, double>(memoizedSolutions[startIndex], area));
        }