forked from Pyomo/pysp
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Moving Pyro examples to example folder
- Loading branch information
Showing
6 changed files
with
151 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
from pyomo.environ import * | ||
|
||
# create a standard python dict for mapping subsquares to | ||
# the list (row,col) entries | ||
subsq_to_row_col = dict() | ||
|
||
subsq_to_row_col[1] = [(i,j) for i in range(1,4) for j in range(1,4)] | ||
subsq_to_row_col[2] = [(i,j) for i in range(1,4) for j in range(4,7)] | ||
subsq_to_row_col[3] = [(i,j) for i in range(1,4) for j in range(7,10)] | ||
|
||
subsq_to_row_col[4] = [(i,j) for i in range(4,7) for j in range(1,4)] | ||
subsq_to_row_col[5] = [(i,j) for i in range(4,7) for j in range(4,7)] | ||
subsq_to_row_col[6] = [(i,j) for i in range(4,7) for j in range(7,10)] | ||
|
||
subsq_to_row_col[7] = [(i,j) for i in range(7,10) for j in range(1,4)] | ||
subsq_to_row_col[8] = [(i,j) for i in range(7,10) for j in range(4,7)] | ||
subsq_to_row_col[9] = [(i,j) for i in range(7,10) for j in range(7,10)] | ||
|
||
# creates the sudoku model for a 10x10 board, where the | ||
# input board is a list of fixed numbers specified in | ||
# (row, col, val) tuples. | ||
def create_sudoku_model(board): | ||
|
||
model = ConcreteModel() | ||
|
||
# store the starting board for the model | ||
model.board = board | ||
|
||
# create sets for rows columns and squares | ||
model.ROWS = RangeSet(1,9) | ||
model.COLS = RangeSet(1,9) | ||
model.SUBSQUARES = RangeSet(1,9) | ||
model.VALUES = RangeSet(1,9) | ||
|
||
# create the binary variables to define the values | ||
model.y = Var(model.ROWS, model.COLS, model.VALUES, within=Binary) | ||
|
||
# fix variables based on the current board | ||
for (r,c,v) in board: | ||
model.y[r,c,v].fix(1) | ||
|
||
# create the objective - this is a feasibility problem | ||
# so we just make it a constant | ||
model.obj = Objective(expr= 1.0) | ||
|
||
# @row_col_cons: | ||
# exactly one number in each row | ||
def _RowCon(model, r, v): | ||
return sum(model.y[r,c,v] for c in model.COLS) == 1 | ||
model.RowCon = Constraint(model.ROWS, model.VALUES, rule=_RowCon) | ||
|
||
# exactly one nubmer in each column | ||
def _ColCon(model, c, v): | ||
return sum(model.y[r,c,v] for r in model.ROWS) == 1 | ||
model.ColCon = Constraint(model.COLS, model.VALUES, rule=_ColCon) | ||
# @:row_col_cons | ||
|
||
# @subsq_con: | ||
# exactly one number in each subsquare | ||
def _SqCon(model, s, v): | ||
return sum(model.y[r,c,v] for (r,c) in subsq_to_row_col[s]) == 1 | ||
model.SqCon = Constraint(model.SUBSQUARES, model.VALUES, rule=_SqCon) | ||
# @:subsq_con | ||
|
||
# @num_con: | ||
# exactly one number in each cell | ||
def _ValueCon(model, r, c): | ||
return sum(model.y[r,c,v] for v in model.VALUES) == 1 | ||
model.ValueCon = Constraint(model.ROWS, model.COLS, rule=_ValueCon) | ||
# @:num_con | ||
|
||
return model | ||
|
||
# use this function to add a new integer cut to the model. | ||
def add_integer_cut(model): | ||
# add the ConstraintList to store the IntegerCuts if | ||
# it does not already exist | ||
if not hasattr(model, "IntegerCuts"): | ||
model.IntegerCuts = ConstraintList() | ||
|
||
# add the integer cut corresponding to the current | ||
# solution in the model | ||
cut_expr = 0.0 | ||
for r in model.ROWS: | ||
for c in model.COLS: | ||
for v in model.VALUES: | ||
if not model.y[r,c,v].fixed: | ||
# check if the binary variable is on or off | ||
# note, it may not be exactly 1 | ||
if value(model.y[r,c,v]) >= 0.5: | ||
cut_expr += (1.0 - model.y[r,c,v]) | ||
else: | ||
cut_expr += model.y[r,c,v] | ||
model.IntegerCuts.add(cut_expr >= 1) | ||
|
||
# prints the current solution stored in the model | ||
def print_solution(model): | ||
for r in model.ROWS: | ||
print(' '.join(str(v) for c in model.COLS | ||
for v in model.VALUES | ||
if value(model.y[r,c,v]) >= 0.5)) |
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
from pyomo.opt import (SolverFactory, | ||
TerminationCondition) | ||
from sudoku import (create_sudoku_model, | ||
print_solution, | ||
add_integer_cut) | ||
|
||
# define the board | ||
board = [(1,1,5),(1,2,3),(1,5,7), \ | ||
(2,1,6),(2,4,1),(2,5,9),(2,6,5), \ | ||
(3,2,9),(3,3,8),(3,8,6), \ | ||
(4,1,8),(4,5,6),(4,9,3), \ | ||
(5,1,4),(5,4,8),(5,6,3),(5,9,1), \ | ||
(6,1,7),(6,5,2),(6,9,6), \ | ||
(7,2,6),(7,7,2),(7,8,8), \ | ||
(8,4,4),(8,5,1),(8,6,9),(8,9,5), \ | ||
(9,5,8),(9,8,7),(9,9,9)] | ||
|
||
model = create_sudoku_model(board) | ||
|
||
solution_count = 0 | ||
while 1: | ||
|
||
with SolverFactory("glpk") as opt: | ||
results = opt.solve(model) | ||
if results.solver.termination_condition != \ | ||
TerminationCondition.optimal: | ||
print("All board solutions have been found") | ||
break | ||
|
||
solution_count += 1 | ||
|
||
add_integer_cut(model) | ||
|
||
print("Solution #%d" % (solution_count)) | ||
print_solution(model) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
WARNING: Constant objective detected, replacing with a placeholder to prevent | ||
solver failure. | ||
Solution #1 | ||
5 3 4 6 7 8 9 1 2 | ||
6 7 2 1 9 5 3 4 8 | ||
1 9 8 3 4 2 5 6 7 | ||
8 5 9 7 6 1 4 2 3 | ||
4 2 6 8 5 3 7 9 1 | ||
7 1 3 9 2 4 8 5 6 | ||
9 6 1 5 3 7 2 8 4 | ||
2 8 7 4 1 9 6 3 5 | ||
3 4 5 2 8 6 1 7 9 | ||
WARNING: Constant objective detected, replacing with a placeholder to prevent | ||
solver failure. | ||
All board solutions have been found |
File renamed without changes.