Esempio n. 1
0
        //
        // Recur through all of the shapes to pre-calculate their areas.
        //
        private void PreprocessShapeHierarchyAreas(KnownMeasurementsAggregator known, List <Figure> allFigures)
        {
            foreach (Figure theFigure in allFigures)
            {
                // Acquire the indices of the shape.
                IndexList figIndices = IndexList.AcquireAtomicRegionIndices(figureAtoms, theFigure.atoms);
                figureIndexMap[figIndices] = theFigure;

                double area = theFigure.GetArea(known);

                if (area > 0)
                {
                    ShapeRegion atomRegion = new ShapeRegion(theFigure);

                    SolutionAgg agg = new SolutionAgg();

                    // The equation is the identity equation.
                    agg.solEq       = new ComplexRegionEquation(atomRegion, atomRegion);
                    agg.solType     = SolutionAgg.SolutionType.COMPUTABLE;
                    agg.solArea     = area;
                    agg.atomIndices = IndexList.AcquireAtomicRegionIndices(figureAtoms, theFigure.atoms);

                    // Add this solution to the database.
                    solutions.AddSolution(agg);
                }
            }
        }
Esempio n. 2
0
        private void PreprocessAtomAreas(KnownMeasurementsAggregator known)
        {
            //
            // Preprocess any of the shape atoms to see if the area is computable.
            //
            for (int a = 0; a < figureAtoms.Count; a++)
            {
                ShapeAtomicRegion shapeAtom = figureAtoms[a] as ShapeAtomicRegion;
                if (shapeAtom != null)
                {
                    double area = shapeAtom.GetArea(known);

                    if (area > 0)
                    {
                        ShapeRegion atomRegion = new ShapeRegion(shapeAtom.shape);

                        SolutionAgg agg = new SolutionAgg();

                        // The equation is the identity equation.
                        agg.solEq       = new ComplexRegionEquation(atomRegion, atomRegion);
                        agg.solType     = SolutionAgg.SolutionType.COMPUTABLE;
                        agg.solArea     = area;
                        agg.atomIndices = new IndexList(a);

                        // Add this solution to the database.
                        solutions.AddSolution(agg);
                    }
                }
            }
        }
Esempio n. 3
0
        //
        // Is this problem (defined by the set of atomic regions) covered / defined by all the root shapes?
        //
        public bool IsProblemInteresting(List <Figure> roots, List <AtomicRegion> regions)
        {
            SolutionAgg solution = solutions.GetSolutionAgg(this.figureAtoms, regions);

            List <int>[] coverage = DetermineAtomCoverageOfShapes(roots);

            return(SolutionCoversRoots(coverage, solution, roots.Count));
        }
Esempio n. 4
0
        public override bool Equals(object obj)
        {
            SolutionAgg that = obj as SolutionAgg;

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

            return(Utilities.EqualOrderedSets(this.atomIndices.orderedIndices, that.atomIndices.orderedIndices));
        }
Esempio n. 5
0
        //
        // Acquire a single solution equation and area value.
        //
        public KeyValuePair <ComplexRegionEquation, double> GetSolution(List <Atomizer.AtomicRegion> figureAtoms, List <Atomizer.AtomicRegion> desiredRegions)
        {
            IndexList indices = IndexList.AcquireAtomicRegionIndices(figureAtoms, desiredRegions);

            SolutionAgg solutionAgg = null;

            if (!solutions.TryGetValue(indices, out solutionAgg))
            {
                throw new ArgumentException("Could not find a solution in the database.");
            }

            return(new KeyValuePair <ComplexRegionEquation, double>(solutionAgg.solEq, solutionAgg.solArea));
        }
Esempio n. 6
0
        //
        // Does this one solution cover all root shapes.
        //
        private bool SolutionCoversRoots(List <int>[] coverage, SolutionAgg solution, int numShapes)
        {
            List <int> shapesCovered = new List <int>();

            // Collect all shape-covered indices
            foreach (int index in solution.atomIndices.orderedIndices)
            {
                Utilities.AddUniqueList <int>(shapesCovered, coverage[index]);
            }

            // If we covered all indices, the solution covers.
            return(shapesCovered.Count == numShapes);
        }
