示例#1
0
        public ComplexRegionEquation(SimpleRegionEquation simple) : base()
        {
            target = simple.target;

            expr = new Binary(simple.bigger, simple.op, simple.smaller);

            thisArea = -1;
        }
        public ComplexRegionEquation(SimpleRegionEquation simple)
            : base()
        {
            target = simple.target;

            expr = new Binary(simple.bigger, simple.op, simple.smaller);

            thisArea = -1;
        }
        //
        // Equals checks that for both sides of this equation is the same as one entire side of the other equation
        //
        public override bool Equals(object obj)
        {
            SimpleRegionEquation thatEquation = obj as SimpleRegionEquation;

            if (thatEquation == null)
            {
                return(false);
            }

            return(this.op == thatEquation.op &&
                   target.Equals(thatEquation.target) &&
                   bigger.Equals(thatEquation.bigger) &&
                   smaller.Equals(thatEquation.smaller));
        }
        //
        // Add edges
        //
        private bool CreateAddEdges(Region large, Region small, Region atom)
        {
            bool addedEdge = false;

            //
            // A = (A \ a) + a
            //
            SimpleRegionEquation sumAnnotation = new SimpleRegionEquation(large, small, OperationT.ADDITION, atom);
            List <Region>        sources       = new List <Region>();

            sources.Add(small);
            sources.Add(atom);
            if (graph.AddEdge(sources, large, sumAnnotation))
            {
                addedEdge = true;
            }

            //
            // (A \ a) = A - a
            //
            SimpleRegionEquation diff1Annotation = new SimpleRegionEquation(small, large, OperationT.SUBTRACTION, atom);

            sources = new List <Region>();
            sources.Add(large);
            sources.Add(atom);
            if (graph.AddEdge(sources, small, diff1Annotation))
            {
                addedEdge = true;
            }

            //
            // a = A - (A \ a)
            //
            SimpleRegionEquation diff2Annotation = new SimpleRegionEquation(atom, large, OperationT.SUBTRACTION, small);

            sources = new List <Region>();
            sources.Add(large);
            sources.Add(small);
            if (graph.AddEdge(sources, atom, diff2Annotation))
            {
                addedEdge = true;
            }

            return(addedEdge);
        }
        //
        // There is one addition edge and two subtraction edges per set of 3 nodes.
        // Build the edges top-down from complete set of atoms down to singletons.
        //
        private void BuildEdges(List <Atomizer.AtomicRegion> atoms)
        {
            // Acquire an integer representation of the powerset of atomic nodes
            // This is memoized so it's fast.
            List <List <int> > powerset = Utilities.ConstructPowerSetWithNoEmpty(atoms.Count);

            //
            // For each layer (of particular subset size), establish all links.
            //
            int setIndex            = atoms.Count; // Skip the singletons
            int currSetSize         = 2;
            int prevLayerStartIndex = 0;

            while (setIndex < powerset.Count)
            {
                //
                // For each layer, look at each individual set and deconstruct
                //
                int layerSize = (int)Utilities.Combination(atoms.Count, currSetSize++);

                for (int layerIndex = 0; layerIndex < layerSize; layerIndex++)
                {
                    int currentIndex = setIndex + layerIndex;

                    // Look at each set
                    // Take away, in turn, each element in the set to construct the desired edges.
                    List <int> currentSet = powerset[currentIndex];
                    foreach (int val in currentSet)
                    {
                        // Make a copy of this set and remove the element
                        List <int> differenceSet = new List <int>(currentSet);
                        differenceSet.Remove(val);

                        int singletonIndex  = val; // the index of a singleton corresponds to its value
                        int differenceIndex = GetPowerSetIndex(powerset, differenceSet, prevLayerStartIndex, setIndex + layerSize);

                        //
                        // Build the edge for this 3 node combinations.
                        //

                        //
                        // A = (A \ a) + a
                        //
                        SimpleRegionEquation sumAnn = new SimpleRegionEquation(graph.vertices[currentIndex].data,
                                                                               graph.vertices[differenceIndex].data, OperationT.ADDITION, graph.vertices[singletonIndex].data);
                        List <int> sourceIndices = new List <int>();
                        sourceIndices.Add(differenceIndex);
                        sourceIndices.Add(singletonIndex);
                        graph.AddIndexEdge(sourceIndices, currentIndex, sumAnn);

                        //
                        // (A \ a) = A - a
                        //
                        SimpleRegionEquation diffAnn1 = new SimpleRegionEquation(graph.vertices[differenceIndex].data,
                                                                                 graph.vertices[currentIndex].data, OperationT.SUBTRACTION, graph.vertices[singletonIndex].data);
                        sourceIndices = new List <int>();
                        sourceIndices.Add(currentIndex);
                        sourceIndices.Add(singletonIndex);
                        graph.AddIndexEdge(sourceIndices, differenceIndex, diffAnn1);

                        //
                        // a = A - (A \ a)
                        //
                        SimpleRegionEquation diffAnn2 = new SimpleRegionEquation(graph.vertices[singletonIndex].data,
                                                                                 graph.vertices[currentIndex].data, OperationT.SUBTRACTION, graph.vertices[differenceIndex].data);
                        sourceIndices = new List <int>();
                        sourceIndices.Add(currentIndex);
                        sourceIndices.Add(differenceIndex);
                        graph.AddIndexEdge(sourceIndices, singletonIndex, diffAnn2);
                    }
                }
                prevLayerStartIndex = setIndex;
                setIndex           += layerSize;
            }
        }
        //
        // There is one addition edge and two subtraction edges per set of 3 nodes.
        // Build the edges top-down from complete set of atoms down to singletons.
        //
        private void BuildEdges(List <Atomizer.AtomicRegion> atoms, bool[] marked)
        {
            // We don't want edges connecting a singleton region to an 'empty' region.
            if (atoms.Count == 1)
            {
                return;
            }

            // The node for this set of list of atoms.
            Region atomsRegion = new Region(atoms);

            // Check to see if we have already visited this node and constructed the edges.
            int nodeIndex = graph.GetNodeIndex(atomsRegion);

            if (marked[nodeIndex])
            {
                return;
            }

            foreach (Atomizer.AtomicRegion atom in atoms)
            {
                List <Atomizer.AtomicRegion> atomsMinusAtom = new List <Atomizer.AtomicRegion>(atoms);
                atomsMinusAtom.Remove(atom);

                Region aMinus1Region = new Region(atomsMinusAtom);
                Region atomRegion    = new Region(atom);

                //
                // A = (A \ a) + a
                //
                SimpleRegionEquation sumAnnotation = new SimpleRegionEquation(atomsRegion, aMinus1Region, OperationT.ADDITION, atomRegion);
                List <Region>        sources       = new List <Region>();
                sources.Add(aMinus1Region);
                sources.Add(atomRegion);
                graph.AddEdge(sources, atomsRegion, sumAnnotation);

                //
                // (A \ a) = A - a
                //
                SimpleRegionEquation diff1Annotation = new SimpleRegionEquation(aMinus1Region, atomsRegion, OperationT.SUBTRACTION, atomRegion);
                sources = new List <Region>();
                sources.Add(atomsRegion);
                sources.Add(atomRegion);
                graph.AddEdge(sources, aMinus1Region, diff1Annotation);

                //
                // a = A - (A \ a)
                //
                SimpleRegionEquation diff2Annotation = new SimpleRegionEquation(atomRegion, atomsRegion, OperationT.SUBTRACTION, aMinus1Region);
                sources = new List <Region>();
                sources.Add(atomsRegion);
                sources.Add(aMinus1Region);
                graph.AddEdge(sources, atomRegion, diff2Annotation);

                //
                // Recursive call to construct edges with A \ a
                //
                BuildEdges(atomsMinusAtom, marked);
            }

            Debug.WriteLine(graph.EdgeCount());
            marked[nodeIndex] = true;
        }
 // Copy constructor
 public SimpleRegionEquation(SimpleRegionEquation simple) : this(simple.target, simple.bigger, simple.op, simple.smaller)
 {
 }
        //
        // 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);
        }
        //
        // Add edges
        //
        private bool CreateAddEdges(Region large, Region small, Region atom)
        {
            bool addedEdge = false;

            //
            // A = (A \ a) + a
            //
            SimpleRegionEquation sumAnnotation = new SimpleRegionEquation(large, small, OperationT.ADDITION, atom);
            List<Region> sources = new List<Region>();
            sources.Add(small);
            sources.Add(atom);
            if (graph.AddEdge(sources, large, sumAnnotation)) addedEdge = true;

            //
            // (A \ a) = A - a
            //
            SimpleRegionEquation diff1Annotation = new SimpleRegionEquation(small, large, OperationT.SUBTRACTION, atom);
            sources = new List<Region>();
            sources.Add(large);
            sources.Add(atom);
            if (graph.AddEdge(sources, small, diff1Annotation)) addedEdge = true;

            //
            // a = A - (A \ a)
            //
            SimpleRegionEquation diff2Annotation = new SimpleRegionEquation(atom, large, OperationT.SUBTRACTION, small);
            sources = new List<Region>();
            sources.Add(large);
            sources.Add(small);
            if (graph.AddEdge(sources, atom, diff2Annotation)) addedEdge = true;

            return addedEdge;
        }
