|
@@ -3,8 +3,7 @@ package com.pact;
|
|
import java.util.HashSet;
|
|
import java.util.HashSet;
|
|
import java.util.Iterator;
|
|
import java.util.Iterator;
|
|
|
|
|
|
-public class Node
|
|
|
|
-{
|
|
|
|
|
|
+public class Node {
|
|
Node parent;
|
|
Node parent;
|
|
String venn;
|
|
String venn;
|
|
HashSet<Node> children;
|
|
HashSet<Node> children;
|
|
@@ -13,11 +12,11 @@ public class Node
|
|
|
|
|
|
public Node(Node p, String s) {
|
|
public Node(Node p, String s) {
|
|
this.linkNode = null;
|
|
this.linkNode = null;
|
|
- this.linkNodes = new HashSet();
|
|
|
|
|
|
+ this.linkNodes = new HashSet<>();
|
|
this.venn = s;
|
|
this.venn = s;
|
|
this.parent = p;
|
|
this.parent = p;
|
|
|
|
|
|
- this.children = new HashSet();
|
|
|
|
|
|
+ this.children = new HashSet<>();
|
|
if (s.length() > 1)
|
|
if (s.length() > 1)
|
|
setChildren(s);
|
|
setChildren(s);
|
|
}
|
|
}
|
|
@@ -82,54 +81,36 @@ public class Node
|
|
sibs.remove(this);
|
|
sibs.remove(this);
|
|
return sibs;
|
|
return sibs;
|
|
}
|
|
}
|
|
- return new HashSet();
|
|
|
|
|
|
+ return new HashSet<>();
|
|
}
|
|
}
|
|
|
|
|
|
- public boolean equals(Node node)
|
|
|
|
- {
|
|
|
|
|
|
+ public boolean equals(Object obj) {
|
|
|
|
+ if (!(obj instanceof Node)) return false;
|
|
|
|
+
|
|
|
|
+ Node node = (Node) obj;
|
|
String nodeVenn = node.getVenn();
|
|
String nodeVenn = node.getVenn();
|
|
- if ((nodeVenn.length() == 1) && (this.venn.length() == nodeVenn.length())) {
|
|
|
|
|
|
+
|
|
|
|
+ // Case for leaf nodes
|
|
|
|
+ if ((nodeVenn.length() == 1) && (this.venn.length() == 1)) {
|
|
return nodeVenn.equals(this.venn);
|
|
return nodeVenn.equals(this.venn);
|
|
}
|
|
}
|
|
|
|
|
|
- int itCount = 0;
|
|
|
|
- int eqCount = 0;
|
|
|
|
|
|
+ if (children.size() != node.children.size()){
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Check to make sure all of my children exist in node's children
|
|
for (Node theirChild : node.children) {
|
|
for (Node theirChild : node.children) {
|
|
- itCount++;
|
|
|
|
|
|
+ boolean foundMatch = false;
|
|
for (Node myChild : this.children) {
|
|
for (Node myChild : this.children) {
|
|
if (myChild.equals(theirChild)) {
|
|
if (myChild.equals(theirChild)) {
|
|
- eqCount++;
|
|
|
|
|
|
+ foundMatch = true;
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+ if(!foundMatch) return false;
|
|
}
|
|
}
|
|
-
|
|
|
|
- if (itCount != eqCount) {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- itCount = 0;
|
|
|
|
- eqCount = 0;
|
|
|
|
- Iterator it = this.children.iterator();
|
|
|
|
- while (it.hasNext()) {
|
|
|
|
- Iterator nIt = node.children.iterator();
|
|
|
|
- Node toCheck = (Node)it.next();
|
|
|
|
- itCount++;
|
|
|
|
- while (nIt.hasNext()) {
|
|
|
|
- if (toCheck.equals((Node)nIt.next())) {
|
|
|
|
- eqCount++;
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return itCount == eqCount;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public boolean equals(Object o)
|
|
|
|
- {
|
|
|
|
- return equals((Node)o);
|
|
|
|
|
|
+ return true;
|
|
}
|
|
}
|
|
|
|
|
|
// @Override
|
|
// @Override
|
|
@@ -146,6 +127,24 @@ public class Node
|
|
//
|
|
//
|
|
// }
|
|
// }
|
|
|
|
|
|
|
|
+ public void deepSearch(Node node, HashSet<NodePair> h) {
|
|
|
|
+ HashSet<NodePair> first_result = searchBothNodePair(node);
|
|
|
|
+ for(NodePair res : first_result) {
|
|
|
|
+ h.add(res);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for(Node child : node.children) {
|
|
|
|
+ deepSearch(child, h);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public Node root() {
|
|
|
|
+ if (getSiblings().isEmpty()) {
|
|
|
|
+ return this;
|
|
|
|
+ }
|
|
|
|
+ return this.parent.root();
|
|
|
|
+ }
|
|
|
|
+
|
|
private int getNumAreas() {
|
|
private int getNumAreas() {
|
|
int count = 0;
|
|
int count = 0;
|
|
for (int i = 0; i < this.venn.length(); i++) {
|
|
for (int i = 0; i < this.venn.length(); i++) {
|
|
@@ -156,63 +155,152 @@ public class Node
|
|
return count;
|
|
return count;
|
|
}
|
|
}
|
|
|
|
|
|
- public HashSet<Node> reducedCombine(Node node) {
|
|
|
|
- HashSet result = new HashSet();
|
|
|
|
|
|
+ private void search(Node node, HashSet<NodePair> h) {
|
|
|
|
+ if (equals(node)) {
|
|
|
|
+ this.linkNodes.add(node);
|
|
|
|
+ node.linkNodes.add(this);
|
|
|
|
+ h.add(new NodePair(this, node));
|
|
|
|
+ } else {
|
|
|
|
+ for(Node child : children) {
|
|
|
|
+ child.search(node, h);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
|
|
- if (oneAreaShared(this, node)) {
|
|
|
|
- result.add(combineAtRoot(node));
|
|
|
|
- return result;
|
|
|
|
|
|
+ private HashSet<NodePair> searchBothNodePair(Node node) {
|
|
|
|
+ HashSet<NodePair> sResult = new HashSet<>();
|
|
|
|
+ search(node, sResult);
|
|
|
|
+
|
|
|
|
+ HashSet<NodePair> nsResult = new HashSet<>();
|
|
|
|
+ node.search(this, nsResult);
|
|
|
|
+
|
|
|
|
+ for (NodePair curr : nsResult) {
|
|
|
|
+ boolean inSet = inSet(curr, sResult);
|
|
|
|
+ if (!inSet) {
|
|
|
|
+ sResult.add(curr);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- HashSet compCombine = combine(node);
|
|
|
|
- Iterator it = compCombine.iterator();
|
|
|
|
|
|
+ return sResult;
|
|
|
|
+ }
|
|
|
|
|
|
- if (!it.hasNext()) {
|
|
|
|
- return result;
|
|
|
|
|
|
+ private boolean inSet(NodePair n, Iterable<NodePair> it) {
|
|
|
|
+ for (NodePair nodes : it) {
|
|
|
|
+ if (n.equals(nodes)) {
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- Node curr = (Node)it.next();
|
|
|
|
- int smallest = curr.getNumAreas();
|
|
|
|
- result.add(curr);
|
|
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
|
|
- while (it.hasNext()) {
|
|
|
|
- Node curr1 = (Node)it.next();
|
|
|
|
- int currAreas = curr1.getNumAreas();
|
|
|
|
- if (currAreas < smallest) {
|
|
|
|
- smallest = currAreas;
|
|
|
|
- result.clear();
|
|
|
|
- result.add(curr1);
|
|
|
|
- } else if (currAreas == smallest) {
|
|
|
|
- result.add(curr1);
|
|
|
|
|
|
+ private boolean isIn(Node node) {
|
|
|
|
+ if (this == node) {
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ for (Node child : this.children) {
|
|
|
|
+ if (child.isIn(node)) {
|
|
|
|
+ return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- return removeDuplicates(result);
|
|
|
|
|
|
+ return false;
|
|
}
|
|
}
|
|
|
|
|
|
- private HashSet<Node> removeDuplicates(HashSet<Node> h) {
|
|
|
|
- Iterator it = h.iterator();
|
|
|
|
- HashSet result = new HashSet();
|
|
|
|
- while (it.hasNext()) {
|
|
|
|
- Node curr = (Node)it.next();
|
|
|
|
- if (!contains(curr, result)) {
|
|
|
|
- result.add(curr);
|
|
|
|
|
|
+ private Node hasLink() {
|
|
|
|
+ HashSet<Node> sibs = getSiblings();
|
|
|
|
+ for (Node curr : sibs) {
|
|
|
|
+ if (!curr.linkNodes.isEmpty()) {
|
|
|
|
+ return curr;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- return result;
|
|
|
|
|
|
+ return null;
|
|
}
|
|
}
|
|
|
|
|
|
- private static boolean oneAreaShared(Node node1, Node node2)
|
|
|
|
- {
|
|
|
|
- HashSet<Nodes> result = new HashSet<>();
|
|
|
|
- node2.deepSearch(node1, result);
|
|
|
|
- HashSet<Nodes> largest = getLNodes(result);
|
|
|
|
- if (largest.isEmpty()) {
|
|
|
|
|
|
+ private boolean unshared() {
|
|
|
|
+ if (this.linkNodes.isEmpty()) {
|
|
|
|
+ if(this.children.isEmpty()) {
|
|
|
|
+ return true;
|
|
|
|
+ } else {
|
|
|
|
+ for (Node node : this.children) {
|
|
|
|
+ if (!node.unshared()) {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return true;
|
|
|
|
+ } else {
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
- return (Nodes.getNodesSize(largest) == 1) && (largest.size() == 1);
|
|
|
|
}
|
|
}
|
|
|
|
|
|
- public HashSet<Node> combine(Node node) {
|
|
|
|
- Node node1 = node.reduce();
|
|
|
|
- Node node2 = reduce();
|
|
|
|
|
|
+ private void resetSearch() {
|
|
|
|
+ this.linkNodes = new HashSet<>();
|
|
|
|
+ this.linkNode = null;
|
|
|
|
+
|
|
|
|
+ for (Node child : this.children) {
|
|
|
|
+ child.resetSearch();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private HashSet<Node> getDuplicates(HashSet<NodePair> h) {
|
|
|
|
+ HashSet<Node> result = new HashSet<>();
|
|
|
|
+ for (NodePair curr : h) {
|
|
|
|
+ if (curr.node1 == this)
|
|
|
|
+ result.add(curr.node2);
|
|
|
|
+ else if (curr.node2 == this) {
|
|
|
|
+ result.add(curr.node1);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return result;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private Node reduce() {
|
|
|
|
+ HashSet<Node> uniqueC = new HashSet<>();
|
|
|
|
+ HashSet<Node> dupC = new HashSet<>();
|
|
|
|
+ for (Node child : this.children) {
|
|
|
|
+ if (child.inSet(uniqueC))
|
|
|
|
+ dupC.add(child);
|
|
|
|
+ else {
|
|
|
|
+ uniqueC.add(child);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if ((dupC.isEmpty()) || (this.venn.length() == 1)) {
|
|
|
|
+ return this;
|
|
|
|
+ }
|
|
|
|
+ Iterator uIt = uniqueC.iterator();
|
|
|
|
+ String result = "";
|
|
|
|
+ if (uIt.hasNext()) {
|
|
|
|
+ result = result + ((Node)uIt.next()).getVenn();
|
|
|
|
+ }
|
|
|
|
+ if (uIt.hasNext()) {
|
|
|
|
+ result = result + "(" + result;
|
|
|
|
+ while (uIt.hasNext()) {
|
|
|
|
+ result = result + ((Node)uIt.next()).getVenn();
|
|
|
|
+ }
|
|
|
|
+ result = result + ")";
|
|
|
|
+ }
|
|
|
|
+ return new Node(null, result);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private boolean inSet(HashSet<Node> h) {
|
|
|
|
+ for (Node curr : h) {
|
|
|
|
+ if (curr.equals(this)) {
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void collectUnshared(HashSet<Node> h) {
|
|
|
|
+ if (unshared()) {
|
|
|
|
+ h.add(this);
|
|
|
|
+ }
|
|
|
|
+ for (Node child : children) {
|
|
|
|
+ child.collectUnshared(h);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public static HashSet<Node> combine(Node node1, Node node2) {
|
|
|
|
+ node1 = node1.reduce();
|
|
|
|
+ node2 = node2.reduce();
|
|
|
|
|
|
node2.resetSearch();
|
|
node2.resetSearch();
|
|
node1.resetSearch();
|
|
node1.resetSearch();
|
|
@@ -227,17 +315,17 @@ public class Node
|
|
node2.deepSearch(node1, sResult);
|
|
node2.deepSearch(node1, sResult);
|
|
|
|
|
|
if (sResult.isEmpty()) {
|
|
if (sResult.isEmpty()) {
|
|
- result.add(node2.combineAtRoot(node1));
|
|
|
|
|
|
+ result.add(combineAtRoot(node2, node1));
|
|
return result;
|
|
return result;
|
|
}
|
|
}
|
|
|
|
|
|
- HashSet<Nodes> largest = getLNodes(sResult);
|
|
|
|
|
|
+ HashSet<NodePair> largest = getLNodePair(sResult);
|
|
|
|
|
|
- HashSet<Node> unsharedNodes = new HashSet<>();
|
|
|
|
- node2.collectUnshared(unsharedNodes);
|
|
|
|
- node1.collectUnshared(unsharedNodes);
|
|
|
|
|
|
+ HashSet<Node> unsharedNodePair = new HashSet<>();
|
|
|
|
+ node2.collectUnshared(unsharedNodePair);
|
|
|
|
+ node1.collectUnshared(unsharedNodePair);
|
|
|
|
|
|
- if ((unsharedNodes.isEmpty()) && (node1.getNumAreas() == node2.getNumAreas())) {
|
|
|
|
|
|
+ if ((unsharedNodePair.isEmpty()) && (node1.getNumAreas() == node2.getNumAreas())) {
|
|
if (node1.children.size() < node2.children.size()) {
|
|
if (node1.children.size() < node2.children.size()) {
|
|
Node toAdd = new Node(null, node1.getVenn());
|
|
Node toAdd = new Node(null, node1.getVenn());
|
|
result.add(toAdd);
|
|
result.add(toAdd);
|
|
@@ -253,7 +341,7 @@ public class Node
|
|
if (!largest.isEmpty()) {
|
|
if (!largest.isEmpty()) {
|
|
Iterator itLargest = largest.iterator();
|
|
Iterator itLargest = largest.iterator();
|
|
|
|
|
|
- Nodes flargest = (Nodes)itLargest.next();
|
|
|
|
|
|
+ NodePair flargest = (NodePair)itLargest.next();
|
|
|
|
|
|
HashSet<Node> lg1sibs = flargest.node1.getSiblings();
|
|
HashSet<Node> lg1sibs = flargest.node1.getSiblings();
|
|
HashSet<Node> lg2sibs = flargest.node2.getSiblings();
|
|
HashSet<Node> lg2sibs = flargest.node2.getSiblings();
|
|
@@ -271,35 +359,32 @@ public class Node
|
|
|
|
|
|
if ((otherSibs1.isEmpty()) && (otherSibs2.isEmpty())) {
|
|
if ((otherSibs1.isEmpty()) && (otherSibs2.isEmpty())) {
|
|
for (Node newSib : newSibs) {
|
|
for (Node newSib : newSibs) {
|
|
- unsharedNodes.add(newSib);
|
|
|
|
|
|
+ unsharedNodePair.add(newSib);
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
- HashSet newLinkedNodes = getLinkedNodes(unsharedNodes);
|
|
|
|
|
|
+ HashSet<NodePair> newLinkedNodePair = getLinkedNodePair(unsharedNodePair);
|
|
|
|
|
|
- HashSet polys = reviewPolys(newLinkedNodes);
|
|
|
|
- if (!polys.isEmpty())
|
|
|
|
- {
|
|
|
|
|
|
+ HashSet<HashSet<NodePair>> polys = reviewPolys(newLinkedNodePair);
|
|
|
|
+ if (!polys.isEmpty()) {
|
|
Iterator polyIt = polys.iterator();
|
|
Iterator polyIt = polys.iterator();
|
|
if (polyIt.hasNext()) {
|
|
if (polyIt.hasNext()) {
|
|
HashSet polyresult = addPolys((HashSet)polyIt.next());
|
|
HashSet polyresult = addPolys((HashSet)polyIt.next());
|
|
Iterator prIt = polyresult.iterator();
|
|
Iterator prIt = polyresult.iterator();
|
|
if (prIt.hasNext()) {
|
|
if (prIt.hasNext()) {
|
|
- Nodes curr = (Nodes)prIt.next();
|
|
|
|
|
|
+ NodePair curr = (NodePair)prIt.next();
|
|
if ((curr.node1.parent != null) && (curr.node1.linkNode.parent != null)) {
|
|
if ((curr.node1.parent != null) && (curr.node1.linkNode.parent != null)) {
|
|
String polyString1 = buildUp(curr.node1.parent, curr.node2.getVenn());
|
|
String polyString1 = buildUp(curr.node1.parent, curr.node2.getVenn());
|
|
String polyString2 = buildUp(curr.node1.linkNode.parent, curr.node2.getVenn());
|
|
String polyString2 = buildUp(curr.node1.linkNode.parent, curr.node2.getVenn());
|
|
Node polyOne = new Node(null, polyString1);
|
|
Node polyOne = new Node(null, polyString1);
|
|
Node polyTwo = new Node(null, polyString2);
|
|
Node polyTwo = new Node(null, polyString2);
|
|
- HashSet polyresults = polyOne.combine(polyTwo);
|
|
|
|
- Iterator prsIt = polyresults.iterator();
|
|
|
|
- while (prsIt.hasNext())
|
|
|
|
- result.add(prsIt.next());
|
|
|
|
- }
|
|
|
|
- else if (curr.node1.parent != null) {
|
|
|
|
|
|
+ HashSet<Node> polyresults = combine(polyOne, polyTwo);
|
|
|
|
+ for (Node polyResult : polyresults)
|
|
|
|
+ result.add(polyResult);
|
|
|
|
+ } else if (curr.node1.parent != null) {
|
|
String polyString1 = buildUp(curr.node1.parent, curr.node2.getVenn());
|
|
String polyString1 = buildUp(curr.node1.parent, curr.node2.getVenn());
|
|
Node polyOne = new Node(null, polyString1);
|
|
Node polyOne = new Node(null, polyString1);
|
|
result.add(polyOne);
|
|
result.add(polyOne);
|
|
@@ -315,16 +400,15 @@ public class Node
|
|
return result;
|
|
return result;
|
|
}
|
|
}
|
|
|
|
|
|
- Iterator nLNit = newLinkedNodes.iterator();
|
|
|
|
|
|
+ Iterator nLNit = newLinkedNodePair.iterator();
|
|
if (nLNit.hasNext()) {
|
|
if (nLNit.hasNext()) {
|
|
- HashSet combined = ((Nodes)nLNit.next()).combineNew();
|
|
|
|
|
|
+ HashSet combined = ((NodePair)nLNit.next()).combineNew();
|
|
Iterator cIt = combined.iterator();
|
|
Iterator cIt = combined.iterator();
|
|
while (cIt.hasNext()) {
|
|
while (cIt.hasNext()) {
|
|
- Nodes curr = (Nodes)cIt.next();
|
|
|
|
- HashSet newResults = curr.node1.combine(curr.node2);
|
|
|
|
|
|
+ NodePair curr = (NodePair)cIt.next();
|
|
|
|
+ HashSet newResults = combine(curr.node1, curr.node2);
|
|
Iterator nRit = newResults.iterator();
|
|
Iterator nRit = newResults.iterator();
|
|
- while (nRit.hasNext())
|
|
|
|
- {
|
|
|
|
|
|
+ while (nRit.hasNext()) {
|
|
result.add(nRit.next());
|
|
result.add(nRit.next());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -332,42 +416,39 @@ public class Node
|
|
return result;
|
|
return result;
|
|
}
|
|
}
|
|
|
|
|
|
- if (Nodes.getNodesSize(largest) == 1)
|
|
|
|
- {
|
|
|
|
- HashSet unique = getUniqueNodes(sResult);
|
|
|
|
|
|
+ if (NodePair.getNodesSize(largest) == 1) {
|
|
|
|
+ HashSet unique = getUniqueNodePair(sResult);
|
|
Iterator uIt = unique.iterator();
|
|
Iterator uIt = unique.iterator();
|
|
|
|
|
|
while (uIt.hasNext()) {
|
|
while (uIt.hasNext()) {
|
|
Node curr = (Node)uIt.next();
|
|
Node curr = (Node)uIt.next();
|
|
HashSet dupres = curr.getDuplicates(sResult);
|
|
HashSet dupres = curr.getDuplicates(sResult);
|
|
if (dupres.size() > 1) {
|
|
if (dupres.size() > 1) {
|
|
- HashSet newDupNodes = getLinkedNodes(dupres);
|
|
|
|
- Iterator ndIt = newDupNodes.iterator();
|
|
|
|
|
|
+ HashSet newDupNodePair = getLinkedNodePair(dupres);
|
|
|
|
+ Iterator ndIt = newDupNodePair.iterator();
|
|
while (ndIt.hasNext()) {
|
|
while (ndIt.hasNext()) {
|
|
- HashSet combined = ((Nodes)ndIt.next()).combineNew();
|
|
|
|
|
|
+ HashSet combined = ((NodePair)ndIt.next()).combineNew();
|
|
Iterator cIt = combined.iterator();
|
|
Iterator cIt = combined.iterator();
|
|
while (cIt.hasNext()) {
|
|
while (cIt.hasNext()) {
|
|
- Nodes curr2 = (Nodes)cIt.next();
|
|
|
|
- HashSet newResults = curr2.node1.combine(curr2.node2);
|
|
|
|
|
|
+ NodePair curr2 = (NodePair)cIt.next();
|
|
|
|
+ HashSet newResults = combine(curr2.node1, curr2.node2);
|
|
Iterator nRit = newResults.iterator();
|
|
Iterator nRit = newResults.iterator();
|
|
- while (nRit.hasNext())
|
|
|
|
- {
|
|
|
|
|
|
+ while (nRit.hasNext()) {
|
|
result.add(nRit.next());
|
|
result.add(nRit.next());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
else {
|
|
- result.add(node2.combineAtRoot(node1));
|
|
|
|
|
|
+ result.add(combineAtRoot(node2, node1));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
return result;
|
|
}
|
|
}
|
|
|
|
|
|
- if (Nodes.getNodesSize(largest) > 1)
|
|
|
|
- {
|
|
|
|
|
|
+ if (NodePair.getNodesSize(largest) > 1) {
|
|
for (Object aLargest : largest) {
|
|
for (Object aLargest : largest) {
|
|
- Nodes currL = (Nodes) aLargest;
|
|
|
|
|
|
+ NodePair currL = (NodePair) aLargest;
|
|
HashSet largeResult = subTrees(currL);
|
|
HashSet largeResult = subTrees(currL);
|
|
Iterator lrIt = largeResult.iterator();
|
|
Iterator lrIt = largeResult.iterator();
|
|
while (lrIt.hasNext()) {
|
|
while (lrIt.hasNext()) {
|
|
@@ -380,7 +461,52 @@ public class Node
|
|
return result;
|
|
return result;
|
|
}
|
|
}
|
|
|
|
|
|
- private void sortLargestSibs(Iterator<Node> lgsibs, Node lg, HashSet<Node> ns, HashSet<Node> os) {
|
|
|
|
|
|
+ public static HashSet<Node> reducedCombine(Node node1, Node node2) {
|
|
|
|
+ HashSet<Node> result = new HashSet<>();
|
|
|
|
+
|
|
|
|
+ if (oneAreaShared(node1, node2)) {
|
|
|
|
+ result.add(combineAtRoot(node1, node2));
|
|
|
|
+ return result;
|
|
|
|
+ }
|
|
|
|
+ HashSet<Node> compCombine = combine(node1, node2);
|
|
|
|
+
|
|
|
|
+ int smallest = Integer.MAX_VALUE;
|
|
|
|
+ for (Node curr : compCombine) {
|
|
|
|
+ int currAreas = curr.getNumAreas();
|
|
|
|
+ if (currAreas < smallest) {
|
|
|
|
+ smallest = currAreas;
|
|
|
|
+ result.clear();
|
|
|
|
+ result.add(curr);
|
|
|
|
+ } else if (currAreas == smallest) {
|
|
|
|
+ result.add(curr);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return removeDuplicates(result);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private static HashSet<Node> removeDuplicates(HashSet<Node> h) {
|
|
|
|
+ Iterator it = h.iterator();
|
|
|
|
+ HashSet result = new HashSet();
|
|
|
|
+ while (it.hasNext()) {
|
|
|
|
+ Node curr = (Node)it.next();
|
|
|
|
+ if (!curr.inSet(result)) {
|
|
|
|
+ result.add(curr);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return result;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private static boolean oneAreaShared(Node node1, Node node2) {
|
|
|
|
+ HashSet<NodePair> result = new HashSet<>();
|
|
|
|
+ node2.deepSearch(node1, result);
|
|
|
|
+ HashSet<NodePair> largest = getLNodePair(result);
|
|
|
|
+ if (largest.isEmpty()) {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ return (NodePair.getNodesSize(largest) == 1) && (largest.size() == 1);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private static void sortLargestSibs(Iterator<Node> lgsibs, Node lg, HashSet<Node> ns, HashSet<Node> os) {
|
|
while (lgsibs.hasNext()) {
|
|
while (lgsibs.hasNext()) {
|
|
Node curr = lgsibs.next();
|
|
Node curr = lgsibs.next();
|
|
Iterator linkIt = curr.linkNodes.iterator();
|
|
Iterator linkIt = curr.linkNodes.iterator();
|
|
@@ -403,8 +529,7 @@ public class Node
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- public HashSet<Node> subTrees(Nodes largest)
|
|
|
|
- {
|
|
|
|
|
|
+ private static HashSet<Node> subTrees(NodePair largest) {
|
|
HashSet<Node> result = new HashSet();
|
|
HashSet<Node> result = new HashSet();
|
|
HashSet<Node> n = largest.combineSubTrees();
|
|
HashSet<Node> n = largest.combineSubTrees();
|
|
|
|
|
|
@@ -423,104 +548,39 @@ public class Node
|
|
(largest.node2.parent != null)) {
|
|
(largest.node2.parent != null)) {
|
|
String one = buildUp(largest.node1.parent, curr1);
|
|
String one = buildUp(largest.node1.parent, curr1);
|
|
String two = buildUp(largest.node2.parent, curr2);
|
|
String two = buildUp(largest.node2.parent, curr2);
|
|
- Node newone = new Node(null, one);
|
|
|
|
- Node newtwo = new Node(null, two);
|
|
|
|
- HashSet newresult = newone.combine(newtwo);
|
|
|
|
- Iterator newit = newresult.iterator();
|
|
|
|
- while (newit.hasNext()) {
|
|
|
|
- result.add((Node) newit.next());
|
|
|
|
- }
|
|
|
|
|
|
+ Node newOne = new Node(null, one);
|
|
|
|
+ Node newTwo = new Node(null, two);
|
|
|
|
+ HashSet<Node> newResult = combine(newOne, newTwo);
|
|
|
|
+ result.addAll(newResult);
|
|
return result;
|
|
return result;
|
|
}
|
|
}
|
|
if (largest.node1.parent != null) {
|
|
if (largest.node1.parent != null) {
|
|
String one = buildUp(largest.node1.parent, curr1);
|
|
String one = buildUp(largest.node1.parent, curr1);
|
|
- Node newone = new Node(null, one);
|
|
|
|
- result.add(newone);
|
|
|
|
|
|
+ Node newOne = new Node(null, one);
|
|
|
|
+ result.add(newOne);
|
|
return result;
|
|
return result;
|
|
}
|
|
}
|
|
if (largest.node2.parent != null) {
|
|
if (largest.node2.parent != null) {
|
|
String two = buildUp(largest.node2.parent, curr2);
|
|
String two = buildUp(largest.node2.parent, curr2);
|
|
- Node newtwo = new Node(null, two);
|
|
|
|
- result.add(newtwo);
|
|
|
|
|
|
+ Node newTwo = new Node(null, two);
|
|
|
|
+ result.add(newTwo);
|
|
return result;
|
|
return result;
|
|
}
|
|
}
|
|
System.out.println("Houston we have a problem.");
|
|
System.out.println("Houston we have a problem.");
|
|
}
|
|
}
|
|
-
|
|
|
|
return result;
|
|
return result;
|
|
}
|
|
}
|
|
|
|
|
|
- private void search(Node node, HashSet<Nodes> h)
|
|
|
|
- {
|
|
|
|
- if (equals(node)) {
|
|
|
|
- this.linkNodes.add(node);
|
|
|
|
- node.linkNodes.add(this);
|
|
|
|
- h.add(new Nodes(this, node));
|
|
|
|
- } else {
|
|
|
|
- for(Node child : children) {
|
|
|
|
- child.search(node, h);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private HashSet<Nodes> searchBothNodes(Node node)
|
|
|
|
- {
|
|
|
|
- HashSet<Nodes> sResult = new HashSet<>();
|
|
|
|
- search(node, sResult);
|
|
|
|
-
|
|
|
|
- HashSet<Nodes> nsResult = new HashSet<>();
|
|
|
|
- node.search(this, nsResult);
|
|
|
|
-
|
|
|
|
- for (Nodes curr : nsResult) {
|
|
|
|
- boolean inSet = inSet(curr, sResult);
|
|
|
|
- if (!inSet) {
|
|
|
|
- sResult.add(curr);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return sResult;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public void deepSearch(Node node, HashSet<Nodes> h)
|
|
|
|
- {
|
|
|
|
- HashSet<Nodes> first_result = searchBothNodes(node);
|
|
|
|
- for(Nodes res : first_result) {
|
|
|
|
- h.add(res);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- for(Node child : node.children) {
|
|
|
|
- deepSearch(child, h);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private boolean inSet(Nodes n, Iterable<Nodes> it)
|
|
|
|
- {
|
|
|
|
- for (Nodes nodes : it) {
|
|
|
|
- if (n.equals(nodes)) {
|
|
|
|
- return true;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private void resetSearch() {
|
|
|
|
- this.linkNodes = new HashSet<>();
|
|
|
|
- this.linkNode = null;
|
|
|
|
-
|
|
|
|
- for (Node child : this.children) {
|
|
|
|
- child.resetSearch();
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
/**
|
|
/**
|
|
*
|
|
*
|
|
- * @param h A HashSet
|
|
|
|
- * @return The largest Nodes in h, based on the length of n1's Venn diagram
|
|
|
|
|
|
+ * @param h HashSet
|
|
|
|
+ * @return The largest NodePair in h, based on the length of n1's Venn diagram
|
|
*/
|
|
*/
|
|
- private static HashSet<Nodes> getLNodes(HashSet<Nodes> h) {
|
|
|
|
- HashSet<Nodes> result = new HashSet<>();
|
|
|
|
|
|
+ private static HashSet<NodePair> getLNodePair(HashSet<NodePair> h) {
|
|
|
|
+ HashSet<NodePair> result = new HashSet<>();
|
|
int size = -1;
|
|
int size = -1;
|
|
|
|
|
|
- for(Nodes curr : h){
|
|
|
|
|
|
+ for(NodePair curr : h){
|
|
if (curr.nodesSize() > size) {
|
|
if (curr.nodesSize() > size) {
|
|
size = curr.nodesSize();
|
|
size = curr.nodesSize();
|
|
result.clear();
|
|
result.clear();
|
|
@@ -532,29 +592,28 @@ public class Node
|
|
return result;
|
|
return result;
|
|
}
|
|
}
|
|
|
|
|
|
- private Node combineAtRoot(Node node)
|
|
|
|
- {
|
|
|
|
- HashSet<Node> uniqueNodes = new HashSet<>();
|
|
|
|
|
|
+ private static Node combineAtRoot(Node node1, Node node2) {
|
|
|
|
+ HashSet<Node> uniqueNodePair = new HashSet<>();
|
|
boolean reduced = false;
|
|
boolean reduced = false;
|
|
- for(Node curr : this.children) {
|
|
|
|
- if (!contains(curr, uniqueNodes))
|
|
|
|
- uniqueNodes.add(curr);
|
|
|
|
|
|
+ for(Node curr : node1.children) {
|
|
|
|
+ if (!curr.inSet(uniqueNodePair))
|
|
|
|
+ uniqueNodePair.add(curr);
|
|
else {
|
|
else {
|
|
reduced = true;
|
|
reduced = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- for(Node curr : node.children) {
|
|
|
|
- if (!contains(curr, uniqueNodes))
|
|
|
|
- uniqueNodes.add(curr);
|
|
|
|
|
|
+ for(Node curr : node2.children) {
|
|
|
|
+ if (!curr.inSet(uniqueNodePair))
|
|
|
|
+ uniqueNodePair.add(curr);
|
|
else {
|
|
else {
|
|
reduced = true;
|
|
reduced = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (!reduced) {
|
|
if (!reduced) {
|
|
- return new Node(null, "(" + this.venn + node.getVenn() + ")");
|
|
|
|
|
|
+ return new Node(null, "(" + node1.venn + node2.getVenn() + ")");
|
|
} else {
|
|
} else {
|
|
String result_venn = "(";
|
|
String result_venn = "(";
|
|
- for (Node unique : uniqueNodes) {
|
|
|
|
|
|
+ for (Node unique : uniqueNodePair) {
|
|
result_venn = result_venn + unique;
|
|
result_venn = result_venn + unique;
|
|
}
|
|
}
|
|
result_venn = result_venn + ")";
|
|
result_venn = result_venn + ")";
|
|
@@ -562,60 +621,16 @@ public class Node
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- private boolean unshared() {
|
|
|
|
- if (this.linkNodes.isEmpty()) {
|
|
|
|
- if(this.children.isEmpty()) {
|
|
|
|
- return true;
|
|
|
|
- } else {
|
|
|
|
- for (Node node : this.children) {
|
|
|
|
- if (!node.unshared()) {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return true;
|
|
|
|
- } else {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private void collectUnshared(HashSet<Node> h) {
|
|
|
|
- if (unshared()) {
|
|
|
|
- h.add(this);
|
|
|
|
- }
|
|
|
|
- for (Node child : children) {
|
|
|
|
- child.collectUnshared(h);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private HashSet<Nodes> getLinkedNodes(HashSet<Node> h)
|
|
|
|
- {
|
|
|
|
- HashSet result = new HashSet();
|
|
|
|
|
|
+ private static HashSet<NodePair> getLinkedNodePair(HashSet<Node> h) {
|
|
|
|
+ HashSet<NodePair> result = new HashSet<>();
|
|
for (Node curr : h) {
|
|
for (Node curr : h) {
|
|
if (curr.hasLink() != null)
|
|
if (curr.hasLink() != null)
|
|
- result.add(new Nodes(curr, curr.hasLink()));
|
|
|
|
|
|
+ result.add(new NodePair(curr, curr.hasLink()));
|
|
}
|
|
}
|
|
return result;
|
|
return result;
|
|
}
|
|
}
|
|
|
|
|
|
- private Node hasLink() {
|
|
|
|
- HashSet<Node> sibs = getSiblings();
|
|
|
|
- for (Node curr : sibs) {
|
|
|
|
- if (!curr.linkNodes.isEmpty()) {
|
|
|
|
- return curr;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return null;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public Node root() {
|
|
|
|
- if (getSiblings().isEmpty()) {
|
|
|
|
- return this;
|
|
|
|
- }
|
|
|
|
- return this.parent.root();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private String buildUp(Node n, String s) {
|
|
|
|
|
|
+ private static String buildUp(Node n, String s) {
|
|
if (n.parent == null) {
|
|
if (n.parent == null) {
|
|
return s;
|
|
return s;
|
|
}
|
|
}
|
|
@@ -630,18 +645,17 @@ public class Node
|
|
return buildUp(n.parent, result);
|
|
return buildUp(n.parent, result);
|
|
}
|
|
}
|
|
|
|
|
|
- private HashSet<HashSet<Nodes>> reviewPolys(HashSet<Nodes> h)
|
|
|
|
- {
|
|
|
|
- HashSet<HashSet<Nodes>> result = new HashSet<>();
|
|
|
|
- for (Nodes curr : h) {
|
|
|
|
- HashSet<Nodes> curresult = new HashSet<>();
|
|
|
|
- for (Nodes inCurr : h) {
|
|
|
|
|
|
+ private static HashSet<HashSet<NodePair>> reviewPolys(HashSet<NodePair> h) {
|
|
|
|
+ HashSet<HashSet<NodePair>> result = new HashSet<>();
|
|
|
|
+ for (NodePair curr : h) {
|
|
|
|
+ HashSet<NodePair> curresult = new HashSet<>();
|
|
|
|
+ for (NodePair inCurr : h) {
|
|
if (inCurr == curr) {
|
|
if (inCurr == curr) {
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
- HashSet<Node> linkedNodes = inCurr.node2.linkNodes;
|
|
|
|
|
|
+ HashSet<Node> linkedNodePair = inCurr.node2.linkNodes;
|
|
boolean found = false;
|
|
boolean found = false;
|
|
- for (Node currln : linkedNodes) {
|
|
|
|
|
|
+ for (Node currln : linkedNodePair) {
|
|
if (currln == curr.node2) {
|
|
if (currln == curr.node2) {
|
|
found = true;
|
|
found = true;
|
|
inCurr.node2.linkNode = currln;
|
|
inCurr.node2.linkNode = currln;
|
|
@@ -660,40 +674,27 @@ public class Node
|
|
return result;
|
|
return result;
|
|
}
|
|
}
|
|
|
|
|
|
- private HashSet<Nodes> addPolys(HashSet<Nodes> h) {
|
|
|
|
- HashSet<Nodes> setResult = new HashSet<>();
|
|
|
|
- Nodes first = null;
|
|
|
|
|
|
+ private static HashSet<NodePair> addPolys(HashSet<NodePair> h) {
|
|
|
|
+ HashSet<NodePair> setResult = new HashSet<>();
|
|
|
|
+ NodePair first = null;
|
|
String result = "";
|
|
String result = "";
|
|
- for (Nodes nodes : h) {
|
|
|
|
|
|
+ for (NodePair nodes : h) {
|
|
if (first == null) {
|
|
if (first == null) {
|
|
first = nodes;
|
|
first = nodes;
|
|
result = first.node2.getVenn();
|
|
result = first.node2.getVenn();
|
|
}
|
|
}
|
|
result += nodes.node1.getVenn();
|
|
result += nodes.node1.getVenn();
|
|
}
|
|
}
|
|
- for (Nodes nodes : h) {
|
|
|
|
- Nodes toAdd = new Nodes((nodes).node2, new Node(null, "(" + result + ")"));
|
|
|
|
|
|
+ for (NodePair nodes : h) {
|
|
|
|
+ NodePair toAdd = new NodePair((nodes).node2, new Node(null, "(" + result + ")"));
|
|
setResult.add(toAdd);
|
|
setResult.add(toAdd);
|
|
}
|
|
}
|
|
return setResult;
|
|
return setResult;
|
|
}
|
|
}
|
|
|
|
|
|
- private boolean isIn(Node node) {
|
|
|
|
- if (this == node) {
|
|
|
|
- return true;
|
|
|
|
- }
|
|
|
|
- for (Node child : this.children) {
|
|
|
|
- if (child.isIn(node)) {
|
|
|
|
- return true;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private HashSet<Node> getUniqueNodes(HashSet<Nodes> h)
|
|
|
|
- {
|
|
|
|
|
|
+ private static HashSet<Node> getUniqueNodePair(HashSet<NodePair> h) {
|
|
HashSet<Node> result = new HashSet<>();
|
|
HashSet<Node> result = new HashSet<>();
|
|
- for (Nodes curr : h) {
|
|
|
|
|
|
+ for (NodePair curr : h) {
|
|
if (!result.contains(curr.node1)) {
|
|
if (!result.contains(curr.node1)) {
|
|
result.add(curr.node1);
|
|
result.add(curr.node1);
|
|
}
|
|
}
|
|
@@ -704,54 +705,4 @@ public class Node
|
|
return result;
|
|
return result;
|
|
}
|
|
}
|
|
|
|
|
|
- private HashSet<Node> getDuplicates(HashSet<Nodes> h) {
|
|
|
|
- HashSet<Node> result = new HashSet<>();
|
|
|
|
- for (Nodes curr : h) {
|
|
|
|
- if (curr.node1 == this)
|
|
|
|
- result.add(curr.node2);
|
|
|
|
- else if (curr.node2 == this) {
|
|
|
|
- result.add(curr.node1);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return result;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- protected Node reduce()
|
|
|
|
- {
|
|
|
|
- HashSet<Node> uniqueC = new HashSet<>();
|
|
|
|
- HashSet<Node> dupC = new HashSet<>();
|
|
|
|
- for (Node child : this.children) {
|
|
|
|
- if (contains(child, uniqueC))
|
|
|
|
- dupC.add(child);
|
|
|
|
- else {
|
|
|
|
- uniqueC.add(child);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- if ((dupC.isEmpty()) || (this.venn.length() == 1)) {
|
|
|
|
- return this;
|
|
|
|
- }
|
|
|
|
- Iterator uIt = uniqueC.iterator();
|
|
|
|
- String result = "";
|
|
|
|
- if (uIt.hasNext()) {
|
|
|
|
- result = result + ((Node)uIt.next()).getVenn();
|
|
|
|
- }
|
|
|
|
- if (uIt.hasNext()) {
|
|
|
|
- result = result + "(" + result;
|
|
|
|
- while (uIt.hasNext()) {
|
|
|
|
- result = result + ((Node)uIt.next()).getVenn();
|
|
|
|
- }
|
|
|
|
- result = result + ")";
|
|
|
|
- }
|
|
|
|
- return new Node(null, result);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private boolean contains(Node n, HashSet<Node> h)
|
|
|
|
- {
|
|
|
|
- for (Node curr : h) {
|
|
|
|
- if (curr.equals(n)) {
|
|
|
|
- return true;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
}
|
|
}
|