Initializing help system before first use

K. Puzzles and pastimes


Description: The following models implement solutions to the puzzles published in the book `Programmation Lineaire' by C. Gueret, C. Prins, and M. Sevaux (Eyrolles 2000, in French). Each problem is implemented as a MIP and as a CP model.

Problem name Difficulty
K‑1 Playing Mastermind **
K‑2 Marathon puzzle *
K‑3 Congress puzzle *
K‑4 Placing chips *
K‑5 Nephew puzzle **
K‑6 N-queens problem *


These models show how to formulate different logical constraints using binary variables (MIP models).
File(s): k1masterm.mos, k2marath.mos, k3congress.mos, k4even.mos, k5nephew.mos, k6queens.mos

k1masterm.mos
(!******************************************************
   Mosel Example Problems
   ======================

   file k1mastm.mos
   ````````````````
   Playing Mastermind

   Given information:
   Round  Pos.1   Pos.2   Pos.3   Pos.4   Judgement
    1     red     yellow  white   green   1 color well positioned, 
                                          1 color on wrong position  
    2     blue    green   white   blue    1 color well positioned
    3     yellow  black   white   black   1 color well positioned, 
                                          1 color on wrong position
    4     blue    yellow  red     black   all colors on wrong position
    
   (c) 2008 Fair Isaac Corporation
       author: S. Heipcke, Mar. 2002
*******************************************************!)

model "K-1 Mastermind"
 uses "mmxprs"

 declarations
  POS = 1..4                          ! Positions in a row
  COLORS = {"White","Blue","Yellow","Black","Red","Green"}
    
  place: array(POS,COLORS) of mpvar   ! 1 if color at the position, 0 otherwise
 end-declarations

! Assign one color per position
 forall(p in POS) sum(c in COLORS) place(p,c) = 1 

! Round 1: 1 color well positioned, 1 color on wrong position
  place(1,"Red") + place(2,"Yellow") + place(3,"White") + place(4,"Green") = 1
  sum(p in POS | p<>1) place(p,"Red") + 
    sum(p in POS | p<>2) place(p,"Yellow") +
    sum(p in POS | p<>3) place(p,"White") + 
    sum(p in POS | p<>4) place(p,"Green") = 1
 
! Round 2: 1 color well positioned
  place(1,"Blue") + place(2,"Green") + place(3,"White") + place(4,"Blue") = 1
  sum(p in POS | p<>1 and p<>4) place(p,"Blue") + 
    sum(p in POS | p<>2) place(p,"Green") +
    sum(p in POS | p<>3) place(p,"White") = 0

! Round 3: 1 color well positioned, 1 color on wrong position
  place(1,"Yellow") + place(2,"Black") + place(3,"White") + place(4,"Black") = 1
  sum(p in POS | p<>1) place(p,"Yellow") + 
    sum(p in POS | p<>2 and p<>4) place(p,"Black") +
    sum(p in POS | p<>3) place(p,"White") = 1
 
! Round 4: 4 colors on wrong position
  place(1,"Blue") + place(2,"Yellow") + place(3,"Red") + place(4,"Black") = 0
  sum(p in POS | p<>1) place(p,"Blue") + 
    sum(p in POS | p<>2) place(p,"Yellow") +
    sum(p in POS | p<>3) place(p,"Red") + 
    sum(p in POS | p<>4) place(p,"Black") = 4
 
 forall(p in POS, c in COLORS) place(p,c) is_binary
 
! Solve the problem: no objective
 minimize(0)

! Solution printing
 forall(c in COLORS) writeln(c,": ", getsol(sum(p in POS)p*place(p,c)) )

end-model

k2marath.mos
(!******************************************************
   Mosel Example Problems
   ======================

   file k2marath.mos
   ````````````````
   Marathon puzzle
   
   Dominique, Ignace, Naren, Olivier, Philippe, and Pascal
   have arrived as the first six at the Paris marathon.
   Reconstruct their arrival order from the following
   information:
   a) Olivier has not arrived last
   b) Dominique, Pascal and Ignace have arrived before Naren 
      and Olivier
   c) Dominique who was third last year has improved this year.
   d) Philippe is among the first four.
   e) Ignace has arrived neither in second nor third position.
   f) Pascal has beaten Naren by three positions.
   g) Neither Ignace nor Dominique are on the fourth position.
   
   (c) 2008 Fair Isaac Corporation
       author: S. Heipcke, Mar. 2002
*******************************************************!)

model "K-2 Marathon"
 uses "mmxprs"

 declarations
  POS = 1..6                          ! Arrival positions
  RUNNERS = {"Dominique","Ignace","Naren","Olivier","Philippe","Pascal"}
    
  arrive: array(RUNNERS,POS) of mpvar ! 1 if runner is p-th, 0 otherwise
 end-declarations

! One runner per position
 forall(p in POS) sum(r in RUNNERS) arrive(r,p) = 1 
 
! One position per runner
 forall(r in RUNNERS) sum(p in POS) arrive(r,p) = 1 
 
! a: Olivier not last
 arrive("Olivier",6) = 0

! b: Dominique, Pascal and Ignace before Naren and Olivier
 sum(p in 5..6) (arrive("Dominique",p)+arrive("Pascal",p)+arrive("Ignace",p)) =
   0
 sum(p in 1..3) (arrive("Naren",p)+arrive("Olivier",p)) = 0
 
! c: Dominique better than third
 arrive("Dominique",1)+arrive("Dominique",2) = 1
 
! d: Philippe is among the first four 
 sum(p in 1..4) arrive("Philippe",p) = 1

! e: Ignace neither second nor third
 arrive("Ignace",2)+arrive("Ignace",3) = 0

! f: Pascal three places earlier than Naren
 sum(p in 4..6) arrive("Pascal",p) = 0
 sum(p in 1..3) arrive("Naren",p) = 0

! g: Neither Ignace nor Dominique on fourth position
 arrive("Ignace",4)+arrive("Dominique",4) = 0
 
 forall(p in POS, r in RUNNERS) arrive(r,p) is_binary
 
! Solve the problem: no objective
 minimize(0)

! Solution printing
 forall(r in RUNNERS) writeln(r,": ", getsol(sum(p in POS)p*arrive(r,p)) )

end-model

k3congress.mos
(!******************************************************
   Mosel Example Problems
   ======================

   file k3congress.mos
   ```````````````````
   Congress puzzle
   
   At an international congress taking place on 7-11 August
   five researchers of different nationality are giving talks,
   each on a different day. Find out the date and nationality
   for every researcher from the following information:
   a) Michael is not Japanese.
   b) Eric is French and he talks before the 10th.
   c) Arabinda talks on the 9th.
   d) The Chinese who is not Hitoshi gives his talk on the 8th, 
      before Michael.
   e) Hitoshi does his talk after the Indian and before the American.
   
   (c) 2008 Fair Isaac Corporation
       author: S. Heipcke, Mar. 2002