示例#10
0
        //
        // 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));
        }
        //
        // There is one addition edge and two subtraction edges per set of 3 nodes.
        // Build the edges top-down from complete set of atoms down to singletons.
        //
        private void BuildEdges(List<Atomizer.AtomicRegion> atoms)
        {
            // Acquire an integer representation of the powerset of atomic nodes
            // This is memoized so it's fast.
            List<List<int>> powerset = Utilities.ConstructPowerSetWithNoEmpty(atoms.Count);

            //
            // For each layer (of particular subset size), establish all links.
            //
            int setIndex = atoms.Count; // Skip the singletons
            int currSetSize = 2;
            int prevLayerStartIndex = 0;
            while (setIndex < powerset.Count)
            {
                //
                // For each layer, look at each individual set and deconstruct
                //
                int layerSize = (int)Utilities.Combination(atoms.Count, currSetSize++);

                for (int layerIndex = 0; layerIndex < layerSize; layerIndex++)
                {
                    int currentIndex = setIndex + layerIndex;

                    // Look at each set
                    // Take away, in turn, each element in the set to construct the desired edges.
                    List<int> currentSet = powerset[currentIndex];
                    foreach (int val in currentSet)
                    {
                        // Make a copy of this set and remove the element
                        List<int> differenceSet = new List<int>(currentSet);
                        differenceSet.Remove(val);

                        int singletonIndex = val; // the index of a singleton corresponds to its value
                        int differenceIndex = GetPowerSetIndex(powerset, differenceSet, prevLayerStartIndex, setIndex + layerSize);

                        //
                        // Build the edge for this 3 node combinations.
                        //

                        //
                        // A = (A \ a) + a
                        //
                        SimpleRegionEquation sumAnn = new SimpleRegionEquation(graph.vertices[currentIndex].data,
                                                                               graph.vertices[differenceIndex].data, OperationT.ADDITION, graph.vertices[singletonIndex].data);
                        List<int> sourceIndices = new List<int>();
                        sourceIndices.Add(differenceIndex);
                        sourceIndices.Add(singletonIndex);
                        graph.AddIndexEdge(sourceIndices, currentIndex, sumAnn);

                        //
                        // (A \ a) = A - a
                        //
                        SimpleRegionEquation diffAnn1 = new SimpleRegionEquation(graph.vertices[differenceIndex].data,
                                                                                 graph.vertices[currentIndex].data, OperationT.SUBTRACTION, graph.vertices[singletonIndex].data);
                        sourceIndices = new List<int>();
                        sourceIndices.Add(currentIndex);
                        sourceIndices.Add(singletonIndex);
                        graph.AddIndexEdge(sourceIndices, differenceIndex, diffAnn1);

                        //
                        // a = A - (A \ a)
                        //
                        SimpleRegionEquation diffAnn2 = new SimpleRegionEquation(graph.vertices[singletonIndex].data,
                                                                                 graph.vertices[currentIndex].data, OperationT.SUBTRACTION, graph.vertices[differenceIndex].data);
                        sourceIndices = new List<int>();
                        sourceIndices.Add(currentIndex);
                        sourceIndices.Add(differenceIndex);
                        graph.AddIndexEdge(sourceIndices, singletonIndex, diffAnn2);
                    }
                }
                prevLayerStartIndex = setIndex;
                setIndex += layerSize;
            }
        }
        //
        // There is one addition edge and two subtraction edges per set of 3 nodes.
        // Build the edges top-down from complete set of atoms down to singletons.
        //
        private void BuildEdges(List<Atomizer.AtomicRegion> atoms, bool[] marked)
        {
            // We don't want edges connecting a singleton region to an 'empty' region.
            if (atoms.Count == 1) return;

            // The node for this set of list of atoms.
            Region atomsRegion = new Region(atoms);

            // Check to see if we have already visited this node and constructed the edges.
            int nodeIndex = graph.GetNodeIndex(atomsRegion);
            if (marked[nodeIndex]) return;

            foreach (Atomizer.AtomicRegion atom in atoms)
            {
                List<Atomizer.AtomicRegion> atomsMinusAtom = new List<Atomizer.AtomicRegion>(atoms);
                atomsMinusAtom.Remove(atom);

                Region aMinus1Region = new Region(atomsMinusAtom);
                Region atomRegion = new Region(atom);

                //
                // A = (A \ a) + a
                //
                SimpleRegionEquation sumAnnotation = new SimpleRegionEquation(atomsRegion, aMinus1Region, OperationT.ADDITION, atomRegion);
                List<Region> sources = new List<Region>();
                sources.Add(aMinus1Region);
                sources.Add(atomRegion);
                graph.AddEdge(sources, atomsRegion, sumAnnotation);

                //
                // (A \ a) = A - a
                //
                SimpleRegionEquation diff1Annotation = new SimpleRegionEquation(aMinus1Region, atomsRegion, OperationT.SUBTRACTION, atomRegion);
                sources = new List<Region>();
                sources.Add(atomsRegion);
                sources.Add(atomRegion);
                graph.AddEdge(sources, aMinus1Region, diff1Annotation);

                //
                // a = A - (A \ a)
                //
                SimpleRegionEquation diff2Annotation = new SimpleRegionEquation(atomRegion, atomsRegion, OperationT.SUBTRACTION, aMinus1Region);
                sources = new List<Region>();
                sources.Add(atomsRegion);
                sources.Add(aMinus1Region);
                graph.AddEdge(sources, atomRegion, diff2Annotation);

                //
                // Recursive call to construct edges with A \ a
                //
                BuildEdges(atomsMinusAtom, marked);
            }

            Debug.WriteLine(graph.EdgeCount());
            marked[nodeIndex] = true;
        }
示例#13
0
 // Copy constructor
 public SimpleRegionEquation(SimpleRegionEquation simple)
     : this(simple.target, simple.bigger, simple.op, simple.smaller)
 {
 }