Esempio n. 7
0
        //
        // Acquire a single solution equation and area value.
        //
        public SolutionAgg GetSolutionAgg(List <Atomizer.AtomicRegion> figureAtoms, List <Atomizer.AtomicRegion> desiredRegions)
        {
            IndexList indices = IndexList.AcquireAtomicRegionIndices(figureAtoms, desiredRegions);

            SolutionAgg solutionAgg = null;

            if (!solutions.TryGetValue(indices, out solutionAgg))
            {
                throw new ArgumentException("Could not find a solution in the database.");
            }

            return(solutionAgg);
        }
Esempio n. 8
0
        //
        // Catalyst routine to the recursive solver: returns solution equation and actual area.
        //
        public void SolveAll(KnownMeasurementsAggregator known, List <Figure> allFigures)
        {
            PreprocessAtomAreas(known);
            PreprocessShapeHierarchyAreas(known, allFigures);

            //
            // Using the atomic regions, explore all of the top-most shapes recursively.
            //
            for (int a = 0; a < figureAtoms.Count; a++)
            {
                IndexList   atomIndexList = new IndexList(a);
                SolutionAgg agg           = null;

                solutions.TryGetValue(atomIndexList, out agg);

                if (agg == null)
                {
                    Figure topShape = figureAtoms[a].GetTopMostShape();

                    // Shape Region?
                    ComplexRegionEquation startEq = new ComplexRegionEquation(null, new ShapeRegion(topShape));
                    double outerArea = topShape.GetArea(known);

                    // Invoke the recursive solver using the outermost region and catalyst.
                    //ProcessChildrenShapes(a, new ShapeRegion(topShape), topShape.Hierarchy(),
                    //             new List<TreeNode<Figure>>(),
                    //             startEq, outerArea, known);
                    SolveHelper(new ShapeRegion(topShape),
                                topShape.Hierarchy().Children(),
                                startEq, outerArea, known);
                }
                else if (agg.solType == SolutionAgg.SolutionType.COMPUTABLE)
                {
                    //solutions[atomIndexList] = agg;
                }
                else if (agg.solType == SolutionAgg.SolutionType.INCOMPUTABLE)
                {
                    //solutions[atomIndexList] = agg;
                }
                else if (agg.solType == SolutionAgg.SolutionType.UNKNOWN)
                {
                    //TBD
                }
            }

            //
            // Subtraction of shapes extracts as many atomic regions as possible of the strict atomic regions, now compose those together.
            //
            ComposeAllRegions();
        }
Esempio n. 9
0
        //
        // Given a shape that owns the atomic region, recur through the resulting atomic region
        //
        // From
        //
        public void SolveHelper(Region currOuterRegion, List <TreeNode <Figure> > currHierarchyRoots,
                                ComplexRegionEquation currEquation, double currArea, KnownMeasurementsAggregator known)
        {
            IndexList currOuterRegionIndices = IndexList.AcquireAtomicRegionIndices(figureAtoms, currOuterRegion.atoms);

            // There is no outer region
            if (currOuterRegionIndices.IsEmpty())
            {
                return;
            }

            //
            // We have reached this point by subtracting shapes, therefore, we have an equation.
            //
            SolutionAgg agg = new SolutionAgg();

            agg.solEq = new ComplexRegionEquation(currEquation);
            agg.solEq.SetTarget(currOuterRegion);
            agg.solType     = currArea < 0 ? SolutionAgg.SolutionType.INCOMPUTABLE : SolutionAgg.SolutionType.COMPUTABLE;
            agg.solArea     = currArea;
            agg.atomIndices = currOuterRegionIndices;

            //
            // Add this solution to the database.
            //
            solutions.AddSolution(agg);

            // Was this equation solving for a single atomic region? If so, leave.
            if (currOuterRegion.IsAtomic())
            {
                return;
            }

            //
            // Recursively explore EACH sub-shape root inside of the outer region.
            //
            foreach (TreeNode <Figure> shapeNode in currHierarchyRoots)
            {
                // A list omitting this shape
                List <TreeNode <Figure> > updatedHierarchy = new List <TreeNode <Figure> >(currHierarchyRoots);
                updatedHierarchy.Remove(shapeNode);

                // Process this shape
                ProcessShape(currOuterRegion, shapeNode, updatedHierarchy, currEquation, currArea, known);

                // Process the children
                ProcessChildrenShapes(currOuterRegion, shapeNode, updatedHierarchy, currEquation, currArea, known);
            }
        }
