FICO
FICO Xpress Optimization Examples Repository
FICO Optimization Community FICO Xpress Optimization Home
Back to examples browserPrevious exampleNext example

Frequency assignment with polarity

Description
Frequency Assignment Problem with polarization constraints taken from the ROADEF'2001 challenge. The implemented algorithm is a two phase algorithm, the main model runfapp.mos repeatedly runs the submodel fappmod.mos, using different onfigurations.


Source Files
By clicking on a file name, a preview is opened at the bottom of this page.
runfapp.mos[download]
fappmod.mos[download]

Data Files





fappmod.mos

(!****************************************************************
   CP example problems
   ===================
   
   file fappmod.mos
   ````````````````
   Frequency Assignment Problem with Polarity
   - Submodel executed by runfapp.mos -

  (c) 2008 Artelys S.A. and Fair Isaac Corporation
      Creation: 2005, rev. Apr. 2022
*****************************************************************!)

model FAPP
 uses "kalis", "mmjobs"

 parameters
  PHASE=1                                 ! 1: lower bound, 2: solve problem
  BOUND=0                                 ! lower bound value (phase 2 only)
 end-parameters

 ! Evaluate the relaxation level of the current solution
 forward function evaluate_solution(k:integer): integer 
 ! Post the electromagnetic compatibility constraints for a certain level 'k'
 forward function post_CEMX(k:integer) : boolean 
 ! Find a solution minimizing 'k' knowing that kmin is a lower bound on 'k'
 forward procedure solve_FAPP(kmin:integer)
 ! Find a lower bound on 'k'
 forward function find_lb_FAPP : integer    
 
 declarations
  nbTravel:integer                        ! Number of travels
  nbFreqDom:integer                       ! Number of frequency domains
  nbCI:integer                            ! Number of hard constraints
  nbCEME:integer                          ! Number of CEME soft constraints
  nbCEMD:integer                          ! Number of CEMD soft constraints
  Travels: range                          ! Set of Travels
  Freqs: range                            ! Set of frequency domains
  FREQDOMS: dynamic array(Freqs,range) of integer ! Frequency domains
  SIZEDOMS: array(Freqs) of integer       ! Frequency domain sizes
  VKEV: dynamic array(range,range) of integer     ! Soft constraint indices
  VKE : dynamic array(range,range) of integer     ! CEME coefficients
  VKD : dynamic array(range,range) of integer     ! CEMD coefficients
  Types={"F","P"}                         ! Type of constraint ('F' stands for frequency and 'P' for polarity)
  Ops={"E","I"}                           ! Type of constraint ('E' stands for equality and 'I' for inequality)
  TR: array(Travels, Types) of integer    ! Travel data
  CI: dynamic array(Travels, Travels, Types, Ops) of integer ! Hard constraints data
 end-declarations 

! ***** Read data from memory *****
 initializations from "bin:shmem:fappdata"
  nbTravel  nbFreqDom  
  nbCI  nbCEME  nbCEMD  
  FREQDOMS  SIZEDOMS   
  TR  CI   
  VKEV  VKE  VKD 
 end-initializations 
 finalize(Travels)

! ***** Define the problem *****
 declarations 
  freq: array(Travels) of cpvar           ! Frequency variables
  pols: array(Travels) of cpvar           ! Polarity variables
  strategy: array(range) of cpbranching   ! Branching strategy
  BACKTRACKSLIMIT: integer                ! Limit on no. of backtracks
 end-declarations

! Domains of decision variables
 forall(t in Travels) do                  ! for all travels:
  setdomain(freq(t), union(f in 0..SIZEDOMS(TR(t,"F"))-1) {FREQDOMS(TR(t,"F"),f)})                  ! set the corresponding frequency domain
                                          ! set the corresponding polarity domain
  case TR(t,"P") of    
    -1: pols(t)=-1
     0: setdomain(pols(t), {-1,1})   
     1: pols(t)=1
  end-case      
 end-do

