Download
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)