Esempio n. 10
0
        //private void PreprocessShapeHierarchyAreas(KnownMeasurementsAggregator known, TreeNode<Figure> currentRoot)
        //{
        //    Figure theFigure = currentRoot.GetData();

        //    // Acquire the indices of the shape.
        //    IndexList figIndices = IndexList.AcquireAtomicRegionIndices(figureAtoms, theFigure.atoms);
        //    figureIndexMap[figIndices] = theFigure;

        //    double area = theFigure.GetArea(known);

        //    if (area > 0)
        //    {
        //        ShapeRegion atomRegion = new ShapeRegion(theFigure);

        //        SolutionAgg agg = new SolutionAgg();

        //        // The equation is the identity equation.
        //        agg.solEq = new ComplexRegionEquation(atomRegion, atomRegion);
        //        agg.solType = SolutionAgg.SolutionType.COMPUTABLE;
        //        agg.solArea = area;
        //        agg.atomIndices = IndexList.AcquireAtomicRegionIndices(figureAtoms, theFigure.atoms);

        //        // Add this solution to the database.
        //        solutions.AddSolution(agg);
        //    }

        //    foreach (TreeNode<Figure> child in currentRoot.Children())
        //    {
        //        PreprocessShapeHierarchyAreas(known, child);
        //    }
        //}

        //
        // Combine (through addition) any / all set of two equations in which there is no shared atomic region:
        //    (0 1 2) + (5 6) = (0 1 2 5 6)
        //
        // worklist-style fixpoint construction
        //
        private void ComposeAllRegions()
        {
            List <SolutionAgg> worklist = new List <SolutionAgg>(solutions.GetComputableSolutions());

            while (worklist.Any())
            {
                SolutionAgg currentSol = worklist[0];
                worklist.RemoveAt(0);

                foreach (SolutionAgg otherSol in solutions.GetSolutions())
                {
                    HandleComposition(worklist, currentSol, otherSol);
                }

                solutions.AddSolution(currentSol);
            }
        }
Esempio n. 11
0
        private void HandleComposition(List <SolutionAgg> worklist, SolutionAgg first, SolutionAgg second)
        {
            // Addition of the two regions.
            SolutionAgg unionSol = HandleUnion(first, second);

            if (unionSol != null)
            {
                AddToWorklist(worklist, unionSol);
            }
            else
            {
                // Subtraction of the two regions.
                SolutionAgg diffSol = HandleDifference(first, second);
                if (diffSol != null)
                {
                    AddToWorklist(worklist, diffSol);
                }
            }
        }
Esempio n. 12
0
        //
        // Adds an equation, if it does not exist.
        // If an equation for the region already exists, take the shortest one or the one that is computable.
        //
        private bool AddSolution(Dictionary <IndexList, SolutionAgg> solDictionary, SolutionAgg that)
        {
            //
            // Does this equation NOT exist in the database?
            //
            SolutionAgg existentAgg = null;

            if (!solDictionary.TryGetValue(that.atomIndices, out existentAgg))
            {
                // Add this solution to the database.
                solDictionary.Add(that.atomIndices, that);

                return(true);
            }

            //
            // The equation already exists in the database.
            //
            return(UpdateSolution(solDictionary, existentAgg, that));
        }
Esempio n. 13
0
        private SolutionAgg HandleDifference(SolutionAgg first, SolutionAgg second)
        {
            // Can we combine the currentSol with this existent solution?
            IndexList diffIndices = IndexList.DifferenceIndices(first.atomIndices, second.atomIndices);

            // Disjoint union not possible.
            if (diffIndices == null)
            {
                return(null);
            }

            //
            // Can combine; create a new solution / equation with addition.
            //
            SolutionAgg newSum = new SolutionAgg();

            newSum.atomIndices = diffIndices;
            newSum.solType     = first.solType == SolutionAgg.SolutionType.COMPUTABLE &&
                                 second.solType == SolutionAgg.SolutionType.COMPUTABLE ? SolutionAgg.SolutionType.COMPUTABLE : SolutionAgg.SolutionType.INCOMPUTABLE;
            if (newSum.solType == SolutionAgg.SolutionType.INCOMPUTABLE)
            {
                newSum.solArea = -1;
            }
            else
            {
                newSum.solArea = first.solArea > second.solArea ? first.solArea - second.solArea : second.solArea - first.solArea;
            }

            if (first.atomIndices.Count > second.atomIndices.Count)
            {
                newSum.solEq = new ComplexRegionEquation(MakeRegion(diffIndices.orderedIndices),
                                                         new ComplexRegionEquation.Binary(first.solEq.target, OperationT.SUBTRACTION, second.solEq.target));
            }
            else
            {
                newSum.solEq = new ComplexRegionEquation(MakeRegion(diffIndices.orderedIndices),
                                                         new ComplexRegionEquation.Binary(second.solEq.target, OperationT.SUBTRACTION, first.solEq.target));
            }

            return(newSum);
        }
