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 96 97 98 99 100 101 102 103 | /******************************************************************************* * 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.io.Source. _ import scala.math. _ /* Langford's number problem in Oscar. Langford's number problem (CSP lib problem 24) """ Arrange 2 sets of positive integers 1..k to a sequence, such that, following the first occurence of an integer i, each subsequent occurrence of i, appears i+1 indices later than the last. For example, for k=4, a solution would be 41312432 """ * John E. Miller: Langford's Problem http://www.lclark.edu/~miller/langford.html * Encyclopedia of Integer Sequences for the number of solutions for each k @author Hakan Kjellerstrand hakank@gmail.com */ object Langford { def main(args : Array[String]) { val cp = CPSolver() // // data // val k = if (args.length > 0 ) args( 0 ).toInt else 4 ; val num _ to _ show = if (args.length > 1 ) args( 1 ).toInt else 0 ; // // variables // val position = Array.fill( 2 *k)(CPIntVar( 0 to 2 *k- 1 )(cp)) // channel positions to a solution array val solution = Array.fill( 2 *k)(CPIntVar( 1 to k)(cp)) // // constraints // var numSols = 0 cp.solve subjectTo { cp.add(allDifferent(position), Strong) for (i <- 1 to k) { cp.add(position(i+k- 1 ) == (position(i- 1 ) + i+ 1 )) cp.add(solution(position(i- 1 )) == i) cp.add(solution(position(k+i- 1 )) == i) } // symmetry breaking cp.add(solution( 0 ) < solution( 2 *k- 1 )) } search { binary(position, _ .size, _ .min) } onSolution { print( "solution:" + solution.mkString( "" ) + " " ) println( "position:" + position.mkString( "" )) numSols + = 1 } println(cp.start(num _ to _ show)) } } |