With the following code, I am trying to get Mathematica to return a 3×3 magic square where the constraint is not that the rows, columns, and diagonals sum to the same value, but rather that they satisfy a given function, memoF[x, y, z].
If memoF[x, y, z] = x + y + z, it works very quickly and without issues. However, as soon as the function becomes more complex —such as in the case I am showing, where functions like Max or KroneckerDelta are used— the computation times become unmanageable. I assume this is because FindInstance starts considering all possible combinations.
I suppose that maybe I should approach the problem in a different way, or perhaps code it in a style more suited to a language where I can have more control over each step... I'm stuck Any ideas?
Clear[memoF];
memoF[x_, y_, z_] :=
memoF[x, y, z] =
Max[Max[x, y] + 1 + KroneckerDelta[x, y], z] + 1 +
KroneckerDelta[Max[x, y] + 1 + KroneckerDelta[x, y], z];
magicSquareILP[k_, target_] :=
Module[{vars, constraints},
vars = Flatten@Table[a[i, j], {i, 3}, {j, 3}];
constraints = Join[
Thread[1 <= vars <= k],
Table[memoF @@ Table[a[i, j], {j, 3}] == target, {i, 3}],
Table[memoF @@ Table[a[j, i], {j, 3}] == target, {i, 3}],
{memoF @@ Diagonal@Array[a, {3, 3}] == target,
memoF @@ Diagonal[Reverse /@ Array[a, {3, 3}]] == target}
];
FindInstance[constraints, vars, Integers, 1]]
With[{k = 4, target = 5}, magicSquareILP[k, target]]
Thank you!
