广度优先搜索Javascript(算法或输入)

时间:2017-05-10 11:16:22

标签: javascript breadth-first-search

它应该是一个广度优先搜索,标记父母的标签。当它完成后,追踪那些父母回到起点开始走路。

地图只是这些图块的数组

function Tile(x, y){

    this.x = x;
    this.y = y;

    //for BFS
    this.px = 0;
    this.py = 0;
    this.visited = false;

    this.is = " ";

    this.n = null;
    this.e = null;
    this.s = null;
    this.w = null;
}

我不能为我的生活弄清楚它是我的算法还是我的起始数据。

如果有人可以帮我解决这个问题或将其清除为正确,我将非常感激。

    function FakeBFS(){
    var me = this;

    this.get_path = function(sx, sy, ex, ey, map){
        var x = sx;
        var y = sy;
        var unfinished = [{"x":sx, "y":sy}];

        //walk until we can't or we reach our destination
        while(unfinished.length && x != ex && y != ey){

            var new_location = unfinished.shift();

            x = new_location.x;
            y = new_location.y;

            //if we haven't been here...
            if(map.tiles[x][y].visited == false){

                console.log("\n\nlooking for path from:"+x+","+y+" to:"+ex+","+ey);
                var nesw_array = new Array(
                                            [x,y+1], //n
                                            [x+1,y], //e
                                            [x,y-1], //s
                                            [x-1,y]);//w
                                            console.log(nesw_array);

                //add all the vertices we care about to unfinished
                for(var nesw=0; nesw<4; nesw++){
                    var vx = nesw_array[nesw][0];
                    var vy = nesw_array[nesw][1];
                    console.log(nesw_array[nesw]);
                    if( (map.tiles[vx][vy].is == " "
                    ||  map.tiles[vx][vy].is == "H")
                    &&  map.tiles[vx][vy].visited == false){
                        console.log("parenting["+nesw+"]"+map.tiles[vx][vy].x+","+map.tiles[vx][vy].y+" to:"+x+","+y);
                        //set the route we took to get here
                        map.tiles[vx][vy].px = x;
                        map.tiles[vx][vy].py = y;
                        unfinished.push({"x":map.tiles[vx][vy].x, "y":map.tiles[vx][vy].y});
                    }
                }
                //visit this vertex
                map.tiles[x][y].visited = true;
            }

            console.log("END LOOP looking for path from:"+x+","+y+" to:"+ex+","+ey);
        }

        //walk back to start for our path
        var path = Array();
        if(x == ex && y == ey){
            while(x != sx && y != sy){
                path.push({"x":x,"y":y});
                console.log(x+","+y);
                x = map.tiles[x][y].px;
                y = map.tiles[x][y].py;
            }
            path.push({"x":x,"y":y});
            console.log("Path:"+util.inspect(path));
            return path;
        }
        return false;
    }
}

我制作了一些样本数据,它基本上遇到了同样难以确定的问题。 在下面的代码中,“me”指的是Map()对象。

function TestMap(){
    var me = this;
    this.paths = new Array();
    //width and height
    this.size = 10;
    this.num_tiles = this.size*this.size;
    //we can't build on the edge
    this.start = 1;
    this.end = this.size-this.start;

    //
    //
    //tiles
    ////////////////////////////////////////
    this.tiles = new Array();

    //
    //
    //print
    //////////////////////////////////////////
    this.print = function(){
        var mapscii = "";
        for(var y=this.end; y>-1; y--){
            for(var x=0; x<this.size; x++){

                    mapscii += this.tiles[x][y].is;

            }
            mapscii += "\n";
        }
        console.log(mapscii);
    }

    //
    //
    //setup the tile array and the associations
    /////////////////////////////////////////////////
    this.init_map = function (){
        for(var x=0; x<me.size; x++){
            me.tiles[x] = new Array();
            for(var y=0; y<me.size; y++){
                var t = new Tile(x, y);

                //draw bounds
                if(x==0 || y==0 || x==me.size-1 || y==me.size-1){
                    t.is = "#";
                }
                me.tiles[x][y] = t;
            }
        }
    }

    //
    //
    //setup the tile array and the associations
    /////////////////////////////////////////////////
    this.fake_map = function (){
        var fake_rooms = [      [2,2]
                            ,   [2,3]
                            ,   [3,2]
                            //, [3,3]

                            //, [5,2]
                            ,   [5,3]
                            ,   [6,2]
                            ,   [6,3]
                        ];

        var fake_doors = [
                                [3,3]
                            ,   [5,2]
                        ];

        for(var x=0; x<fake_rooms.length; x++){
            me.tiles[fake_rooms[x][0]][fake_rooms[x][1]].is = ".";
        }
        for(var x=0; x<fake_doors.length; x++){
            me.tiles[fake_doors[x][0]][fake_doors[x][1]].is = "H";
        }
    }

    this.fake_place_paths = function(){
        var bfs = new BFS();

        me.paths[0] = bfs.get_path(
                        3,3,
                        5,2,
                        me
            );
    }

    this.mark_paths = function(){
        for(var i=0; i<me.paths.length; i++){
            console.log(me.paths);
            var thispath = me.paths[i];
            console.log("["+i+"]"+thispath.x+","+thispath.y);
            me.tiles[thispath.x][thispath.y].is = "+";
        }
    }

    this.init_map();
    this.fake_map();
    this.fake_place_paths();
    this.print();
    this.mark_paths();
}

