Initializing help system before first use

Defining, posting and propagating linear constraints


Type: Programming
Rating: 1 (simple)
Description:
  • linctr.mos - Posting and propagating linear constraints
  • scalar_product.mos - Using 'dot' for the formulation of the scalar/dot product between an array of decision variables and an array of reals or integers
File(s): linctr.mos, scalar_product.mos


linctr.mos
(!****************************************************************
   CP example problems
   ===================
   
   file linctr.mos
   ```````````````
   Posting and propagating linear constraints.

   (c) 2008 Artelys S.A. and Fair Isaac Corporation
       Creation: 2005, rev. Mar. 2013
*****************************************************************!)
model "Linear constraints"
 uses "kalis"

 declarations
  N = 3
  R = 1..N
  x: array(R) of cpvar
  c1: cpctr
 end-declarations  

 forall(i in R) do
  0 <= x(i); x(i) <= 50
  setname(x(i), "x"+i)
 end-do

! Automated post+propagation
 x(1) >= x(3) + 5
 writeln(x(1), " ", x(3))
 
! Named constraint (explicit post)
 c1:= x(3) >= x(2) + 10 
 
 if cp_post(c1) then
  writeln("With constraint c1: ", x)
 else exit(1)
 end-if            

! Stop automated propagation
 setparam("kalis_auto_propagate", false)

! Automated post w/o propagation
 x(2) >= 10
 writeln("new bound for x2: ", x) 
 if cp_propagate then
  writeln("after propagation: ", x) 
 end-if

! Minimize the value of x(1) 
 if cp_minimize(x(1)) then
  write("Solution: ")
  forall(i in R) write(getsol(x(i)), " ")
  writeln  
 end-if
end-model

scalar_product.mos
(!******************************************************
   CP example problems
   ===================
   
   file scalar_product.mos
   ```````````````````````
   Using the scalar/dot product operator for the efficient
   creation of `cplinexpr` expressions of the form:
     A_1 * x_1 + A_2 * x_2 + ... + A_n * x_n
   specified as:
     dot(x, A)
   with `x` an array of cpvar or cpfloatvar, and
        `A` an array of real or integer
   in place of using this less efficient form: 
     sum(i in 1..n) (x(i) * A(i))

   Copyright(C) 2019 Artelys S.A. and Fair Isaac Corporation
                     Creation: 2019
*******************************************************!)

model "Scalar_Product"
 uses "kalis"

 setparam("KALIS_VERBOSE_LEVEL", 1)

 declarations
   n: integer         ! Specify the test size
 end-declarations
 n := 10
 if isodd(n) then
   n += 1
 end-if

!**** Case 1: Defining a linear constraint over cpvar ****
 declarations
   R=1..n
   x: array(R) of cpvar
   A: array(R) of real
   AIntVersion: array(R) of integer
   Sp : cplinexp
 end-declarations

! Initialization
 forall(i in R) do
   setname(x(i), "x" +i)
   -100 <= x(i); x(i) <= 100
   A(i) := i
   AInt(i) := i
 end-do

! Constraint definition
 Sp := dot(x, A)
! Same expression as: Sp := sum(i in R) (x(i) * A(i))
 Sp = 3                 ! Posting the constraint

!**** Case 2: Working with 2-dimensional arrays **** 
 m := n div 2
 declarations
   RM=1..m
   R2=1..2
   x2: array(RM, R2) of cpvar
   B: array(RM, R2) of real
   BInt: array(RM, R2) of integer
   sp2 : cplinexp
 end-declarations

! Initialization
 forall(i in RM, j in R2) do
   setname(x2(i,j), "x" + i + "_" + j)
   -100 <= x2(i,j); x2(i,j) <= 100
   B(i,j) := i + j
   BInt(i,j) := i + j
 end-do

! Constraint definition
 Sp2 := dot(x2, B)
 Sp2 = 3

!**** Case 3: Defining a linear constraint with cpfloatvar ****
 writeln("Sub test 3")
 declarations
  x3: array(R) of cpfloatvar
  C: array(R) of real
  CInt: array(R) of integer
  Sp3 : cplinexp
 end-declarations

! Initialization
 forall(i in R) do
  setname(x3(i), "y_" + i)
  -100 <= x3(i); x3(i) <= 100
  C(i) := i
  CInt(i) := i
 end-do

! Constraint definition
 Sp3 := dot(x3, C)
 Sp3 = 3  


!**** Solve the problem ****
 res := cp_minimise(x2(1, 1))
 writeln("Problem solved: ", res)
 writeln("Sp=", Sp.sol, " Sp2=", Sp2.sol, " Sp3=", Sp3.sol)
 writeln(array(i in R) x(i).sol)
 writeln(array(i in RM,j in R2) x2(i,j).sol)
 writeln(array(i in R) x3(i).sol)

!**** Validate the results ****
! Case 1
 result1 := sum(i in R) (getsol(x(i)) * A(i))
 result2 := getsol(Sp)
 if (result1 <> result2 or result1 <> 3) then
    writeln("TEST FAILED : failed for one-dimensionnal array")
    writeln("result1=", result1, ", result2=", result2)
    exit(1)
 end-if

! Case 2
 result1 := sum(i in RM, j in R2) (getsol(x2(i, j)) * B(i, j))
 result2 := getsol(Sp2)
 if (result1 <> result2 or result1 <> 3) then
    writeln("TEST FAILED: failed for multi-dimensional array")
    writeln("result1=", result1, ", result2=", result2)
    exit(1)
 end-if

! Case 3
 tol := 1e-4
 result1 := sum(i in R) (getsol(x3(i)) * C(i))
 result2 := getsol(Sp3)
 if (abs(result1 - result2) > tol or abs(result1 - 3) > tol) then
    writeln("TEST FAILED: failed for cpfloatvar array")
    writeln("result1=", result1, ", result2=", result2)
    exit(1)
 end-if


!**** Validate commutativity of dot operator **** 
 if (getsol(dot(A, x)) <> 3) then
   writeln("TEST FAILED: failed for commutation 1: dot(ar, acpvar)")
   exit(1)
 end-if

 if (getsol(dot(B, x2)) <> 3) then
   writeln("TEST FAILED: failed for commutation 2: dot(ar, acpvar)")
   exit(1)
 end-if

 if (abs(getsol(dot(C, x3)) - 3) > tol) then
   writeln("TEST FAILED: failed for commutation 3: dot(ar, acpfloatvar)")
   exit(1)
 end-if

!**** Validate dot operator with array of integer ****
 if (getsol(dot(x, AInt)) <> 3) then
   writeln("TEST FAILED: failed integer version 1: dot(acpvar, ai)")
   exit(1)
 end-if

 if (getsol(dot(x2, BInt)) <> 3) then
   writeln("TEST FAILED: failed for integer version 2: dot(acpvar, ai)")
   exit(1)
 end-if

 if (abs(getsol(dot(x3, CInt)) - 3) > tol) then
   writeln("TEST FAILED: failed for integer version 3: dot(acpfloatvar, ai)")
   exit(1)
 end-if

 if (getsol(dot(AInt, x)) <> 3) then
   writeln("TEST FAILED: failed for commutation 4: dot(ai, acpvar)")
   exit(1)
 end-if

 if (getsol(dot(BInt, x2)) <> 3) then
   writeln("TEST FAILED: failed for commutation 5: dot(ai, acpvar)")
   exit(1)
 end-if

 if (abs(getsol(dot(CInt, x3)) - 3) > tol) then
   writeln("TEST FAILED: failed for commutation 6: dot(ai, acpfloatvar)")
   exit(1)
 end-if

 writeln("TEST PASSED")

end-model