*******************************************************!)

model "K-3 Congress"
 uses "mmxprs"

 declarations
  DAYS = 7..11
  NAMES = {"Arabinda","Eric","Hitoshi","Michael","Zhicheng"}
  NAT = {"Japanese","French","Chinese","American","Indian"}
    
  talk: array(NAMES,NAT,DAYS) of mpvar ! (p,n,d) 1 if person p of nationality n
                                       ! gives a talk on day d, 0 otherwise
 end-declarations

! One researcher per day and nationality
 forall(p in NAMES) sum(n in NAT, d in DAYS) talk(p,n,d) = 1 
 
! Every nationality exactly once
 forall(n in NAT) sum(p in NAMES, d in DAYS) talk(p,n,d)  = 1 

! One talk per day
 forall(d in DAYS) sum(p in NAMES, n in NAT) talk(p,n,d) = 1
 
! a: Michael is not Japanese
 sum(d in DAYS) talk("Michael","Japanese",d) = 0

! b: Eric is French and he talks before the 10th
 sum(d in 7..9) talk("Eric","French",d) = 1

! c: Arabinda talks on the 9th
 sum(n in NAT) talk("Arabinda",n,9) = 1

! d: The Chinese who is not Hitoshi gives his talk on the 8th, before Michael
 sum(d in DAYS) (talk("Hitoshi","Chinese",d)+talk("Michael","Chinese",d)) = 0
 sum(p in NAMES) talk(p,"Chinese",8) = 1
 sum(n in NAT, d in 9..11) talk("Michael",n,d) = 1

