Juliaによるバックトラッキングアルゴリズムの実装例

バックトラッキングアルゴリズムは、組み合わせ最適化問題を解決するための基本的な手法です。Julia言語を活用することで、明確で効率的な実装が可能です。以下、具体的な問題例を通じて実装方法を解説します。

function solve_queens(n::Int)
    board = zeros(Int, n, n)
    solutions = Vector{Matrix{Int}}()
    place_queens(board, 1, n, solutions)
    return solutions
end

function place_queens(board, row, n, solutions)
    if row > n
        push!(solutions, copy(board))
        return
    end

    for col in 1:n
        if is_valid_position(board, row, col, n)
            board[row, col] = 1
            place_queens(board, row + 1, n, solutions)
            board[row, col] = 0
        end
    end
end

function is_valid_position(board, row, col, n)
    for i in 1:row-1
        if board[i, col] == 1
            return false
        end
        left_diag = col - (row - i)
        if left_diag >= 1 && board[i, left_diag] == 1
            return false
        end
        right_diag = col + (row - i)
        if right_diag <= n && board[i, right_diag] == 1
            return false
        end
    end
    return true
end

数独ソルバーの実装例:

function solve_sudoku_puzzle(board::Matrix{Int})
    empty_cell = find_next_empty(board)
    if empty_cell === nothing
        return true
    end

    row, col = empty_cell
    for num in 1:9
        if is_valid_placement(board, row, col, num)
            board[row, col] = num
            if solve_sudoku_puzzle(board)
                return true
            end
            board[row, col] = 0
        end
    end
    return false
end

function find_next_empty(board)
    for i in 1:9, j in 1:9
        if board[i, j] == 0
            return (i, j)
        end
    end
    return nothing
end

function is_valid_placement(board, row, col, num)
    for j in 1:9
        board[row, j] == num && return false
    end
    for i in 1:9
        board[i, col] == num && return false
    end
    start_row = 3 * (div(row-1, 3)) + 1
    start_col = 3 * (div(col-1, 3)) + 1
    for i in 0:2, j in 0:2
        if board[start_row + i, start_col + j] == num
            return false
        end
    end
    return true
end

全排列の生成:

function generate_permutations(elements)
    results = Vector{Vector{Int}}()
    build_permutations([], elements, results)
    return results
end

function build_permutations(current, remaining, results)
    if isempty(remaining)
        push!(results, copy(current))
        return
    end

    for i in 1:length(remaining)
        new_current = push!(copy(current), remaining[i])
        new_remaining = deleteat(remaining, i)
        build_permutations(new_current, new_remaining, results)
    end
end

部分集合の生成:

function generate_subsets(elements)
    subsets = Vector{Vector{Int}}()
    collect_subsets([], elements, subsets)
    return subsets
end

function collect_subsets(current, remaining, subsets)
    push!(subsets, copy(current))
    for i in 1:length(remaining)
        next_element = remaining[i]
        new_current = push!(copy(current), next_element)
        new_remaining = remaining[i+1:end]
        collect_subsets(new_current, new_remaining, subsets)
    end
end

タグ: julia backtracking n_queens sudoku permutation

5月16日 22:35 投稿