Esempio n. 14
0
        //
        // Given that both the old and new solutions are computable, how to do we prefer one solution over another?
        //
        private bool PreferNewComputableSolution(SolutionAgg existent, SolutionAgg newSolution)
        {
            bool exisDefShapes = existent.solEq.DefinedByShapes();
            bool newDefShapes  = newSolution.solEq.DefinedByShapes();

            //
            // Favor a solution consisting of all shapes over the alternative.
            //
            if (exisDefShapes && !newDefShapes)
            {
                return(false);
            }
            if (!exisDefShapes && newDefShapes)
            {
                return(true);
            }

            //
            // Favor a shorter solution.
            //
            return(existent.solEq.Length > newSolution.solEq.Length);
        }
Esempio n. 15
0
        //
        // If the solution is already in the database, update the solution in the database (if needed).
        // otherwise, add this solution to the worklist.
        //
        private void AddToWorklist(List <SolutionAgg> worklist, SolutionAgg solution)
        {
            //// Guarantee we may add this to the aorklist for processing.
            //if (!solutions.Contains(solution))
            //{
            //    worklist.Add(solution);
            //    return;
            //}

            //
            // If the solution is already in the database, update the solution in the database (if needed).
            //
            if (solutions.AddSolution(solution))
            {
                // The solution may be in the worklist for processing; update accordingly.
                int worklistIndex = worklist.IndexOf(solution);
                if (worklistIndex != -1)
                {
                    worklist[worklistIndex] = solution;
                }
            }
        }
Esempio n. 16
0
        private SolutionAgg HandleUnion(SolutionAgg first, SolutionAgg second)
        {
            // Can we combine the currentSol with this existent solution?
            IndexList unionIndices = IndexList.UnionIndices(first.atomIndices, second.atomIndices);

            // Disjoint union not possible.
            if (unionIndices == null)
            {
                return(null);
            }

            //
            // Can combine; create a new solution / equation with addition.
            //
            SolutionAgg newSum = new SolutionAgg();

            newSum.atomIndices = unionIndices;
            newSum.solType     = first.solType == SolutionAgg.SolutionType.COMPUTABLE &&
                                 second.solType == SolutionAgg.SolutionType.COMPUTABLE ? SolutionAgg.SolutionType.COMPUTABLE : SolutionAgg.SolutionType.INCOMPUTABLE;
            newSum.solArea = newSum.solType == SolutionAgg.SolutionType.COMPUTABLE ? first.solArea + second.solArea : -1;
            newSum.solEq   = new ComplexRegionEquation(MakeRegion(unionIndices.orderedIndices),
                                                       new ComplexRegionEquation.Binary(first.solEq.target, OperationT.ADDITION, second.solEq.target));
            return(newSum);
        }
Esempio n. 17
0
 //
 // If the solution exists in the root solutions as incomputable, seek a solution from the extended
 //
 public bool TryGetValue(IndexList indices, out SolutionAgg solutionAgg)
 {
     return solutions.TryGetValue(indices, out solutionAgg);
 }
Esempio n. 18
0
        //
        // Given that both the old and new solutions are computable, how to do we prefer one solution over another?
        //
        private bool PreferNewComputableSolution(SolutionAgg existent, SolutionAgg newSolution)
        {
            bool exisDefShapes = existent.solEq.DefinedByShapes();
            bool newDefShapes = newSolution.solEq.DefinedByShapes();

            //
            // Favor a solution consisting of all shapes over the alternative.
            //
            if (exisDefShapes && !newDefShapes) return false;
            if (!exisDefShapes && newDefShapes) return true;

            //
            // Favor a shorter solution.
            //
            return existent.solEq.Length > newSolution.solEq.Length;
        }
