nodejs A* + 优先队列解8数码问题

题目地址:http://coursera.cs.princeton.edu/algs4/assignments/8puzzle.html

function Puzzle(dimension){

this.array = new Array();

this.moves;

this.manhattan;

this.priority;

this.spacePos;

}

Puzzle.prototype = {

construstor : Puzzle,

init : function (dimension) {

// this.array = [8, 1, 3, 4, 0, 2, 7, 6, 5]

this.array[0] = 8;

this.array[1] = 1;

this.array[2] = 3;

this.array[3] = 4;

this.array[4] = 0;

this.array[5] = 2;

this.array[6] = 7;

this.array[7] = 6;

this.array[8] = 5;

this.moves = 0;

this.manhattan = 0;

for (var i = 0; i < dimension*dimension; i++){

if (this.array[i])

this.manhattan = this.manhattan + Math.floor(Math.abs(this.array[i]-i-1)/dimension) + Math.abs(this.array[i]-i-1)%dimension;

else this.spacePos = i;

}

this.priority = this.moves + this.manhattan;

},

manhattanFn : function (dimension) {

this.manhattan = 0;

for (var i = 0; i < dimension*dimension; i++){

if (this.array[i])

this.manhattan = this.manhattan + Math.floor(Math.abs(this.array[i]-i-1)/dimension) + Math.abs(this.array[i]-i-1)%dimension;

else this.spacePos = i;

}

this.priority = this.moves + this.manhattan;

},

swap : function (a, b){

var tmp = this.array[a];

this.array[a] = this.array[b];

this.array[b] = tmp;

},

clone : function () {

var copy = new Puzzle();

copy.moves = this.moves;

copy.manhattan = this.manhattan;

copy.priority = this.priority;

copy.spacePos = this.spacePos;

for (var i = 0; i < this.array.length; ++i){

copy.array[i] = this.array[i];

}

return copy;

}

}

function PriorityQueue(){

this.cnt;

this.array = new Array();

}

PriorityQueue.prototype = {

constructor : PriorityQueue,

init: function () {

this.cnt = 0;

},

swap : function (a, b){

var tmp = this.array[a];

this.array[a] = this.array[b];

this.array[b] = tmp;

},

push : function (node) {

var curIdx = this.cnt = this.cnt +1;

this.array[curIdx] = node;

//console.log(this);

while (Math.floor(curIdx/2)){

//console.log(Math.floor(curIdx/2));

if (this.array[curIdx].priority < this.array[Math.floor(curIdx/2)].priority){

this.swap(curIdx, Math.floor(curIdx/2));

// var tmp = node.clone();

// this.array[curIdx] = this.array[Math.floor(curIdx/2)].clone();

// this.array[Math.floor(curIdx/2)] = tmp;

}

curIdx = Math.floor(curIdx/2);

}

},

pop : function () {

var minNode = this.array[1];

this.swap(1, this.cnt);

this.cnt = this.cnt - 1;

var curIdx = 1;

//console.log(this);

while (2*curIdx<=this.cnt){

var left = 2*curIdx;

var right = 2*curIdx + 1;

var small = curIdx;

if (this.array[left].priority < this.array[curIdx].priority) small = left;

if (right <= this.cnt && this.array[right].priority < this.array[small].priority) small = right;

this.swap(curIdx, small);

curIdx = 2*curIdx;

}

return minNode;

}

}

var dimension = 3;

var moves = 0;

var puzzle = new Puzzle(dimension);

puzzle.init(dimension);

//console.log(puzzle);

var pq = new PriorityQueue();

pq.init();

pq.push(puzzle);

//console.log(pq);

while(pq.cnt){

moves = moves + 1;

var minNode = pq.pop();

//console.log(pq);

if (minNode.spacePos-dimension >= 0){

var tmp = minNode.clone();

tmp.swap(tmp.spacePos, tmp.spacePos-dimension);

tmp.moves = moves;

tmp.manhattanFn(dimension);

if (tmp.manhattan == 0) return console.log(tmp.moves);

if (tmp.manhattan < minNode.manhattan)

pq.push(tmp);

}

//console.log(minNode.spacePos);

//console.log(tmp.spacePos);

if (minNode.spacePos+dimension < dimension*dimension){

var tmp = minNode.clone();

tmp.swap(tmp.spacePos, tmp.spacePos+dimension);

tmp.moves = moves;

tmp.manhattanFn(dimension);

if (tmp.manhattan == 0) return console.log(tmp.moves);

if (tmp.manhattan < minNode.manhattan)

pq.push(tmp);

}

if (Math.floor(minNode.spacePos/dimension) == Math.floor((minNode.spacePos+1)/dimension)){

var tmp = minNode.clone();

tmp.swap(tmp.spacePos, tmp.spacePos+1);

tmp.moves = moves;

tmp.manhattanFn(dimension);

if (tmp.manhattan == 0) return console.log(tmp.moves);

if (tmp.manhattan < minNode.manhattan)

pq.push(tmp);

}

if (Math.floor(minNode.spacePos/dimension) == Math.floor((minNode.spacePos-1)/dimension)){

var tmp = minNode.clone();

tmp.swap(tmp.spacePos, tmp.spacePos-1);

tmp.moves = moves;

tmp.manhattanFn(dimension);

if (tmp.manhattan == 0) return console.log(tmp.moves);

if (tmp.manhattan < minNode.manhattan)

pq.push(tmp);

}

//console.log(pq);

}

console.log('no wey');

你可能感兴趣的:(nodejs A* + 优先队列解8数码问题)