"use strict"; //var tab = window.open(); shortestPathDijkstra( ); function shortestPathDijkstra( ) { var G = mazeB(); //G.print(); return; var sNode; // source node number while (sNode<0 || sNode>G.nnum | sNode%1!==0) { sNode = Number(prompt("source node? (int 0 to "+G.nnum+")?")); } var edge, n, ob; // temps var pq = makePriorityQueue(); // priority queue for best performance var pLen = 0; G.nodes[sNode].dist = pLen; // shortest path source to source is 0 pq.insert(pLen,sNode); // put source node num on queue to get ball rolling while (pq.size() > 0) { // process the min node on the heap ob = pq.getMin(); pq.delMin(); n = ob.val; if (G.nodes[n].handled) { continue; } // might be in pq from earlier pathlength G.nodes[n].handled = true; edge = G.nodes[n].adj; // deal with out edge nodes if any while (edge!==null) { if (!G.nodes[edge.tn].handled) { // dont process if we have already done it pLen = G.nodes[n].dist + edge.weight; if (pLen < G.nodes[edge.tn].dist) { // update distance for dest node G.nodes[edge.tn].dist = pLen; G.nodes[edge.tn].path = n; pq.insert(pLen,edge.tn); } } edge = edge.next; // on to next edge } } //alert("end: "); // now report the results var str = "shortest path lengths from node " + sNode + " (" + G.nodes[sNode].name + ") to:\n"; for (var n=0; n'); lst = this.nodes[i].adj; while (lst!==null) { tab.document.write("       --'" + lst.weight + "'---> "+lst.tn + "
"); lst = lst.next; } } }, print: function(exStr) { var lst; var str = (exStr || "") + "\n"; for (var i=0; i " + lst.tn + "\n" ; lst = lst.next; } } alert(str); }, } return gobj; //================================================================== // end of main graph constructor code body //================================================================== // node and edge factory constructors //================================================================== function makeNodeFactory() { var factory = { idNum:0, gen: function (s) { var node = { idn:this.idNum++, name:(s || "..."), next:null, // list of nodes adj:null, // list of edges indeg:0, outdeg:0, dist:Infinity, // use for shortest path info, etc path:-1, handled:false, } return node; }, } return factory; } function makeEdgeFactory() { var factory = { idNum:0, gen: function (n,wt) { var node = { tn:n, weight:(wt || 1), next:null, // list of edges idn:this.idNum++, } return node; }, } return factory; } } // end of graph constructor //================================================================== // binary heap constructor //================================================================== function makePriorityQueue() { // constructor for a min heap var heap = { elts: [-Infinity], // load bignum into elt 0, slot 0 not used root:1, // slot 1 is always root last:0, // slot last always holds last val used in array elts LC: function (n) { return 2*n; }, // slot num RC: function (n) { return (2*n)+1; }, // slot num PN: function (n) { return Math.floor(n/2); }, // slot num LCV: function (n) { return this.elts[this.LC(n)]; }, // element value RCV: function (n) { return this.elts[this.RC(n)]; }, // element value PNV: function (n) { return this.elts[this.PN(n)]; }, // element value size: function ( ) { return this.last; }, // num vals stored getMin: function ( ) { return this.elts[this.root]; }, insert: function (p,v) { var ob = {pri:p, val:v}; this.last++; this.elts[this.last] = ob; var n=this.last; var p=this.PN(n); var temp; while ( (p!==0) && (ob.pri < this.elts[p].pri) ) { // swap elt in n with elt in p temp=this.elts[n]; this.elts[n]=this.elts[p]; this.elts[p]=temp; n = p; p = this.PN(n); } }, delMin: function () { if (this.size()===0) { return; } if (this.size()===1) { this.elts[1]=Infinity; this.last--; return;} // havbe at least two elts // move last val to root this.elts[this.root]= this.elts[this.last]; this.elts[this.last] = Infinity; this.last--; // bubble down from root var temp, done=false; var n=this.root, c=0; while (!done) { if (this.isLeaf(n)) { done=true; } else { if (this.hasOnlyLC(n)) { c=this.LC(n); } else { c = (this.LCV(n).pri < this.RCV(n).pri) ? this.LC(n) : this.RC(n); } if (this.elts[n].pri > this.elts[c].pri) { temp=this.elts[c]; this.elts[c]=this.elts[n]; this.elts[n]=temp; n = c; } else { done=true; } } } }, isLeaf: function (n) { return ( this.LC(n)>this.last && this.RC(n)>this.last ); }, hasOnlyLC: function (n) { return ( this.RC(n)>this.last && this.LC(n)<=this.last ); }, print: function ( ) { var str="heap elts: \n"; for (var i=1; i<=this.size(); i++) { str += "p: "+this.elts[i].pri + ", v: "+ this.elts[i].val + "\n"; } alert(str); }, } return heap; }