这就是“假地图”在打印时的样子。

#= Bounds

。 =房间

H =门

##########
#        #
#        #
#        #
#        #
#        #
# .H ..  #
# .. H.  #
#        #
##########

这是我的调试输出。

C:\Users\trans\Documents\JS>node test_bfs.js


looking for path from:3,3 to:5,2
[ [ 3, 4 ], [ 4, 3 ], [ 3, 2 ], [ 2, 3 ] ]
[ 3, 4 ]
parenting[0]3,4 to:3,3
[ 4, 3 ]
parenting[1]4,3 to:3,3
[ 3, 2 ]
[ 2, 3 ]
END LOOP looking for path from:3,3 to:5,2


looking for path from:3,4 to:5,2
[ [ 3, 5 ], [ 4, 4 ], [ 3, 3 ], [ 2, 4 ] ]
[ 3, 5 ]
parenting[0]3,5 to:3,4
[ 4, 4 ]
parenting[1]4,4 to:3,4
[ 3, 3 ]
[ 2, 4 ]
parenting[3]2,4 to:3,4
END LOOP looking for path from:3,4 to:5,2


looking for path from:4,3 to:5,2
[ [ 4, 4 ], [ 5, 3 ], [ 4, 2 ], [ 3, 3 ] ]
[ 4, 4 ]
parenting[0]4,4 to:4,3
[ 5, 3 ]
[ 4, 2 ]
parenting[2]4,2 to:4,3
[ 3, 3 ]
END LOOP looking for path from:4,3 to:5,2


looking for path from:3,5 to:5,2
[ [ 3, 6 ], [ 4, 5 ], [ 3, 4 ], [ 2, 5 ] ]
[ 3, 6 ]
parenting[0]3,6 to:3,5
[ 4, 5 ]
parenting[1]4,5 to:3,5
[ 3, 4 ]
[ 2, 5 ]
parenting[3]2,5 to:3,5
END LOOP looking for path from:3,5 to:5,2


looking for path from:4,4 to:5,2
[ [ 4, 5 ], [ 5, 4 ], [ 4, 3 ], [ 3, 4 ] ]
[ 4, 5 ]
parenting[0]4,5 to:4,4
[ 5, 4 ]
parenting[1]5,4 to:4,4
[ 4, 3 ]
[ 3, 4 ]
END LOOP looking for path from:4,4 to:5,2


looking for path from:2,4 to:5,2
[ [ 2, 5 ], [ 3, 4 ], [ 2, 3 ], [ 1, 4 ] ]
[ 2, 5 ]
parenting[0]2,5 to:2,4
[ 3, 4 ]
[ 2, 3 ]
[ 1, 4 ]
parenting[3]1,4 to:2,4
END LOOP looking for path from:2,4 to:5,2
END LOOP looking for path from:4,4 to:5,2


looking for path from:4,2 to:5,2
[ [ 4, 3 ], [ 5, 2 ], [ 4, 1 ], [ 3, 2 ] ]
[ 4, 3 ]
[ 5, 2 ]
parenting[1]5,2 to:4,2
[ 4, 1 ]
parenting[2]4,1 to:4,2
[ 3, 2 ]
END LOOP looking for path from:4,2 to:5,2
##########
#        #
#        #
#        #
#        #
#        #
# .H ..  #
# .. H.  #
#        #
##########

[ false ]
[0]undefined,undefined
C:\Users\trans\Documents\JS\testmap.js:102
                        me.tiles[thispath.x][thispath.y].is = "+";
                                            ^

TypeError: Cannot read property 'undefined' of undefined
    at TestMap.mark_paths (C:\Users\trans\Documents\JS\testmap.js:102:24)
    at new TestMap (C:\Users\trans\Documents\JS\testmap.js:110:7)
    at Object.<anonymous> (C:\Users\trans\Documents\JS\test_bfs.js:2:11)
    at Module._compile (module.js:570:32)
    at Object.Module._extensions..js (module.js:579:10)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)
    at Function.Module._load (module.js:438:3)
    at Module.runMain (module.js:604:10)
    at run (bootstrap_node.js:390:7)

1 个答案:

答案 0 :(得分:0)

主要的问题是我离开循环的条件,还修改了我在获取数据之前引用的变量。

           .......................

    //walk until we can't or we reach our destination
    while(unfinished.length){

        var new_location = unfinished.shift();

        x = new_location.x;
        y = new_location.y;

        if(x == ex && y == ey){
            unfinished.length = 0;
            continue;
        }

    ..........................

    //walk back to start for our path
    var path = Array();
    if(x == ex && y == ey){
        console.log("here");
        while(!(x == sx && y == sy)){
            path.push({"x":x,"y":y});
            console.log(x+","+y);
            //temporary to not screw up reference
            var tempx = map.tiles[x][y].px;
            tempx = map.tiles[x][y].px;
            y = map.tiles[x][y].py;
            x = tempx;
            console.log(x+","+y);
        }
        path.push({"x":x,"y":y});
        return path;
    }
    return false;