算法笔记 #007# Backtracking

留着备用。

题目描述和代码参考:https://www.geeksforgeeks.org/8-queen-problem/

NQueenProblem(js代码):

class NQueenProblem {
    static printSolution(board, numOfSolutions) {
        console.log(`第${numOfSolutions}种解法:`);
        for (let i = 0; i != board.length; ++i) {
            let temp = "";
            for (let j = 0; j != board.length; ++j) {
                temp += board[i][j] + " ";
            }
            console.log(temp);
        }
    }
    
    static solve(num) {
        let numOfSolutions = 0;
        let board = CommonUtil.zeros(num, num);
        
        let isSafe = function(col, row) {
            // 检查该行左边有没皇后
            for (let i = 0; i != col; ++i) {
                if (board[i][row] == 1) return false;
            }
            // 检查左上角
            for (let i = col - 1, j = row - 1; i >= 0 && j >= 0; --i, --j) {
                if (board[i][j] == 1) return false;                
            }
            // 检查左下角
            for (let i = col - 1, j = row + 1; i >= 0 && j < num; --i, ++j) {
                if (board[i][j] == 1) return false;                 
            }
            return true;
        };            
        
        let placeNextQueen = function(col) {
            // 如果所有皇后都放置好了,说明找到了一种方案
            if (col >= num) {
                NQueenProblem.printSolution(board, ++numOfSolutions);
                return;
            }                
            
            // 在可以放的地方试探
            for (let i = 0; i != num; ++i) {
                if (isSafe(col, i)) {
                    board[col][i] = 1;
                    placeNextQueen(col + 1);
                    board[col][i] = 0;
                }
            }
        };
        
        placeNextQueen(0);
    }
    
    static run(data) {
        NQueenProblem.solve(Number(data));    
        // Number(data)指的是皇后的数量
    }    
}

/

mColoringProblem(js代码):

class mColoringProblem {
    static printSolution(colorOfPoint, numOfSolutions) {
        console.log(`第${numOfSolutions}种解法:`);
        console.log(colorOfPoint);
        // 例如输出[1, 2, 3, 4, 1],表示第1个点第1种颜色,
        // 表示第2个点第2种颜色,表示第3个点第3种颜色,
        // 表示第4个点第4种颜色,表示第5个点第1种颜色,
    }
    
    static solve(graph, m) {
        let numOfSolutions = 0;
        let colorOfPoint = graph.map(() => 0); // 存储每个点的着色情况

        let isSafe = function(pointId, colorId) {
            // 检查会不会和相邻的已着色点冲突
            for (let i = 0; i != pointId; ++i) {
                if (graph[pointId][i] == 1 && colorId == colorOfPoint[i]) {
                    return false;
                }
            }
            return true;
        };            
        
        let coloringNext = function(pointId) {
            // 如果所有点都已经着色,说明找到了一种方案
            if (pointId >= graph.length) {
                mColoringProblem.printSolution(colorOfPoint, ++numOfSolutions);
                return;
            }                
            
            // 尝试着色
            for (let i = 1; i <= m; ++i) {
                if (isSafe(pointId, i)) {
                    colorOfPoint[pointId] = i;
                    coloringNext(pointId + 1);
                    colorOfPoint[pointId] = 0;
                }
            }
        };
        
        coloringNext(0);
    }

    static run(data) {
        // 输入格式:首个数字表示着色点个数
        // 之后是一个描述无向图的邻接矩阵,
        // 最后是颜色数量
        data = CommonUtil.handleData(data);
        let num = data[0];
        let graph = CommonUtil.zeros(num, num);
        let k = 0;
        for (let i = 0; i != num; ++i) {
            for (let j = 0; j != num; ++j) {
                graph[i][j] = data[++k];
            }
        }
        let m = data[k + 1];
        
        // console.log(num, graph, m);
        mColoringProblem.solve(graph, m);
    }    
}
原文地址:https://www.cnblogs.com/xkxf/p/9998247.html