forked from Rishav159/aima-javascript
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds proper color coding in graphs of BFS, Adds DFS, Code rafactored
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
Showing
8 changed files
with
362 additions
and
663 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
230
3-Solving-Problems-By-Searching/c_breadthFirstSearch.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | ||
}) | ||
}) |
Oops, something went wrong.