1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | from Numberjack import * # Magic Square --- CSPLib prob019 # A Magic Square of order N is an N x N matrix of values from 1 to N^2, where # each run, column, and diagonal sum to the same value. This value can be # calculated as N * (N^2 + 1) / 2. def get_model(N): sum_val = N * (N * N + 1 ) / 2 # This is what all the columns, rows and diagonals must add up tp square = Matrix(N, N, 1 , N * N) model = Model( AllDiff(square), [ Sum (row) = = sum_val for row in square.row], [ Sum (col) = = sum_val for col in square.col], Sum ([square[a, a] for a in range (N)]) = = sum_val, Sum ([square[a, N - a - 1 ] for a in range (N)]) = = sum_val ) return square, model def solve(param): square, model = get_model(param[ 'N' ]) solver = model.load(param[ 'solver' ]) solver.setVerbosity(param[ 'verbose' ]) solver.setHeuristic(param[ 'var' ], param[ 'val' ], param[ 'rand' ]) solver.setTimeLimit(param[ 'cutoff' ]) if param[ 'restart' ] = = 'yes' : solver.solveAndRestart() else : solver.solve() out = '' if solver.is_sat(): out = str (square) out + = ( '\nNodes: ' + str (solver.getNodes())) return out default = { 'solver' : 'Mistral' , 'N' : 4 , 'var' : 'MinDomain' , 'val' : 'RandomMinMax' , 'restart' : 'yes' , 'rand' : 2 , 'verbose' : 0 , 'cutoff' : 10 } if __name__ = = '__main__' : param = input (default) print solve(param) |