数独。R


数独。R


#版权2021,Gurobi优化,L狗万app足彩LC */ # #数独示例。数独板是一个9x9的网格,它被进一步分成一个3x3的网格。网格中的每个单元格必须取从0到9的值。#在同一行、列或3x3子网格中的两个网格单元格不能取相同的#值。# #在MIP公式中,二进制变量x[i,j,v]表示是否# cell 的值为'v'。约束条件如下:每个cell必须取一个值(sum_v x[i,j,v] = 1) # 2。每个值在每行中使用一次(sum_i x[i,j,v] = 1) # 3。每个值在每个列中使用一次(sum_j x[i,j,v] = 1) # 4。每个值在每个3x3的subgrid (sum_grid x[i,j,v] = 1)中使用一次。 # library(Matrix) library(gurobi) args <- commandArgs(trailingOnly = TRUE) if (length(args) < 1) { stop('Usage: Rscript sudoku.R filename\n') } # Read input file conn <- file(args[1], open='r') if(!isOpen(conn)) { cat('Could not read file',args[1],'\n') stop('Stop now\n') } linn <- readLines(conn) close(conn) # Ensure that all lines have the same length as the number of lines, and # that the character set is the correct one. # Load fixed positions in board Dim <- length(linn) board <- matrix(0, Dim, Dim, byrow = TRUE) if (Dim != 9) { cat('Input file',args[1],'has',Dim,'lines instead of 9\n') stop('Stop now\n') } for (i in 1:Dim) { line <- strsplit(linn[[i]],split='')[[1]] if (length(line) != Dim) { cat('Input line',i,'has',length(line),'characters, expected',Dim,'\n') stop('Stop now\n') } for (j in 1:Dim) { if (line[[j]] != '.') { k <- as.numeric(line[[j]]) if (k < 1 || k > Dim) { cat('Unexpected character in Input line',i,'character',j,'\n') stop('Stop now\n') } else { board[i,j] = k } } } } # Map X[i,j,k] into an index variable in the model nVars <- Dim * Dim * Dim varIdx <- function(i,j,k) {i + (j-1) * Dim + (k-1) * Dim * Dim} cat('Dataset grid:',Dim,'x',Dim,'\n') # Set-up environment env <- list() envlogfile <- 'sudoku.log' #建立模型模型<- list()模型Modelname <- 'sudoku'模型modelsense <- 'min' #创建变量名、类型和边界模型vtype <- 'B'模型lb <- rep(0, nVars)模型ub <- rep(1, nVars)模型varnames <- rep(", nVars) for (i in 1:Dim) {for (j in 1:Dim) {for (k in 1:Dim) {if (board[i,j] == k) modellb[varIdx(i,j,k)] = 1的模型varnames[varIdx(i,j,k)] = paste0('X',i,j,k)}}} #创建(空)约束:模型<- spMatrix(0,nVars)模型RHS <- c()模型感知<- c()模型constrnames <- c() #每个单元格得到一个值:for (i in 1:Dim) {for (j in 1:Dim) {B <- spMatrix(1, nVars, i = rep(1,Dim), j = varIdx(i,j,1:Dim), x = rep(1,Dim))模型< - rbind(模型A、B)模型rhs < - c(模型, 1)模型< - c(模型意义上说,' = ')模型constrnames < - c(模型{for (k in 1:Dim) {B <- spMatrix(1, nVars, i = rep(1,Dim), j = varIdx(i,1:Dim,k), x = rep(1,Dim))模型的每一列必须出现一次< - rbind(模型A、B)模型rhs < - c(模型, 1)模型< - c(模型意义上说,' = ')模型constrnames < - c(模型{for (k in 1:Dim) {B <- spMatrix(1, nVars, i = rep(1,Dim), j = varIdx(1:Dim,j,k), x = rep(1,Dim))模型的每一行必须出现一次< - rbind(模型A、B)模型rhs < - c(模型, 1)模型< - c(模型意义上说,' = ')模型constrnames < - c(模型constrnames paste0 (OnceValueInColumn, j, k))}} #每个值在每一次网格必须出现一次SubDim < - 3 (k 1:暗){(g1在1:SubDim) {(g2在1:SubDim) {B < spMatrix(1、据nvar i =代表(暗),j = c (varIdx (1 + (g1-1) * SubDim (g2-1) * SubDim + 1: SubDim, k), varIdx (2 + (g1-1) * SubDim (g2-1) * SubDim + 1: SubDim, k),varIdx(3+(g1-1)*SubDim,(g2-1)*SubDim + 1:SubDim, k)), x = rep(1,Dim))模型< - rbind(模型A、B)模型rhs < - c(模型, 1)模型< - c(模型意义上说,' = ')模型constrnames < - c(模型}}} # Save model gurobi_write(model, 'sudoku. ');#优化模型结果<- gurobi(model, env = env) if (result . env状态= = '最佳'){猫(解决方案:\ n)猫 ('----------------------------------\ n”)(我在1:暗){(1 j:暗){如果(j % % SubDim = = 1)猫(“|”)(k 1:暗){如果结果x [varIdx (i, j, k)) > 0.99){猫(k ,' ') } } } 猫(“| \ n”)如果(我% % SubDim = = 0)猫 ('----------------------------------\ n”)其他}}{猫(问题是不可行的\ n)} #腾出rm(结果,模型、板、绝壁,env)