Esempio n. 19
0
        //
        // Adds an equation, if it does not exist.
        // If an equation for the region already exists, take the shortest one or the one that is computable.
        //
        private bool AddSolution(Dictionary<IndexList, SolutionAgg> solDictionary, SolutionAgg that)
        {
            //
            // Does this equation NOT exist in the database?
            //
            SolutionAgg existentAgg = null;
            if (!solDictionary.TryGetValue(that.atomIndices, out existentAgg))
            {
                // Add this solution to the database.
                solDictionary.Add(that.atomIndices, that);

                return true;
            }

            //
            // The equation already exists in the database.
            //
            return UpdateSolution(solDictionary, existentAgg, that);
        }
Esempio n. 20
0
        //
        // If the solution is already in the database, update the solution in the database (if needed).
        // otherwise, add this solution to the worklist.
        //
        private void AddToWorklist(List<SolutionAgg> worklist, SolutionAgg solution)
        {
            //// Guarantee we may add this to the aorklist for processing.
            //if (!solutions.Contains(solution))
            //{
            //    worklist.Add(solution);
            //    return;
            //}

            //
            // If the solution is already in the database, update the solution in the database (if needed).
            //
            if (solutions.AddSolution(solution))
            {
                // The solution may be in the worklist for processing; update accordingly.
                int worklistIndex = worklist.IndexOf(solution);
                if (worklistIndex != -1)
                {
                    worklist[worklistIndex] = solution;
                }
            }
        }
Esempio n. 21
0
        //
        // The equation already exists in the database.
        //
        private bool UpdateSolution(Dictionary <IndexList, SolutionAgg> solDictionary, SolutionAgg existentAgg, SolutionAgg that)
        {
            // Favor a straight-forward calculation of the area (no manipulations to acquire the value).
            if (existentAgg.IsDirectArea())
            {
                return(false);
            }

            // Favor a coomputable equation over incomputable.
            if (existentAgg.solType == SolutionAgg.SolutionType.INCOMPUTABLE && that.solType == SolutionAgg.SolutionType.COMPUTABLE)
            {
                solDictionary[that.atomIndices] = that;
                return(true);
            }
            // Again, favor a computable solution over not.
            else if (existentAgg.solType == SolutionAgg.SolutionType.COMPUTABLE && that.solType == SolutionAgg.SolutionType.INCOMPUTABLE)
            {
                // NO-OP
            }
            // The computability is the same for both equations.
            else if (existentAgg.solType == that.solType || existentAgg.solType == SolutionAgg.SolutionType.UNKNOWN)
            {
                if (!Utilities.CompareValues(existentAgg.solArea, that.solArea))
                {
                    throw new Exception("Area for region " + existentAgg.atomIndices.ToString() +
                                        " was calculated now as (" + existentAgg.solArea + ") AND before (" + that.solArea + ")");
                }

                if (PreferNewComputableSolution(existentAgg, that))
                {
                    solDictionary[that.atomIndices] = that;
                    return(true);
                }
            }

            return(false);
        }
Esempio n. 22
0
        //
        // Does this one solution cover all root shapes.
        //
        private bool SolutionCoversRoots(List<int>[] coverage, SolutionAgg solution, int numShapes)
        {
            List<int> shapesCovered = new List<int>();

            // Collect all shape-covered indices
            foreach (int index in solution.atomIndices.orderedIndices)
            {
                Utilities.AddUniqueList<int>(shapesCovered, coverage[index]);
            }

            // If we covered all indices, the solution covers.
            return shapesCovered.Count == numShapes;
        }
Esempio n. 23
0
        //
        // The equation already exists in the database.
        //
        private bool UpdateSolution(Dictionary<IndexList, SolutionAgg> solDictionary, SolutionAgg existentAgg, SolutionAgg that)
        {
            // Favor a straight-forward calculation of the area (no manipulations to acquire the value).
            if (existentAgg.IsDirectArea()) return false;

            // Favor a coomputable equation over incomputable.
            if (existentAgg.solType == SolutionAgg.SolutionType.INCOMPUTABLE && that.solType == SolutionAgg.SolutionType.COMPUTABLE)
            {
                solDictionary[that.atomIndices] = that;
                return true;
            }
            // Again, favor a computable solution over not.
            else if (existentAgg.solType == SolutionAgg.SolutionType.COMPUTABLE && that.solType == SolutionAgg.SolutionType.INCOMPUTABLE)
            {
                // NO-OP
            }
            // The computability is the same for both equations.
            else if (existentAgg.solType == that.solType || existentAgg.solType == SolutionAgg.SolutionType.UNKNOWN)
            {
                if (!Utilities.CompareValues(existentAgg.solArea, that.solArea))
                {
                    throw new Exception("Area for region " + existentAgg.atomIndices.ToString() +
                                        " was calculated now as (" + existentAgg.solArea + ") AND before (" + that.solArea + ")");
                }

                if (PreferNewComputableSolution(existentAgg, that))
                {
                    solDictionary[that.atomIndices] = that;
                    return true;
                }
            }

            return false;
        }
