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!
Related
I'm trying to implement a class to check if two game objects intersect. Can anyone give me a better solution / more elegant to this problem?
Basically I want to addCollision and know if one object collidesWith another. A double entry matrix seemed a good idea.
private class CollisionMatrix {
private boolean[][] matrix;
private HashMap<Tag, Integer> matrixIndexes = new HashMap<Tag, Integer>();
public CollisionMatrix() {
int i = 0;
for (Tag tag : Tag.values())
matrixIndexes.put(tag, i++);
matrix = new boolean[i][i];
}
private void addCollision(Tag tag1, Tag tag2) {
int p1 = matrixIndexes.get(tag1);
int p2 = matrixIndexes.get(tag2);
matrix[p1][p2] = true;
matrix[p2][p1] = true;
}
private boolean collidesWith(Tag tag1, Tag tag2) {
int p1 = matrixIndexes.get(tag1);
int p2 = matrixIndexes.get(tag2);
return matrix[p1][p2] || matrix[p2][p1];
}
}
This is not a complete answer, but it should set you on a path to get a more complete solution.
The simplest (not efficient) way to do this is to have a list of the objects that can collide with each other and then for every frame in time, got through every object in the list and check if the object collides (Shares the same space or bounding volume) with another one in the list.
pseudo code:
L: list of objects that can potentially collide.
t: time
for each frame in t {
for each object obj in L {
P: list of objects without obj
for each object otherObj in P {
does obj collide with otherObj
}
}
}
While this technically works, it's not a good solution as it will be very slow as soon as you start having many objects, and it doesn't take that many to make it slow.
To make this possible in real time, you would need to add some acceleration techniques.
One of these acceleration techniques is using "Bounding volume hierarchy" or BVH. https://en.wikipedia.org/wiki/Bounding_volume_hierarchy
In a nutshell, BVH is technique or algorithm to enable quick lookups of which objects are likely to collide.
It typically uses some type of tree structure to keep track of the positions and volumes occupied by the said objects. Tree structures provide faster lookup times than just linearly iterating a list multiple times.
Each level of the tree provides a hierarchy of bounding volumes (space the object is likely to occupy). Top levels of the tree provide a bigger volume for the particular object (a more rough, less granular or less fitting to the object's shape), but easier to discard if the object in question is not in that same space (you would know with little calculations that the object would never collide with anything in that same bounding volume). The deeper in the tree you go, the more granular or more fitting to the objects shape the bounding volumes get, until you get the objects which collide.
Hope this helps :)
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 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.
I am trying to implement a breadth first traversal for a maze. This is the code I have so far using a linked list but I am not sure if it is searching breadth first. Is this the proper way to do it? any suggestions, comments?
public boolean traverseBreadth(){
//traverse the floor from entrance to exit
//stepping only on red tiles
steps = new LinkedList<Tile>();
possibleSteps = new LinkedList<Tile>();
//reset markings
reset();
//push the entrance onto the stack
entrance.setVisited();
steps.add(entrance);
System.out.println("add " + entrance);
nextMoves(entrance);
//keep going as long as we have a possibility to move
//and we haven't reached the end yet
while (!possibleSteps.isEmpty()&& (!possibleSteps.getLast().equals(exit)))
{
Tile x = possibleSteps.removeLast();
x.setMarked(); //walked on that square
steps.add(x); //walk to that square
System.out.println("Walked to the square " + x);
//now figure out where you can walk from this square
nextMoves(x);
try {
Thread.currentThread().sleep(1000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
if (possibleSteps.getLast().equals(exit)){
steps.push(possibleSteps.removeLast());
System.out.println("made it from entrance to exit");
System.out.println(steps.toString());
return true;
}
else
{ JOptionPane.showMessageDialog(null,"sorry can't reach the exit");
return false;
}
}
This isn't a breadth first search - this is depth first.
There are 2 places that are obviously depth first
you remove from the end of the frontier (possibleTiles), not the beginning.
you do not have a traversal hierarchy (parent to child) to rebuild the traversal path, only a single "path" with tiles. Therefore, it is depth first.
Things to change:
instead of LinkedList, change that to Dictionary. The key of the dictionary will be the tile, and the value will be the tile's parent. Use this to reconstruct your final path.
your "moveNext" function is probably right. Make sure it is pushing to the end of the List.
do not pop (getLast()) from PossibleSteps. PossibleSteps should be a First-In-First-Out queue. Retrieve the first Tile of PossibleSteps (this will explore the tiles closest to the start first).
Things to improve:
instead of using Tile to track exploration, use a Set (call it ExploredTile) where you put tiles that you have traversed)
use a Queue instead of List.
Some C#/Pseudo Code (cuz I'm not at an IDE)
Dictionary<Tile,Tile> path = ...;
Queue<Tile> frontier = ...;
Set<Tile> explored = ...;
path[start] = null;
while(frontier.Count > 0){
var tile = frontier.Dequeue();
if(explored.Contains(tile)){
continue;
}
explored.add(tile);
if (Tile == Exit){
rebuildPath(Exit);
}else{
for (Tile t in Tile.neighbours){
if (!explored.Contains(t)){
frontier.Enqueue(t);
path[t] = tile; // Set the path hierarchy
}
}
}
}
RebuildPath
LinkedList<Tile> finalPath = ...;
Tile parent = path[exitTile];
finalPath.push(exitTile);
while(parent != null){
finalPath.push(parent);
parent = path[parent];
}
finalPath.reverse();
Hopefully I got it right... :)