Python Example:
from mplpy import *
class MplSudoku(object):
def __init__(self):
self._solValues = []
self._resultString = ""
self._boxAssign = \
[1,1,1,2,2,2,3,3,3,
1,1,1,2,2,2,3,3,3,
1,1,1,2,2,2,3,3,3,
4,4,4,5,5,5,6,6,6,
4,4,4,5,5,5,6,6,6,
4,4,4,5,5,5,6,6,6,
7,7,7,8,8,8,9,9,9,
7,7,7,8,8,8,9,9,9,
7,7,7,8,8,8,9,9,9]
def SolveModel(self, solverName, size, fixedValues):
solver = mpl.Solvers.Add(solverName)
if solver == None:
self._resultString = "Solver " + solverName + " + was not found."
return False
model = mpl.model
model.UseExceptions = True
model.ClearModel()
model.Name = "Sudoku"
result = self._loadModel(model, size, fixedValues)
if not result == ResultType.Success:
if result == ResultType.AddFailed:
self._resultString = model.ResultString
else:
self._resultString = str(model.Error)
model.ClearModel()
return False
try:
model.Solve(solver)
except Exception as ex:
print(str(ex))
result = model.LastResult
if not result == ResultType.Success:
self._resultString = "Solver " + solver.Name + ": " + model.ResultString + "\n" + model.Solution.ResultString
model.ClearModel()
return False
self._resultString = model.Solution.ResultString
self._solValues = self._getSolutionValues(model, size)
model.ClearModel()
return True
def _loadModel(self, model, size, fixedValues):
try:
idxRow = model.IndexSets.AddNumRange("row", 1, size)
model.IndexSets.AddAlias("coln", idxRow)
model.IndexSets.AddNumRange("num", 1, size)
model.IndexSets.AddNumRange("box", 1, size)
model.DataVectors.Add("FixedValues[row,coln]", fixedValues)
model.DataVectors.Add("BoxAssign[row,coln]", self._boxAssign)
model.IndexSets.Add("BoxComp[row,coln,box] WHERE (BoxAssign = box)")
model.VariableVectors.Add("Assign[row,coln,num]", VariableType.Binary)
mplSource = """MODEL
MIN TotalAssign = SUM(row,coln,num: Assign);
SUBJECT TO
SingleCell[row,coln]: SUM(num: Assign) = 1;
SingleRow[row,num]: SUM(coln: Assign) = 1;
SingleCol[coln,num]: SUM(row: Assign) = 1;
SingleBox[box,num]: SUM(row,coln IN BoxComp: Assign) = 1;
FixValue[row,coln,num] WHERE (FixedValues = num): num*Assign = FixedValues;
END"""
model.Parse(mplSource)
except Exception as ex:
print(str(ex))
result = model.LastResult
return result
def _getSolutionValues(self, model, size):
solValues = []
assignVect = model.VariableVectors["Assign"]
for var in assignVect.NonzeroVariables:
row = assignVect.row.Value
col = assignVect.coln.Value
val = assignVect.num.Value
nr = (row - 1) * size + (col - 1)
solValues.append(val)
return solValues
@property
def SolValues(self):
return self._solValues
@property
def ResultString(self):
return self._resultString
@property
def DataDir(self):
return mpl.ModelDirectory