27 Apr 2015
This happened to me several times that when I start my Gradle project with IntelliJ, update my gradle file and run the Gradle refresh, the Gradle update doesn't run citing some issue with allocating heap memory to the JVM and hence the JVM couldn't start.
After scouting stack overflow, I figured out that it has to do with Java version. At that time, I had Java 8, which was causing the problem. I un-installed Java 8 and IntelliJ started using Java 7 and everything worked fine.
After a few weeks, when I started the project, I am faced with the same error again. This time, I didn't have Java 8 on my machine. To make sure, I opened the IntelliJ terminal and ran the command
java -version
As suspected, the JVM couldn't start. Some stack overflow posts suggested updating registry, which I tried, but couldn't get past the issue. Finally, I ran the Java 7 installer once again and restarted IntelliJ. This finally fixed the issue.
In the times where we have less and less time for working on projects, issues like these are a buzz kill, throwing us away from the main work. Especially, if we encounter an issue that we solved several weeks ago, but some how forgot the way we fixed it.
20 Apr 2015
See the Pen Connected nodes by Sundeep (@SundeepB) on CodePen.
Read about the Union Find algorithm here. The algorithm is also explained in Coursera's Algorithms course by Robert Sedgewick and Kevin Wayne.
See the full code on code pen
Its implemented in the awesome D3 JS
We start by defining an svg element in the HTML
<svg class="dot_world"></svg>
That is all the HTML we'll require apart from including the d3 js library. The rest of it is accomplished using D3.
We select the svg element and set the height and width by
var dot_world = d3.select(".dot_world")
.attr("height",height)
.attr("width",width);
In the visualization, each node is a dot. For n nodes, each node is labeled from 0 to n-1.
var data = [];
for (var i = 0;i < total_dots; i++) {
data.push(i);
}
In our visualization, the nodes will be positioned in 2D space, so, we'll need to define functions to return the x and y co-ordinates of each node depending on the position of the node.
var cx = function(d) {
return ((d%dots_on_x)*(dot_span))+dot_spacing;
}
d%dots_on_x
gives the column the dot will be present. With this we can calculate the x position of the node.
var cy = function(d) {
return ((Math.floor(d/dots_on_x))*dot_span)+dot_spacing;
}
Math.floor(d/dots_on_x)
gives the row the dot should be placed in. With this we can calculate the y position of the node.
A circle svg element looks like the following
<circle style="fill: rgb(218, 113, 26);" r="3" cy="394" cx="170"></circle>
While style is optional, r, cx and cy are required. Using D3
var dot = dot_world.selectAll("circle")
.data(data)
.enter()
.append("circle")
.attr("cx",function(d,i){return cx(i);})
.attr("cy",function(d,i){return cy(i);})
.attr("r",dot_radius)
The enter()
function will select all the data that is not attached to any element. At this point, it will be all the elements in the data
array. append(circle)
function will append a <circle>
element for every data element. We'll add cx
, cy
and r
attributes for each element using the functions we constructed earlier. Only because of d3, we were able to establish all this in well structured code.
At this point we'll have all the nodes drawn on the svg canvas. In an ideal situation, any node should be able to connect to any other node. But, if we do the same in the visualization, it'll make the node a mess and hard to understand. For the sake of simplicity and simple visualization, we will allow each node to connect only to its immediate neighbors(excluding diagonal connections). So, each node effectively has at least 2 neighbors and a maximum of 4 neighbors. In an entirely connected network of n nodes, we'll have 2n-(x+y)
connections where n
is the total number of nodes and x
and y
are the number of columns and rows. As we'll want to randomize each connection, we'll take a chance at each connection whether to connect or not. This will make sure some dots are not connected, however, it is not impossible that the entire node comes connected, though I have not seen it occur even once.
An svg line looks like
<line x1="458" y1="42" x2="474" y2="42" style="stroke:#000000;stroke-width=10"></line>
We'll add lines as
var line = dot_world.append("line")
.attr("x1",cxa)
.attr("y1",cya)
.attr("x2",cxa)
.attr("y2",cya)
.attr("style","stroke:#000000;stroke-width=10");
Notice that at this point the line length is zero. This is because we want to animate the line to show that we are connecting the nodes. The line transition is defined as
line.transition()
.attr("x2",cxb)
.delay(2000)
.duration(2000)
.attr("y2",cyb)
.duration(2000);
The animation will begin with a delay()
of 2 seconds so that the animation is not too sudden and the duration()
of animation is also 2 seconds, short enough not to make the user bored and lengthy enough to enjoy the transition.
The data
array is where we maintain our node connections and where the heart of the algorithm is. As explained, we'll go through each node, taking chance with all of its neighbors to make a connection. We'll randomly decide whether the node should connect with its neigbor(like flipping a coin), using
if(Math.random() >= 0.5)
return;
The actual algorithm is quite simple as follows:
//Store a and b's association
if(rootOf(a)!=rootOf(b)) {
//console.log(a + " : " + b);
if(data[a]!=a) {
if(data[b]==b) {
data[b] = rootOf(data[a]);
}else {
//This is a second chance
return;
}
}else {
data[a] = rootOf(data[b]);
}
}
The rootOf function finds the root iteratively
var rootOf = function(a) {
while(data[a]!=a) a = data[a];
return a;
}
While the implementation is over simplification of the algorithm, we can see it working quite well. However, for practical purposes, the algorithm can still be optimized depending on the needs.
25 Dec 2014
Howdy! This post lists the steps involved in setting up this blog
I forked this beautiful blog template from Hyde. Like mentioned in the README for the project, we should not be using the forked gh-pages
branch as it contains their Google analytics tracking code and other specific information. For the same reason, I deleted their original gh-pages
branch so all their speicific changes are lost and created a branch with the same name gh-pages
so that Github can create the pages for me, but it will have the default configuration rather than Hyde
hosted page specific configuration.
To delete remote branch,
git remote origin --delete gh-pages
Followed by
git checkout -b gh-pages
Followed by changes to _config.yml
, then
git push remote origin
To push the changes done in gh-pages branch to master
git checkout master
followed by
git merge gh-pages
Hope this helps!