! Building Hard constraints
 forall(i,j in Travels, s in Types, o in Ops | exists(CI(i,j,s,o))) do  
  case s of    
   "F": if CI(i,j,s,o) = 0 then           ! a constraint between frequency of travels
         if o="E" then                    ! an equality constraint
          freq(i) = freq(j)               ! posting the constraint Fi = Fj
         elif o="I" then                  ! a difference constraint
          freq(i) <> freq(j)              ! posting the constraint Fi <> Fj
         end-if  
        elif CI(i,j,s,o) <> -1 then  
         if o="E" then                    ! an equality constraint
           CI(i,j,s,o) = distance(freq(i),freq(j))  ! Hard Constraint: |Fi - Fj| == CI(i,j,s,o)
         elif o="I" then                  ! a difference constraint
          CI(i,j,s,o) <> distance(freq(i),freq(j))  ! Hard Constraint: |Fi - Fj| <> CI(i,j,s,o)
         end-if  
        end-if       
   "P": if CI(i,j,s,o) = 0 then           ! a constraint between polarity of travels
         if o="E" then                    ! an equality constraint
             pols(i) = pols(j)            ! Hard Constraint: Pi == Pj
          elif o="I" then                 ! a difference constraint
	     pols(i) <> pols(j)           ! Hard Constraint: Pi <> Pj
          end-if  
        end-if
   end-case     
 end-do


! ***** Start solution algorithm *****
 if PHASE=1 then
  lb := find_lb_FAPP                      ! Determine a lower bound
  initializations to "shmem:lb"           ! Send solution to main problem
   lb
  end-initializations
 else
  solve_FAPP(lb)                          ! Solve the problem
 end-if


!============================================================================
! Calculating a lower bound by posting soft constraints
!============================================================================
 function find_lb_FAPP: integer  
  k := 11
  while ((k >= 0) and post_CEMX(k))  k := k - 1
  writeln("==================================================================")
  writeln("LOWER BOUND : K = " + (k+1))
  writeln("==================================================================")
  returned := k+1
 end-function

!============================================================================
! Solving algorithm
!============================================================================
 procedure solve_FAPP(kmin:integer)
  currentStrategy := 0                     ! current strategy
  strategy(0) := assign_var(KALIS_SMALLEST_DOMAIN,KALIS_RANDOM_VALUE)  ! first strategy
  strategy(1) := assign_var(KALIS_SDOMDEG_RATIO,KALIS_NEAREST_VALUE)   ! second strategy
  strategy(2) := assign_var(KALIS_MAX_DEGREE,KALIS_NEAREST_VALUE)      ! third strategy
  k := 11                                  ! initial relaxation level
  BACKTRACKSLIMIT := integer(nbTravel)     ! initial backtracks limit

  while (k >= kmin) do                     ! while the relaxation level of the current solution is greater than our lower bound.
   cp_set_branching(strategy(currentStrategy)) ! set the search strategy
   setparam("KALIS_MAX_COMPUTATION_TIME",2)    ! limit the computation time to two seconds
   writeln("### Now searching for a solution of level ", k, " / ", kmin, " (", BACKTRACKSLIMIT, ")")
   if not cp_find_next_sol then            ! if no solution was found in the given time
    currentStrategy := (currentStrategy + 1) mod 3  ! switch the search strategy for diversification of search
    if currentStrategy = 0 then            ! all the strategy have been used
     BACKTRACKSLIMIT := BACKTRACKSLIMIT + 10   ! increase backtracks limit
    end-if
    writeln("No solution has been found ... diversification of the search: ", currentStrategy)   
   else                                    ! a solution has been found
    BACKTRACKSLIMIT := integer(nbTravel)   ! reset the backtracks limit
    currentStrategy := 0                   ! reset the current strategy
    k := evaluate_solution(11)             ! evaluate solution
    writeln( "==================================================================")
    writeln("a solution of level k = ", k, " has been found with strategy ", currentStrategy)
    writeln( "==================================================================")
    cp_reset_search                        ! resetting the search tree
    if not post_CEMX(k-1) then             ! posting the soft CEM constraints at level k-1
     writeln("optimal")                    ! a contradiction has occured so the minimal k level i
     break
    end-if       
    k := k - 1                             ! solution current relaxation level is k-1
   end-if  
   cp_reset_search                         ! reset the search tree
  end-do
  writeln("==================================================================")
  writeln("OPTIMAL SOLUTION FOUND : K = " + (k))
  writeln("==================================================================")
 end-procedure 