Esempio n. 24
0
 public bool Contains(SolutionAgg solution)
 {
     return(Contains(solution.atomIndices));
 }
Esempio n. 25
0
        //
        // Recur through all of the shapes to pre-calculate their areas.
        //
        private void PreprocessShapeHierarchyAreas(KnownMeasurementsAggregator known, List<Figure> allFigures)
        {
            foreach (Figure theFigure in allFigures)
            {
                // Acquire the indices of the shape.
                IndexList figIndices = IndexList.AcquireAtomicRegionIndices(figureAtoms, theFigure.atoms);
                figureIndexMap[figIndices] = theFigure;

                double area = theFigure.GetArea(known);

                if (area > 0)
                {
                    ShapeRegion atomRegion = new ShapeRegion(theFigure);

                    SolutionAgg agg = new SolutionAgg();

                    // The equation is the identity equation.
                    agg.solEq = new ComplexRegionEquation(atomRegion, atomRegion);
                    agg.solType = SolutionAgg.SolutionType.COMPUTABLE;
                    agg.solArea = area;
                    agg.atomIndices = IndexList.AcquireAtomicRegionIndices(figureAtoms, theFigure.atoms);

                    // Add this solution to the database.
                    solutions.AddSolution(agg);
                }
            }
        }
Esempio n. 26
0
 public bool AddSolution(SolutionAgg that)
 {
     return AddSolution(solutions, that);
 }
Esempio n. 27
0
 public bool Contains(SolutionAgg solution)
 {
     return Contains(solution.atomIndices);
 }
Esempio n. 28
0
        private void HandleComposition(List<SolutionAgg> worklist, SolutionAgg first, SolutionAgg second)
        {
            // Addition of the two regions.
            SolutionAgg unionSol = HandleUnion(first, second);

            if (unionSol != null)
            {
                AddToWorklist(worklist, unionSol);
            }
            else
            {
                // Subtraction of the two regions.
                SolutionAgg diffSol = HandleDifference(first, second);
                if (diffSol != null) AddToWorklist(worklist, diffSol);
            }
        }
Esempio n. 29
0
 public bool AddSolution(SolutionAgg that)
 {
     return(AddSolution(solutions, that));
 }
Esempio n. 30
0
 //
 // If the solution exists in the root solutions as incomputable, seek a solution from the extended
 //
 public bool TryGetValue(IndexList indices, out SolutionAgg solutionAgg)
 {
     return(solutions.TryGetValue(indices, out solutionAgg));
 }
Esempio n. 31
0
        private SolutionAgg HandleUnion(SolutionAgg first, SolutionAgg second)
        {
            // Can we combine the currentSol with this existent solution?
            IndexList unionIndices = IndexList.UnionIndices(first.atomIndices, second.atomIndices);

            // Disjoint union not possible.
            if (unionIndices == null) return null;

            //
            // Can combine; create a new solution / equation with addition.
            //
            SolutionAgg newSum = new SolutionAgg();
            newSum.atomIndices = unionIndices;
            newSum.solType = first.solType == SolutionAgg.SolutionType.COMPUTABLE &&
                             second.solType == SolutionAgg.SolutionType.COMPUTABLE ? SolutionAgg.SolutionType.COMPUTABLE : SolutionAgg.SolutionType.INCOMPUTABLE;
            newSum.solArea = newSum.solType == SolutionAgg.SolutionType.COMPUTABLE ? first.solArea + second.solArea : -1;
            newSum.solEq = new ComplexRegionEquation(MakeRegion(unionIndices.orderedIndices),
                                                     new ComplexRegionEquation.Binary(first.solEq.target, OperationT.ADDITION, second.solEq.target));
            return newSum;
        }
