mplSudoku.py

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

        

Back To Top | Maximal Home Page | List of Samples | Previous Page | Next Page