!============================================================================
! Posting soft constraints
!============================================================================
 function post_CEMX(k:integer): boolean
  writeln("### Now Posting " + (nbCEME) + " CEMX Constraints of level " + k)
  returned := true
  if k <>11 then
   forall(c in 0..nbCEME-1) do    ! for all CEM soft constraints:
    f0 := VKEV(c,0)               ! first frequency variable involved in the constraint
    f1 := VKEV(c,1)               ! second frequency variable involved in the constraint
    vke := VKE(c,k)               ! minimal distance between frequency variables when polarity are equals
    vkd := VKD(c,k)               ! minimal distance between frequency variables when polarity are differents
    if not cp_post(distance(freq(f0),freq(f1)) >= vkd) then  ! posting and propagating the constraint
     returned := false            ! a contradiction occured proving that no solution of level k exists
     break 
    end-if
    implies(pols(f0) = pols(f1),distance(freq(f0),freq(f1)) >= vke)  ! posting the distance constraint
   end-do 
  end-if
 end-function

!============================================================================
! Evaluating the relaxation level of the current solution
!============================================================================
 function evaluate_solution(k:integer): integer
  forall (kk in 0..10) nbViols(kk) := 0    ! initialization of the constraints violation table
  ksol := -1                
  forall(f in 0..nbTravel-1) do
   settarget(freq(f),getsol(freq(f)))    
   settarget(pols(f),getsol(pols(f)))
  end-do
 
  forall(c in 0..nbCEME-1) do     ! for every soft CEM constraints
   v0 := VKEV(c,0)                ! first frequency variable involved in the constraint
   v1 := VKEV(c,1)                ! second frequency variable involved in the constraint
   fv0 :=  getsol(freq(v0))       ! value of the first frequency variable in the current solution
   fv1 :=  getsol(freq(v1))       ! value of the second frequency variable in the current solution
   pv0 :=  getsol(pols(v0))       ! value of the first polarity variable in the current solution
   pv1 :=  getsol(pols(v1))       ! value of the second polarity variable in the current solution
   kv := 0    
 
   forall(kk in 0..k-1) do        ! for all level of  relaxation 'k'
    vke := VKE(c,kk)              ! look the
    vkd := VKD(c,kk)          
    if pv0 = pv1  then            ! polarity are equals in solution
     if not ((fv0 - fv1 >= vke) or (fv1 - fv0 >= vke)) then  ! test of constraint violation
      nbViols(kk) += 1            !
      kv := kk                    !
     end-if
    else                          ! polarity are different in solution
     if not ((fv0 - fv1 >= vkd) or (fv1 - fv0 >= vkd)) then ! test of constraint violation
      nbViols(kk) += 1            ! increase number of constraints violation at level 'kk'
      kv := kk                    !
     end-if
    end-if
   end-do
  
   if kv > ksol then
    ksol := kv                    ! Relaxation level of the solution equal max of relaxation level of all violated constraints.
   end-if
  end-do
  
  sumvk1 := 0
  forall(kk in 0..ksol-1) sumvk1 := sumvk1 + nbViols(kk)  ! compute the sum of violation at level k-1
 
 ! Write some statistics about the solution
  writeln(nbViols(ksol), " constraints violated at level ", ksol)  
  writeln(sumvk1, " constraints violated at level < ", ksol)
  returned := ksol+1              ! return the relaxation level of the solution
 end-function

end-model


Back to examples browserPrevious exampleNext example