Esempio n. 32
0
        //
        // Given a shape that owns the atomic region, recur through the resulting atomic region
        //
        // From
        //
        public void SolveHelper(Region currOuterRegion, List<TreeNode<Figure>> currHierarchyRoots,
                                ComplexRegionEquation currEquation, double currArea, KnownMeasurementsAggregator known)
        {
            IndexList currOuterRegionIndices = IndexList.AcquireAtomicRegionIndices(figureAtoms, currOuterRegion.atoms);

            // There is no outer region
            if (currOuterRegionIndices.IsEmpty()) return;

            //
            // We have reached this point by subtracting shapes, therefore, we have an equation.
            //
            SolutionAgg agg = new SolutionAgg();

            agg.solEq = new ComplexRegionEquation(currEquation);
            agg.solEq.SetTarget(currOuterRegion);
            agg.solType = currArea < 0 ? SolutionAgg.SolutionType.INCOMPUTABLE : SolutionAgg.SolutionType.COMPUTABLE;
            agg.solArea = currArea;
            agg.atomIndices = currOuterRegionIndices;

            //
            // Add this solution to the database.
            //
            solutions.AddSolution(agg);

            // Was this equation solving for a single atomic region? If so, leave.
            if (currOuterRegion.IsAtomic()) return;

            //
            // Recursively explore EACH sub-shape root inside of the outer region.
            //
            foreach (TreeNode<Figure> shapeNode in currHierarchyRoots)
            {
                // A list omitting this shape
                List<TreeNode<Figure>> updatedHierarchy = new List<TreeNode<Figure>>(currHierarchyRoots);
                updatedHierarchy.Remove(shapeNode);

                // Process this shape
                ProcessShape(currOuterRegion, shapeNode, updatedHierarchy, currEquation, currArea, known);

                // Process the children
                ProcessChildrenShapes(currOuterRegion, shapeNode, updatedHierarchy, currEquation, currArea, known);
            }
        }
Esempio n. 33
0
        private SolutionAgg HandleDifference(SolutionAgg first, SolutionAgg second)
        {
            // Can we combine the currentSol with this existent solution?
            IndexList diffIndices = IndexList.DifferenceIndices(first.atomIndices, second.atomIndices);

            // Disjoint union not possible.
            if (diffIndices == null) return null;

            //
            // Can combine; create a new solution / equation with addition.
            //
            SolutionAgg newSum = new SolutionAgg();
            newSum.atomIndices = diffIndices;
            newSum.solType = first.solType == SolutionAgg.SolutionType.COMPUTABLE &&
                             second.solType == SolutionAgg.SolutionType.COMPUTABLE ? SolutionAgg.SolutionType.COMPUTABLE : SolutionAgg.SolutionType.INCOMPUTABLE;
            if (newSum.solType == SolutionAgg.SolutionType.INCOMPUTABLE)
            {
                newSum.solArea = -1;
            }
            else
            {
                newSum.solArea = first.solArea > second.solArea ? first.solArea - second.solArea : second.solArea - first.solArea;
            }

            if (first.atomIndices.Count > second.atomIndices.Count)
            {
                newSum.solEq = new ComplexRegionEquation(MakeRegion(diffIndices.orderedIndices),
                                                         new ComplexRegionEquation.Binary(first.solEq.target, OperationT.SUBTRACTION, second.solEq.target));
            }
            else
            {
                newSum.solEq = new ComplexRegionEquation(MakeRegion(diffIndices.orderedIndices),
                                                         new ComplexRegionEquation.Binary(second.solEq.target, OperationT.SUBTRACTION, first.solEq.target));
            }

            return newSum;
        }
Esempio n. 34
0
        private void PreprocessAtomAreas(KnownMeasurementsAggregator known)
        {
            //
            // Preprocess any of the shape atoms to see if the area is computable.
            //
            for (int a = 0; a < figureAtoms.Count; a++)
            {
                ShapeAtomicRegion shapeAtom = figureAtoms[a] as ShapeAtomicRegion;
                if (shapeAtom != null)
                {
                    double area = shapeAtom.GetArea(known);

                    if (area > 0)
                    {
                        ShapeRegion atomRegion = new ShapeRegion(shapeAtom.shape);

                        SolutionAgg agg = new SolutionAgg();

                        // The equation is the identity equation.
                        agg.solEq = new ComplexRegionEquation(atomRegion, atomRegion);
                        agg.solType = SolutionAgg.SolutionType.COMPUTABLE;
                        agg.solArea = area;
                        agg.atomIndices = new IndexList(a);

                        // Add this solution to the database.
                        solutions.AddSolution(agg);
                    }
                }
            }
        }