! e: Hitoshi does his talk after the Indian and before the American
 sum(n in NAT) (talk("Hitoshi",n,7)+talk("Hitoshi",n,11)) = 0
 sum(p in NAMES, d in 10..11) talk(p,"Indian",d) = 0
 sum(p in NAMES, d in 7..8) talk(p,"American",d) = 0
 sum(d in DAYS) (talk("Hitoshi","Indian",d)+talk("Hitoshi","American",d)) = 0
 
 forall(p in NAMES, n in NAT, d in DAYS) talk(p,n,d) is_binary
 
! Solve the problem: no objective
 minimize(0)

! Solution printing
 forall(p in NAMES) do
  write(p," (") 
  dp:=round(getsol(sum(n in NAT, d in DAYS)d*talk(p,n,d)))
  forall(n in NAT) write( if(getsol(talk(p,n,dp))>0, n, "") )
  writeln(") : ", dp)
 end-do

end-model

k4even.mos
(!******************************************************
   Mosel Example Problems
   ======================

   file k4even.mos
   ```````````````
   Placing a given number of chips on a 4x4 grid 
   such that every row and every column contains
   an even number of chips.
   - Enumerating multiple solutions -
   
   (c) 2008 Fair Isaac Corporation
       author: S. Heipcke, Mar. 2002, rev. June 2011
*******************************************************!)

model "K-4 Even"
 uses "mmxprs"

 declarations
  POS = 1..4                          ! Positions in a row/column
  NCHIP = 10                          ! Number of chips
    
  place: array(POS,POS) of mpvar      ! 1 if chip at the position, 0 otherwise
  row, column: array(POS) of mpvar    ! Chips per row/column divided by 2
 end-declarations

! Total number of chips
 sum(r,c in POS) place(r,c) = NCHIP

! Even number of chips in all rows and columns
 forall(r in POS) sum(c in POS) place(r,c) = 2*row(r)
 forall(c in POS) sum(r in POS) place(r,c) = 2*column(c)
 
 forall(r,c in POS) place(r,c) is_binary
 forall(r in POS) do
  row(r) is_integer; row(r) <= 2
  column(r) is_integer; column(r) <= 2
 end-do   
 
! Solve the problem: no objective
 setparam("XPRS_enummaxsol", 100)   ! Max. number of solutions to be saved
 minimize(XPRS_ENUM,0)

! Solution printing
 forall(i in 1..getparam("XPRS_enumsols")) do
  selectsol(i)                      ! Select a solution from the pool
  writeln("Solution ", i)
  forall(r in POS) do
   forall(c in POS) write( if(getsol(place(r,c))>0, "X ", ". ") )
   writeln
  end-do
 end-do 
 
end-model

k5nephew.mos
(!******************************************************
   Mosel Example Problems
   ======================

   file k5nephew.mos
   `````````````````
   Distributing wine barrels among nephews
   
   A farmer wishes to distribute his 45 wine barrels among
   his 5 nephews. 9 barrels are full, 9 filled to 3/4, 
   9 half-full, 9 filled to a quarter, and 9 are empty.
   Each nephew is to receive the same number of barrels
   and the same volume of wine. Furthermore, each nephew
   must receive at least one barrel of every type and 
   no two of the nephews must be allocated exactly the
   same number of barrels of every fill type. 
   - Enumerating multiple solutions -
   
   (c) 2008 Fair Isaac Corporation
       author: S. Heipcke, Mar. 2002, rev. June 2011
*******************************************************!)

