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; }
// // 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; }