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 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | /******************************************************************************* * OscaR is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. * * OscaR is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License along with OscaR. * If not, see http://www.gnu.org/licenses/lgpl-3.0.en.html ******************************************************************************/ package oscar.examples.cp.hakank import oscar.cp.modeling. _ import oscar.cp.core. _ import scala.math. _ /** Magic square in Oscar. @author Hakan Kjellerstrand hakank@gmail.com */ object MagicSquare { def main(args : Array[String]) { val cp = CPSolver() val n = if (args.length > 0 ) args( 0 ).toInt else 4 ; val num _ to _ show = if (args.length > 1 ) args( 1 ).toInt else 0 ; val n 2 = n*n println( "n:" + n + " num_to_show: " + num _ to _ show) // // variables // val x = Array.fill(n,n)(CPIntVar( 1 to n 2 )(cp)) val x _ t = x.transpose // val total = CPIntVar(cp, 1 to n*n*n) val total = (n * (n*n + 1 ) / 2 ) // // constraints // cp.solve subjectTo { cp.add(allDifferent(x.flatten), Strong) // rows and columns for (i <- 0 until n) { cp.add(sum(x(i)) == total) cp.add(sum(x _ t(i)) == total) } // diagonals cp.add(sum( for (i <- 0 until n) yield x(i)(i)) == total) cp.add(sum( for (i <- 0 until n) yield x(i)(n-i- 1 ) ) == total) // symmetry breaking cp.add(x( 0 )( 0 ) < x( 0 )(n- 1 )) cp.add(x( 0 )(n- 1 ) < x(n- 1 )( 0 )) cp.add(x( 0 )( 0 ) < x(n- 1 )(n- 1 )) } search { binary(x.flatten.toSeq, _ .size, _ .min) } onSolution { println( "\nSolution:\ntotal " + total) for (i <- 0 until n) { println(x(i).map(j = > "%3d" .format(j.value)).mkString( "" )) } println() } println(cp.start(num _ to _ show)) } } |