from ortools.sat.python import cp_modelmodel = cp_model.CpModel()z = model.NewIntVar(-100, 100, "z")# z = model.new_int_var(-100, 100, "z") #これでも同じだが,以下ではCamel Stypeに統一する.# boolean variable bb = model.NewBoolVar("b")# implicitly available negation of b:not_b = b.Not() # will be 1 if b is 0 and 0 if b is 1not_b
最適化は, CpSolverのインスタンス solver を準備し,モデルインスタンス model をSolveメソッドの引数として与えることによって実行される. 返値はstatusであり, 定数OPTIMAL(4)のとき最適解が得られたことになる. 最適目的関数値は,ソルバーインスタンスのObjectiveValueメソッドで, 最適解はValueメソッドに変数インスタンスを渡すことによって得られる.
model = cp_model.CpModel()x_vars = [model.NewBoolVar(f"x{i}") for i inrange(10)]model.Minimize(sum(i * x_vars[i] if i %2==0else i * x_vars[i].Not() for i inrange(10)))solver = cp_model.CpSolver()status = solver.Solve(model)if status == cp_model.OPTIMAL:print('Optimal Value:', solver.ObjectiveValue())for i inrange(10):print( solver.Value( x_vars[i]), end=" ")else:print('Solver exited with nonoptimal status:', status)
Optimal Value: 0.0
0 1 0 1 0 1 0 1 0 1
制約
model = cp_model.CpModel()num_vals =3x = model.new_int_var(0, num_vals -1, "x")y = model.new_int_var(0, num_vals -1, "y")z = model.new_int_var(0, num_vals -1, "z")#model.add(x + z == 3 * y)model.add(x + y != z)model.add(x < z) solver = cp_model.CpSolver()status = solver.solve(model)model.Minimize(x+y+z)if status == cp_model.OPTIMAL or status == cp_model.FEASIBLE:print(f"x = {solver.value(x)}")print(f"y = {solver.value(y)}")print(f"z = {solver.value(z)}")else:print('Solver exited with nonoptimal status:', status)
x = 2 y = 1 z = 0
x = 2 y = 0 z = 1
x = 1 y = 0 z = 2
x = 0 y = 1 z = 2
x = 0 y = 2 z = 1
x = 1 y = 2 z = 0
Status = OPTIMAL
Number of solutions found 6
n =10model = cp_model.CpModel()x = {}for i inrange(n):for j inrange(n): x[i, j] = model.NewIntVar(1, n * n, f"x({i},{j})")x_list = [x[i,j] for i inrange(n) for j inrange(n)]model.AddAllDifferent(x_list)s = n*(n**2+1)//2for i inrange(n): model.Add(sum([x[i, j] for j inrange(n)]) == s) for j inrange(n): model.Add(sum([x[i, j] for i inrange(n)]) == s) model.Add(sum([x[i, i] for i inrange(n)]) == s) model.Add(sum([x[i, n - i -1] for i inrange(n)]) == s)solver = cp_model.CpSolver()status = solver.Solve(model)for i inrange(n):for j inrange(n):print(solver.Value(x[i,j]), end=" ")print()
import mathproblem = [[1,0,0, 0,0,7, 0,9,0],[0,3,0, 0,2,0, 0,0,8],[0,0,9, 6,0,0, 5,0,0],[0,0,5, 3,0,0, 9,0,0],[0,1,0, 0,8,0, 0,0,2],[6,0,0, 0,0,4, 0,0,0],[3,0,0, 0,0,0, 0,1,0],[0,4,0, 0,0,0, 0,0,7],[0,0,7, 0,0,0, 3,0,0]]model = cp_model.CpModel() n =len(problem)cell_size = math.ceil(math.sqrt(n))line_size = cell_size **2line =range(0, line_size)cell =range(0, cell_size)x = {}for i in line:for j in line: x[i, j] = model.NewIntVar(1, line_size, f"x({i},{j})")for i in line: model.AddAllDifferent([x[i, j] for j in line])for j in line: model.AddAllDifferent([x[i, j] for i in line])for i in cell:for j in cell: one_cell = []for di in cell:for dj in cell: one_cell.append(x[(i * cell_size + di, j * cell_size + dj)]) model.AddAllDifferent(one_cell)for i in line:for j in line:if problem[i][j]: model.Add(x[i, j] == problem[i][j])solver = cp_model.CpSolver()status = solver.Solve(model)for i in line:for j in line:print(solver.Value(x[i,j]), end=" ")print()
#唯一の解であることの確認solution_printer = VarArraySolutionPrinter([x[i,j] for i in line for j in line])status = solver.SearchForAllSolutions(model, solution_printer)print("Status", solver.StatusName(status))print("Number of solutions found", solution_printer.solution_count())
import timeclass NQueenSolutionPrinter(cp_model.CpSolverSolutionCallback):def__init__(self, queens: list[cp_model.IntVar]): cp_model.CpSolverSolutionCallback.__init__(self)self.__queens = queensself.__solution_count =0self.__start_time = time.time()def solution_count(self) ->int:returnself.__solution_countdef on_solution_callback(self) ->None: current_time = time.time()print("Solution %i, time = %f s" )self.__solution_count +=1 all_queens =range(len(self.__queens))for i in all_queens:for j in all_queens:ifself.value(self.__queens[j]) == i:# There is a queen in column j, row i.print("Q", end=" ")else:print("_", end=" ")print()print()board_size =5model = cp_model.CpModel()queens = [ model.new_int_var(0, board_size -1, "x%i"% i) for i inrange(board_size)]# All columns must be different because the indices of queens are all# different, so we just add the all different constraint on the rows.model.add_all_different(queens)# No two queens can be on the same diagonal.diag1 = []diag2 = []for i inrange(board_size): q1 = model.new_int_var(0, 2* board_size, "diag1_%i"% i) q2 = model.new_int_var(-board_size, board_size, "diag2_%i"% i) diag1.append(q1) diag2.append(q2) model.add(q1 == queens[i] + i) model.add(q2 == queens[i] - i)model.add_all_different(diag1)model.add_all_different(diag2)solver = cp_model.CpSolver()solution_printer = NQueenSolutionPrinter(queens)solver.parameters.enumerate_all_solutions =Truestatus = solver.solve(model, solution_printer)
from ortools.sat.python import cp_modelimport numpy as npfrom itertools import productdata ="""\ B B C A......BB...... C...... ......A ......C ...... BC CA """.split('\n')nn =len(data)-2def chk(v, c, isless): k =ord(c) -65if k >=0:for j inrange(3):if j != k: model.Add(v[k] < v[j] if isless else v[k] > v[j])model = cp_model.CpModel()vh = np.array([[model.NewIntVar(0, nn -1, f'vh{i}{j}') for j inrange(3)] for i inrange(nn)])vv = np.array([[model.NewIntVar(0, nn -1, f'vv{i}{j}') for j inrange(3)] for i inrange(nn)])for i inrange(nn): model.AddAllDifferent(vh[i]) model.AddAllDifferent(vv[i]) chk(vv[i], data[0][i +1], True) chk(vv[i], data[nn +1][i +1], False) chk(vh[i], data[i +1][0], True) chk(vh[i], data[i +1][nn +1], False)for i, j, k in product(range(nn), range(nn), range(3)): vb1, vb2 = model.NewBoolVar(f'vb1{i}{j}{k}'), model.NewBoolVar(f'vb2{i}{j}{k}') model.Add(vh[i][k] == j).OnlyEnforceIf(vb1) model.Add(vv[j][k] != i).OnlyEnforceIf(vb2) model.AddBoolXOr([vb1, vb2])solver = cp_model.CpSolver()status = solver.Solve(model)res = np.vectorize(solver.Value)(vh)cc = np.full((nn, nn), '.')for i, j in product(range(nn), range(3)): cc[i][res[i][j]] =chr(65+ j)print('\n'.join(' '.join(s) for s in cc))
. A . C B .
. . B . A C
. C A . . B
B . C . . A
A . . B C .
C B . A . .