I'm working on building a partial tree for Monte Carlo Search Tree, I have my node class and it contains things like the game board, who's turn it is, and a list of Nodes for the children nodes. The node constructor takes in a game board and the depth (of the tree) as the parameters. For the root node I call it like so:
Node root = new Node(this.quartoBoard, currentDepth);
(Where depth is 0) that works fine, however, when depth 1, which will be the children of the root node needs to contain 32 nodes. I naively tried this:
for(int i = 0; i < NUMBER_OF_PIECES; i++) {
Node c1 = new Node(this.quartoBoard, currentDepth);
c1.setParent(root);
childrenList1.add(c1);
}
And realized that Nodes can not be created in a for loop like this. Is there an alternative to declaring each node one at a time like so:
Node child1 = new Node(this.quartoBoard, currentDepth);
Node child2 = new Node(this.quartoBoard, currentDepth);
I need to create over 800 nodes and I feel like there is a better way to do it, I just am drawing blanks on how. Any help is greatly appreciated!
Related
I have a graph with nodes to color, where for each node a dataset (a collection of rows / tuples) is associated.
The algorithm is explained by this example:
the uploaded figure shows an execution of Coloring over graph G with
nodes {v1, v3, v2}. Figure (a) initializes nodes as
uncolored. We first consider v1, and select Sσ1 = {{t9, t10}} (Figure (b)). We color nodes v2 and v3 by recursively calling Coloring.
Coloring one node may restrict the color choice of neighboring nodes,
e.g. after we select {{t9, t10}} for v1, we cannot select {{t6, t7,
t10}} for v3 due to the overlapping tuple t10. For node v3,
we have several choices including {{t6, t7}} and {{t7, t8}}. In Figure (c), we assume the coloring algorithm chooses {{t6, t7}} for
v3. As a result, {{t5, t6}}, which was the only choice forv2, cannot
be used due to the overlapping tuple t6. This leads the algorithm
towards an unsatisfying clustering (Figure (d)). The algorithm
backtracks its last decision for v3 by selecting a different color,
{{t7, t8}} for v3 in Figure (e). In this case, the clustering {{t5,
t6}} for v2 does not overlap with {{t7, t8}}. Since we have found a
clustering that satisfies all the constraints (i.e., a coloring of all nodes), Coloring returns true with V containing the nodes and their colors
(i.e., clusterings).
Here's my code i am trying (which i suspect it is wrong the way it colors the nodes because the algorithm runs for too long )
nodeIterator parameter contains all nodes of the graph sorted in customized way.
public Boolean coloring(graph, nodeIterator, vector){
Node nodeIt ;
if (nodeIterator.hasNext())
nodeIt = nodeIterator.next();
else {
return false;
}
// cluster is the current node associated dataset
ArrayList<Dataset<Row>> cluster = allClustersOfGraph.getNextDataset(nodeIt.name);
if (graph.getNeighbors(nodeIt) == null) {
if (!nodeIterator.hasNext()){
colorNode(vector, nodeIt);
return false;
}
else {
colorNode(vector, nodeIt);
nodeIterator.next();
}
}
Iterable<Node> adjNodes = graph.getNeighbors(nodeIt);
Iterator<Node> adjNodesIt = adjNodes.iterator();
// i suspect in the line under, while is an if so that next neighboring nodes of the current processed one, will be in turn processed in the next recursive call of this algorithm
while (adjNodesIt.hasNext()){
Node adjNode = adjNodesIt.next();
if (!checkNodeColored(vector, adjNode)) {
ArrayList<Dataset<Row>> adjCluster = allClustersOfGraph.getNextDataset(adjNode.name);
for (Dataset<Row> subCluster : cluster) {
for (Dataset<Row> subAdjCluster : adjCluster) {
// small datasets (tuples of rows) don't intersect
if (noDatasetIntersection(subCluster, subAdjCluster)) {
colorNode(vector, nodeIt, subCluster);
if (coloring(graph, nodeIterator, vector)) {
return true;
} else {
// vector is where current coloring progress is maintained
// move backwards
vector.remove(vector.size() - 1);
}
}
}
}
} else if (!adjNodesIt.hasNext()) {
// Color last node anyway
colorNode(vector, nodeIt);
return true;
}
}
return false;
}
allClustersOfGraph is of type ArrayList<ArrayList<Dataset<Row>>>
Here's also the pseudo-algorithm :
My question is : i created the loop while (adjNodesIt.hasNext()){...in my code to check for one recursive call all neighboring nodes of the current processed node, is it right to do that in a recursive method ? Also are all limit cases treated through my implementation ?
Thanks for the great help!
I have to develop a Dijkstra Alogirthm in Java and I have a question to Dijkstra in a circle.
So for a Tree or a normal graph without a loop it works.
So I have a Status White means not found, gray = found but not dealt with and black means done.
So when I have a loop I tryed a if (next.status == Node.Black) but then he didn't found all nodes.
So the question is, how can I add a loop detection and found all nodes?
Thanks for help and tips
best regards
witar7
PS: the if (next.equals(startNode) was only an idea to stop the loop.
public void populateDijkstraFrom(Node startNode) {
this.resetState();
PriorityQueue<Node> distanceQueue = new PriorityQueue<Node>();
for (int x = 0; x < nodes.size(); x++) { // for each node
nodes.get(x).distance = Double.POSITIVE_INFINITY; // set distance to inf
nodes.get(x).predecessor = null; // delete existing predecessors
}
startNode.distance = 0.0; // set distance from startNode to zero
startNode.status = Node.GRAY; // mark startNode as active
Node current = startNode;
distanceQueue.add(current); // add startNode to prio queue
while (!distanceQueue.isEmpty()) { // while contains elements
current = distanceQueue.poll(); // set current to head of queue
current.status = Node.BLACK; // mark head as settled
for (Node next : current.getAdjacentNodes() ) { // get all adjacent nodes
if (next.equals(startNode)) {
break;
}
next.status = Node.GRAY;
// stopExecutionUntilSignal();// mark status as found
distanceQueue.add(next);
if (distanceQueue.contains(next)) {
if (next.distance > current.distance + current.getWeight(next)) { // if the found distance is smaller then the existing one
next.predecessor = current; // change distance in node
next.distance = current.distance + current.getWeight(next); // set predecessor
}
}
}
}
this.clearMarks();
}
PS: the if (next.equals(startNode) was only an idea to stop the loop.
There's no need to do this, your while condition will terminate anyway when it can't find anymore unvisited adjacent nodes. You just have to check whether current visited node status is BLACK and if yes, don't add it to the queue (it's already been visited before).
P.S.: I don' think you need GRAY status, just BLACK or WHITE. Deal with the node right away, no need to delay.
I'm trying to convert a 2-3-4 Tree into a Red-Black tree in java, but am having trouble figuring it out.
I've written these two basic classes as follows, to make the problem straightforward, but can't figure out where to go from here.
public class TwoThreeFour<K> {
public List<K> keys;
public List<TwoThreeFour<K>> children;
}
public class RedBlack<K> {
public K key;
public boolean isBlack;
public RedBlack<K> left,right;
public RedBlack<K key, boolean isBlack, RedBlack<K> left, RedBlack<K> right){
this.key = key; this.isBlack = isBlack; this.left = left; this.right = right;
}
}
I'm assuming the 2-3-4 tree is valid, and want to return a red black tree when the method is called.
I've also tried the following code with no luck:
public convert(TwoThreeFour<K> tTF){
if (ttf.keys.size() == 3)
RedBlack<K> node = RedBlack<ttf.keys[1], true, RedBlack<ttf.keys[0], false, /* not sure what to put here for left */, /* not sure what to put here for right */), RedBlack<ttf.keys[2], false, /* not sure what to put here for left */, /* not sure what to put here for right */)
etc. for keys.size() == 2, 1....
I know it has to be recursive in theory, but am having a hard time figuring it out. Any thoughts?
Consider these three rules:
Transform any 2-node in the 2-3-4 tree into a black node in the
red-black tree.
Transform any 3-node into a child node and a parent node. The
child node has two children of its own: either W and X or X and Y.
The parent has one other child: either Y or W. It doesn’t matter
which item becomes the child and which the parent. The child is
colored red and the parent is colored black.
Transform any 4-node into a parent and two children, the first
child has its own children W and X; the second child has children Y
and Z. As before, the children are colored red and the parent is
black.
The red-black rules are automatically satisfied if you follow these rules. Here's the resulting example tree after applying the transformations.
Hopefully that should get you going. For easy to understand and detailed explanation, you can refer to Robert Lafore's Data Structures book.
I am using a JTree in which new nodes needs to be inserted dynamically to the root(consider adding children to root). Once the user selects a node and clicks a button, the new node needs to be added after the selected node. If none of the node is selected then it adds the new node at the end of the tree. Below is my code
public void addNodeToRoot(TestCase testCase) {
DefaultMutableTreeNode childNode = new DefaultMutableTreeNode(testCase.toString());
int currentNoOfChildren = getTcBuilderTree().getModel().getChildCount(getTcBuilderTree().getModel().getRoot());
TreePath currentSelection = getTcBuilderTree().getSelectionPath();
int currentIndex=0;
//if the user has not selected a node add the test case at the end of the tree
if (currentSelection == null) {
currentIndex = currentNoOfChildren;
}
//if user has selected a node then insert the new node after the selected node
else {
int[] currentSelectedIndex = getTcBuilderTree().getSelectionRows();
currentIndex = currentSelectedIndex[0];
}
treeModel.insertNodeInto(childNode, getRoot(), currentIndex);
}
it works all fine but the code gives an exception when there are child nodes in the level 3 as well. The reason is when the tree has more levels and when its expanded then the currentIndex gives unexpected number (it counts all the indexes in all levels up from the root to the selected node) and the app gives ArrayIndexOutOfBoundsException since the currentIndex becomes greater than currentNoOfChildren
If the tree is not expanded then everything happens correctly. Please let me know how to resolve this. Is there any other way to get the no of children of a specific level in the tree?
Maybe code below can resolve your problem.
int currentNoOfChildren = getTcBuilderTree().getVisibleRowCount();
I know this question has been asked before in a similar way, maybe for icons.
What I'm trying is to change the color of the text of the tree node.
In fact, I have a jTree and I will want to set up three differents colors, default one, red and orange.
The purposse, is that if I compare that tree with another one, highlight differences between both trees (default means no diff, orange means just value diff and red means node is complete different)
I have two functions, one which trasverse the "original" tree looking for a node from the compared one, and returns false if {node} is not found:
private Boolean findNodeInRefTree(DefaultTreeModel model, Object root, DefaultMutableTreeNode node){
Boolean bRet = false;
for (int i = 0; ((i < model.getChildCount(root))&&(!bRet)); i++){
DefaultMutableTreeNode child = (DefaultMutableTreeNode) model.getChild(root, i);
bRet = node.getUserObject().equals(child.getUserObject());
if (!bRet)
bRet = findNodeInRefTree(model, child, node);
}//for:i
return bRet;
}
And another function that trasverse the "compare" tree and calls the above for each node.
private void compareTrees(TreeModel model, Object root){
for (int i = 0; i < model.getChildCount(root); i++){
DefaultMutableTreeNode child = (DefaultMutableTreeNode) model.getChild(root, i);
//find if node exists in original
DefaultTreeModel modelRef = (DefaultTreeModel) _ref.getModel();
if (!findNodeInRefTree(modelRef, modelRef.getRoot(), child)){
DefaultTreeCellRenderer render = (DefaultTreeCellRenderer) _temp.getCellRenderer();
render.setForeground(Color.RED);
_temp.setCellRenderer(render);
}//fi
_new.insertNodeInto((DefaultMutableTreeNode) child, (DefaultMutableTreeNode) root, i);
compareTrees(model, child);
}//for:i
}
Then, when it ends I just set the model of the new tree {_new} to the new tree {_temp}, and add the tree to its panel. But the tree doesn't has any different color. Obviously, I'm testing with different trees. Any suggestion?
If I understand your code correctly, your do the comparison at creation time and set the renderer for each tree node (i.e. multiple times) inside method compareTrees.
Unfortunately, that is not the way tree renderers are handled in swing. The renderer is prepared on request during rendering the tree component. Thus setting multiple renderer beforehand won't do anything useful.
A possible approach would be to do the comparison and save the result (i.e. color) in your tree model. You can then write a basic tree renderer which reads this value for the current node and sets the rendering color accordingly.