Skip to content

Commit

Permalink
Adds proper color coding in graphs of BFS, Adds DFS, Code rafactored
Browse files Browse the repository at this point in the history
Node expansion code refactored

Added BFS visualization and FIFO queue

Added ajax for bfs code

Fixes nodeExpansion Bug, BFS reuses nodeExpansion code, Actual bfs code hidden from the user

Changes color of the next node to be expanded in graph of bfs

Adds next node correspondance to graph nodes and adds dfs

Adds green color to the initial queue in dfs
  • Loading branch information
Rishav159 committed Mar 20, 2017
1 parent 0825297 commit ffc5310
Show file tree
Hide file tree
Showing 8 changed files with 362 additions and 663 deletions.
38 changes: 2 additions & 36 deletions 3-Solving-Problems-By-Searching/breadthFirstSearch.js
Original file line number Diff line number Diff line change
@@ -1,37 +1,3 @@

var breadthFirstSearch = function(problem){
this.problem = problem;
this.node = problem.INITIAL;
if(this.problem.GOAL_TEST(this.node)){
return this.problem.NO_ACTION;
}
this.frontier = [this.node];
this.explored = {};
this.iterate = function(){
var isNewState = false;
//If Goal reached, Return No Action
if(this.problem.GOAL_TEST(this.node)){
return [isNewState,this.problem.NO_ACTION];
}
//If stack is empty, return No Action
if(this.frontier.length == 0){
return [isNewState,this.problem.NO_ACTION];
}
//Extract the shallowest node from the queue
node = this.frontier.shift();
this.node = node;
//Add Extracted node to explored
this.explored[node] = true;
actions = this.problem.ACTIONS(node)
for(var i = 0; i < actions.length; i++){
var action = actions[i]
child = this.problem.CHILD_NODE(node,action);
if(!this.explored[child]){
this.frontier.push(child);
this.explored[child] = true;
}
}
isNewState = true;
return [isNewState,node]
}
var breadthFirstSearch = function(frontier){
return frontier[0];
}
230 changes: 47 additions & 183 deletions 3-Solving-Problems-By-Searching/c_breadthFirstSearch.js
Original file line number Diff line number Diff line change
@@ -1,190 +1,54 @@
var bfsProblemStatement = function(graph,start,end){

this.graph = graph;
this.ROWS = this.graph.length;
this.COLS = this.graph[0].length;
this.TOTAL_STATES = this.ROWS * this.COLS;
this.INITIAL = start;
this.END = end;

this.NO_ACTION = 0;
this.UP = 1;
this.RIGHT = 2;
this.DOWN = 3;
this.LEFT = 4;

this.at = function(i,j){
return i * this.COLS + j;
};
this.getIJ = function(x){
return [parseInt(x/this.COLS),x%this.COLS];
};
this.GOAL_TEST = function(state){
return this.END == state;
};
this.ACTIONS = function(state){
var actions = [this.NO_ACTION];
var i = this.getIJ(state)[0];
var j = this.getIJ(state)[1];
if(i - 1 >= 0 && !this.graph[i-1][j]) actions.push(this.UP);
if(i + 1 < this.ROWS && !this.graph[i+1][j]) actions.push(this.DOWN);
if(j - 1 >= 0 && !this.graph[i][j-1]) actions.push(this.LEFT);
if(j + 1 < this.COLS && !this.graph[i][j+1]) actions.push(this.RIGHT);
return actions;
};
this.CHILD_NODE = function(state,action){
var x = this.getIJ(state)[0];
var y = this.getIJ(state)[1];
switch(action){
case this.NO_ACTION: break;
case this.UP:x--;break;
case this.RIGHT:y++;break;
case this.DOWN:x++;break;
case this.LEFT:y--;break;
}
return this.at(x,y)
}
};



$(document).ready(function(){
$.ajax({
url : "breadthFirstSearch.js",
dataType: "text",
success : function (data) {
$("#breadthFirstSearchCode").html(data);
}
});


var two,canvas,bfs;

var graph = [[0,0,0,0,1,1,0,0,1,1],
[1,1,0,0,1,0,1,0,0,0],
[0,0,0,0,0,0,0,0,1,1],
[0,0,1,0,1,1,0,0,0,0],
[0,1,1,0,1,1,1,1,0,1],
[0,0,1,0,1,1,0,1,0,0],
[1,0,1,0,1,0,0,0,0,0]];

var start = 0;
var end = 19;

var DELAY = 0.5 *60;
var SIZE = 40;
var NONBLOCKING = "#AAAACC";
var BLOCKING = "#555577";
var EXPLORED = "#edb168";
var STARTCOLOR = "#EE6622";
var ENDCOLOR = "#66EE22";
var FINISHCOLOR = "#0d6d1e";
var w,h,baseX,baseY;

var problem = undefined;
var state,lastState;
var m_frame = DELAY;
var tiles = [];
var isBinded = false;

function clickHandler(){
two.unbind('update');
tiles = [];
m_frame = DELAY;
//Block-Unblock the clicked cell
//Index attribute of the tag will contain its index in the graph
index = this.getAttribute('index');
if(index != start && index != end){
[x,y] = problem.getIJ(index);
if(graph[x][y] == 1){
graph[x][y] = 0;
}else{
graph[x][y] = 1;
}
}
isBinded = false;
init();
}
function updateHandler(frameCount){
//We need to check if two has already rendered the tags before attempting
//to bind the click event.
if(!isBinded && document.getElementById(tiles[0].id)){
for(var i=0;i<tiles.length;i++){
var elem = document.getElementById(tiles[i].id);
//Each path tag will now have index attribute containing its index
//in the graph array
elem.setAttribute('index',i)
elem.addEventListener('click',clickHandler)
}
isBinded = true;
}
--m_frame;
lastState = state;
if(m_frame == 0){
step();
m_frame = DELAY
}else{
interpolate();
}
};

var w = 600, h = 350;
var visGraph = null;
var visQueue = null;
var agent = null;
var initial = 0;
var end = 16;
var canvas = null;
var queueCanvas = null;
var DELAY = 2000;
var updateFunction = null;
var intervalFunction = null;
var nextNodeColor = 'hsl(108, 96%, 50%)';
function init(){
canvas = document.getElementById('breadthFirstSearchCanvas');
canvas.innerHTML = "";
w = canvas.offsetWidth, h = 300;
two = new Two({width:w , height:h}).appendTo(canvas);
problem = new bfsProblemStatement(graph,start,end);
bfs = new breadthFirstSearch(problem);

state = lastState = problem.INITIAL;
baseX = two.width/2 - problem.COLS/2 * SIZE;
baseY = two.height/2 - problem.ROWS/2 * SIZE;

two.bind('update',updateHandler).play();

drawBackground();

};

function step(){
var isNewState,newState;
[isNewState,newState] = bfs.iterate();
if(isNewState){
state = newState;

}
};



function drawBackground(){
for(var i = 0; i < problem.ROWS; i++){
for(var j = 0; j < problem.COLS; j++){
var temp = two.makeRectangle(SIZE/2+j*SIZE,SIZE/2+i*SIZE,SIZE,SIZE);
if(problem.graph[i][j])
temp.fill = BLOCKING;
else
temp.fill = NONBLOCKING;
temp.noStroke();
tiles.push(temp);
queueCanvas = document.getElementById('fifoQueueCanvas');
graph = new makeDefaultGraph();
agent = new nodeExpansionAgent(graph.adjMatrix,initial);
visGraph = new drawGraph(canvas,h,w,agent,graph.nodes,graph.adjMatrix);
visQueue = new drawQueue(queueCanvas,h,w,agent,graph.nodes);
visGraph.init();
visQueue.init();
visGraph.nodeGroups[initial].children[0].fill = nextNodeColor;
visQueue.rectangles[0].fill = nextNodeColor;
visGraph.two.update();
visQueue.two.update();
updateFunction = function(){
frontier = agent.frontier;
if(frontier.length == 0){
clearInterval(intervalFunction,DELAY);
}else{
var x = breadthFirstSearch(frontier);
agent.expand(x);
visGraph.iterate();
visQueue.iterate();
if(agent.frontier.length != 0){
visGraph.nodeGroups[agent.frontier[0]].children[0].fill = nextNodeColor;
visGraph.two.update();
visQueue.rectangles[0].fill = nextNodeColor;
visQueue.two.update();
}
}
}

tiles[problem.INITIAL].fill = STARTCOLOR;
tiles[problem.END].fill = ENDCOLOR;
var backgroundGroup = two.makeGroup(tiles);
backgroundGroup.translation.set(baseX,baseY);
};
intervalFunction = setInterval(updateFunction,DELAY);
$('#fifoWaiting').css('background-color',visQueue.waitingColor);
$('#fifoNextNode').css('background-color',nextNodeColor);
};

function interpolate(){
if(state != problem.INITIAL && state!= problem.END){
tiles[state].fill = EXPLORED;
}
if(state == problem.END){
tiles[state].fill = FINISHCOLOR;

}
}

init();
});
$('#bfsRestartButton').click(function(){
clearInterval(intervalFunction,DELAY);
init();
})
})
Loading

0 comments on commit ffc5310

Please sign in to comment.