model "K-5 Nephew"
 uses "mmxprs"

 declarations
  NN = 5; NT = 5
  NEPHEWS = 1..NN                     ! Nephews
  TYPES = 1..NT                       ! Contents types of wine barrels
  BARRELS = 45
    
  COEF: array(TYPES) of integer       ! Factors for "alldifferent" constraint
  FILL: array(TYPES) of real          ! Fill level of barrels

  give: array(NEPHEWS,TYPES) of mpvar ! Barrels of type t for every nephew
  p: array(NEPHEWS) of mpvar          ! 'Pattern': value of the product
                                      !            c*give(n,t)
 end-declarations

 FILL:: [1, 0.75, 0.5, 0.25, 0]
 COEF:: [10000, 1000, 100, 10, 1]

! Barrels per nephew
 forall(n in NEPHEWS) sum(t in TYPES) give(n,t) = BARRELS/NN
 forall(t in TYPES) sum(n in NEPHEWS) give(n,t) = BARRELS/NN

! Equilibrated contents
 forall(n in NEPHEWS) 
  sum(t in TYPES) FILL(t)*give(n,t) = BARRELS/NN * (sum(t in TYPES) FILL(t))/NT

! Every nephew receives a different number of barrels of any given type
! (that is, a different pattern for every nephew)
 forall(n in NEPHEWS) sum(t in TYPES) COEF(t)*give(n,t) = p(n)
 forall(n in 2..NN) p(n) - p(n-1) >= 1

 forall(n in NEPHEWS,t in TYPES) do
  give(n,t) is_integer
  1 <= give(n,t); give(n,t) <= NN
 end-do

! Solve the problem: no objective
 minimize(XPRS_ENUM,0)

! Solution printing
 forall(i in 1..getparam("XPRS_enumsols")) do
  selectsol(i)                      ! Select a solution from the pool
  writeln("Solution ", i)
  forall(n in NEPHEWS) do
   write(n,": ")
   forall(t in TYPES) write( getsol(give(n,t)), " " )
   writeln
  end-do
 end-do
end-model

k6queens.mos
(!******************************************************
   Mosel Example Problems
   ======================

   file k6queens.mos
   `````````````````
   Placing N queens on an NxN chess board such that 
   they do not attack each other.
   - Enumerating multiple solutions -
   
   (c) 2008 Fair Isaac Corporation
       author: S. Heipcke, Mar. 2002, rev. June 2011
*******************************************************!)

model "K-6 Queens"
 uses "mmxprs"

 declarations
  NQ = 8                              ! Number of rows and columns
  POS = 1..NQ
    
  queen: array(POS,POS) of mpvar      ! 1 if queen at a position, 0 otherwise
 end-declarations

! Objective: total number of queens
 Total:= sum(r,c in POS) queen(r,c)

! Single queen per row and column
 forall(r in POS) sum(c in POS) queen(r,c) = 1
 forall(c in POS) sum(r in POS) queen(r,c) = 1

! Diagonals 
 forall(c in POS) sum(r in c..NQ) queen(r-c+1,r) <= 1
 forall(r in 2..NQ) sum(c in r..NQ) queen(c,c-r+1) <= 1
 forall(c in POS) sum(r in 1..c) queen(r,c-r+1) <= 1
 forall(r in 2..NQ) sum(c in r..NQ) queen(c,NQ-c+r) <= 1

 forall(r,c in POS) queen(r,c) is_binary
 
! Solve the problem
 setparam("XPRS_enummaxsol", 100)   ! Max. number of solutions to be saved
 minimize(XPRS_ENUM,Total)

! Solution printing
 forall(i in 1..getparam("XPRS_enumsols")) do
  selectsol(i)                      ! Select a solution from the pool
  writeln("Solution ", i, ". Total number of queens: ", getobjval)
  forall(r in POS) do
   forall(c in POS) write( if(getsol(queen(r,c))>0, "Q ", ". ") )
   writeln
  end-do
 end-do 

end-model

© 2001-2024 Fair Isaac Corporation. All rights reserved. This documentation is the property of Fair Isaac Corporation (“FICO”). Receipt or possession of this documentation does not convey rights to disclose, reproduce, make derivative works, use, or allow others to use it except solely for internal evaluation purposes to determine whether to purchase a license to the software described in this documentation, or as otherwise set forth in a written software license agreement between you and FICO (or a FICO affiliate). Use of this documentation and the software described in it must conform strictly to the foregoing permitted uses, and no other use is permitted.