| (!*******************************************************
  * Mosel Example Problems                              *
  * ======================                              *
  *                                                     *
  * file goalctr.mos                                    *
  * ````````````````                                    *
  * Example for the use of the Mosel language           *
  * (Pre-emptive and Archimedian goal programming       *
  *  using constraints)                                 *
  *                                                     *
  * (c) 2008 Fair Isaac Corporation                     *
  *     author: S. Heipcke, 2001, rev. Sep. 2022        *
  *******************************************************!)
model GoalCtr                       ! Start a new model
uses "mmxprs"                       ! Load the optimizer library
uses "mmsystem"
forward procedure preemptive        ! Declare some procedures that are
forward procedure archimedian       ! defined later
declarations
 NGOALS=3                           ! Number of goals
 GOALS=1..NGOALS
 x,y: mpvar                         ! Variables
 dev: array(1..2*NGOALS) of mpvar   ! Deviation from goals
 MinDev: linctr                     ! Objective function
 Goal: array(GOALS) of linctr       ! Goal constraints
end-declarations
 
 Limit:= 100*x + 60*y <= 600        ! Define a constraint
 
! Define the goal constraints
 Goal(1):=  7*x + 3*y >= 40
 Goal(2):= 10*x + 5*y = 60
 Goal(3):=  5*x + 4*y >= 35
                                    ! Some declarations for a nice printout
declarations
 STypes={CT_GEQ, CT_LEQ, CT_EQ}
 ATypes: array(STypes) of string
end-declarations
 
 ATypes(CT_GEQ):= ">="; ATypes(CT_LEQ):= "<="; ATypes(CT_EQ):= "="
  
 preemptive                         ! Pre-emptive goal programming
 archimedian                        ! Archimedian goal programming
!***********************************************************************
procedure printsol
 
  forall(g in GOALS)
    if(dev(2*g).sol>0) then
      writeln(" Goal(",g,") deviation from target: -", dev(2*g).sol)
    elif(dev(2*g-1).sol>0) then
      writeln(" Goal(",g,") deviation from target: +", dev(2*g-1).sol) 
    end-if
 
end-procedure
!***********************************************************************
procedure preemptive
  writeln("Pre-emptive:")
(! 
  Add successively the goals to the problem and solve it, until all
  goals have been added or a goal cannot be satisfied. This assumes that
  the goals are given ordered by priority.
!)
! Remove (=hide) goal constraint from the problem
  forall(i in GOALS) Goal(i).hidden:=true
  i:=0
  while (i<NGOALS) do
    i+=1
    Goal(i).hidden:=false           ! Add (=unhide) the next goal
    case Goal(i).type of            ! Add deviation variable(s)
     CT_GEQ: do
               Deviation:= dev(2*i)
               MinDev += Deviation 
             end-do
     CT_LEQ: do
               Deviation:= -dev(2*i-1)
               MinDev += dev(2*i-1) 
             end-do
     CT_EQ : do
               Deviation:= dev(2*i) - dev(2*i-1)
               MinDev += dev(2*i) + dev(2*i-1) 
             end-do
     else    writeln("Wrong constraint type")
             break
    end-case  
    Goal(i)+= Deviation
   
    minimize(MinDev)                ! Solve the LP-problem
    writeln(" Solution(", i,"): x: ", x.sol, ", y: ", y.sol)
    Goal(i)-= Deviation             ! Remove deviation variable(s) from goal
    if(getobjval>0) then
      writeln("Cannot satisfy goal ",i)
      break
    end-if  
  end-do
                                    ! Solution printout 
  writeln(" Goal", textfmt("Target",11), textfmt("Value",7))
  forall(g in 1..i) 
    writeln(formattext("%4d %3s %5g %7g", g, ATypes(Goal(g).type), 
      -Goal(g).coeff, Goal(g).act-dev(2*g).sol+dev(2*g-1).sol)) 
  printsol
  
end-procedure
!***********************************************************************
procedure archimedian
  writeln("\nArchimedian:")
  declarations
    Penalty: array(GOALS) of real   ! Penalties for goal constraints 
  end-declarations
  Penalty:: [8, 3, 1]
  MinDev:=0                         ! Re-initialize objective function
! Define the objective as weighted sum of the deviation variables  
  forall(g in GOALS) do
    case Goal(g).type of            ! Add deviation variable(s)
     CT_GEQ: do
               Deviation:= dev(2*g)
               MinDev += Penalty(g)*Deviation 
             end-do
     CT_LEQ: do
               Deviation:= -dev(2*g-1)
               MinDev += Penalty(g)*dev(2*g-1) 
             end-do
     CT_EQ : do
               Deviation:= dev(2*g) - dev(2*g-1)
               MinDev += Penalty(g)*(dev(2*g) + dev(2*g-1)) 
             end-do
     else    writeln("Wrong constraint type")
             break
    end-case  
    Goal(g)+= Deviation
  end-do
    
  minimize(MinDev)                  ! Solve the LP-problem
  writeln(" Solution: x: ", x.sol, ", y: ", y.sol)
                                    ! Solution printout 
  writeln(" Goal", textfmt("Target",11), textfmt("Value",7), textfmt("Penalty",9))
  forall(g in GOALS) 
    writeln(formattext("%4d %3s %5g %7g %7g", g, ATypes(Goal(g).type), 
      -Goal(g).coeff, Goal(g).act-dev(2*g).sol+dev(2*g-1).sol, Penalty(g)))
  printsol
end-procedure
  
end-model
 | 
| (!*******************************************************
  * Mosel Example Problems                              *
  * ======================                              *
  *                                                     *
  * file goalobj.mos                                    *
  * ````````````````                                    *
  * Example for the use of the Mosel language           *
  * (Archimedian and pre-emptive goal programming       *
  *  using objective functions)                         *
  *                                                     *
  * (c) 2008 Fair Isaac Corporation                     *
  *     author: S. Heipcke, 2001, rev. Sep. 2022        *
  *******************************************************!)
model GoalObj                       ! Start a new model
uses "mmxprs"                       ! Load the optimizer library
uses "mmsystem"
forward procedure preemptive        ! Declare some procedures that are
forward procedure archimedian       ! defined later
declarations
 NGOALS=3                           ! Number of goals
 GOALS=1..NGOALS
 x,y: mpvar                         ! Variables
 Type: array(GOALS) of string       ! Type of goal objectives
 Sense: array(GOALS) of string      ! Sense of goal objectives
 Weight: array(GOALS) of real       ! Weights of goals
 Deviation: array(GOALS) of real    ! Max. deviation from goals
 Target: array(GOALS) of real       ! Target (RHS) values for goals
 WObj: linctr                       ! Objective function
 Goal: array(GOALS) of linctr       ! Goal constraints
end-declarations
 Limit:= 42*x + 13*y <= 100         ! Define a constraint
                                    ! Define the goal objectives
 Weight::[100, 1, 0.1]
 Type:: ["perc", "abs", "perc"]
 Sense:: ["max", "min", "max"]
 Deviation:: [10, 4, 20] 
 Goal(1):=   5*x +  2*y - 20
 Goal(2):=  -3*x + 15*y - 48
 Goal(3):= 1.5*x + 21*y - 3.8
 archimedian                        ! Archimedian goal programming
 preemptive                         ! Pre-emptive goal programming
!***********************************************************************
 
procedure archimedian
  writeln("Archimedian:")
  
! Define the objective function as weighted sum of the goals
  forall(g in GOALS)
   if(Sense(g)="max") then
     WObj-=Weight(g)*Goal(g)
   else 
     WObj+=Weight(g)*Goal(g)
   end-if  
  minimize(WObj)                    ! Solve the LP-problem
 
                                    ! Solution printout 
  writeln(" Solution: x: ", x.sol, ", y: ", y.sol)
  writeln(" Goal", textfmt("Target",9), textfmt("Value",12))
  forall(g in GOALS)
    writeln(formattext("%4d %8s %12.6f", g, Sense(g), 
      Goal(g).act + Goal(g).coeff )) 
end-procedure
!***********************************************************************
procedure preemptive
  writeln("\nPre-emptive:")
 
(! 
  Optimize successively the goals. After optimizing a goal turn it 
  into a constraint.
!)
  localsetparam("realfmt","%10.6f")
  i:=0
  while (i<NGOALS) do
    i+=1
    case Sense(i) of
     "max": do
             maximize(Goal(i))                  ! Optimize the next goal
             if(getprobstat<>XPRS_OPT) then
               writeln("Cannot satisfy goal ",i)
               break
             else
               Target(i):=getobjval
               if (Type(i)="perc") then
                 Target(i)-= abs(Target(i))*Deviation(i)/100
               else
                 Target(i)-= Deviation(i)
               end-if
               if(i<NGOALS) then
                 Goal(i):= Goal(i) >= Target(i) ! Turn goal into a constraint
               else
                 Goal(i).type:=CT_GEQ           ! Only for printout
               end-if
             end-if 
            end-do
     "min": do
             minimize(Goal(i))                  ! Optimize the next goal
             if(getprobstat<>XPRS_OPT) then
               writeln("Cannot satisfy goal ",i)
               break
             else
               Target(i):=getobjval
               if (Type(i)="perc") then
                 Target(i)+= abs(Target(i))*Deviation(i)/100
               else
                 Target(i)+= Deviation(i)
               end-if
               if(i<NGOALS) then
                 Goal(i):= Goal(i) <= Target(i) ! Turn goal into a constraint
               else
                 Goal(i).type:=CT_LEQ           ! Only for printout
               end-if
             end-if
            end-do
     else  writeln("Unknown objective sense")
           break
    end-case  
   
    writeln(" Solution(", i,"): x: ", x.sol, ", y: ", y.sol, ", obj: ", getobjval)
  end-do
                                    ! Some declarations for a nice printout
  declarations
    STypes={CT_GEQ, CT_LEQ}
    ATypes: array(STypes) of string
  end-declarations
 
  ATypes::([CT_GEQ, CT_LEQ])[">=", "<="]
                                    ! Solution printout 
  localsetparam("realfmt","%12.6f")
  writeln(" Goal", textfmt("Target",15), textfmt("Value",12))
  forall(g in 1..i) do
    write(formattext("%4d %3s %11.6f", g, ATypes(Goal(g).type), Target(g)))
    if(g=NGOALS) then
      writeln(getobjval)
    else   
      writeln(Goal(g).act+Goal(g).coeff+Target(g)) 
    end-if 
  end-do
end-procedure
end-model
 | 
| (!*******************************************************
   Mosel Example Problems
   ======================
   file goalobjmo.mos
   ``````````````````
   Using the Xpress multi-objective functionality
   for Archimedian and pre-emptive goal programming
   with objective functions  
   (c) 2022 Fair Isaac Corporation
       author: S. Heipcke, June 2022
  *******************************************************!)
model GoalObjMO
uses "mmxprs"                       ! Load the optimizer library
uses "mmsystem"
forward procedure preemptive        ! Declare some procedures that are
forward procedure archimedian       ! defined later
declarations
 NGOALS=3                           ! Number of goals
 GOALS=1..NGOALS
 x,y: mpvar                         ! Variables
 Type: array(GOALS) of string       ! Type of goal objectives
 Sense: array(GOALS) of string      ! Sense of goal objectives
 Weight: array(GOALS) of real       ! Weights of goals
 Deviation: array(GOALS) of real    ! Max. deviation from goals
 Priority: array(GOALS) of integer  ! Priority values for goals
 Goal: array(GOALS) of linctr       ! Goal objective expressions
 ObjCfg: array(GOALS) of objconfig  ! Goal configuration
end-declarations
 Limit:= 42*x + 13*y <= 100         ! Define a constraint
                                    ! Define the goal objectives
 Weight::[100, 1, 0.1]
 Type:: ["perc", "abs", "perc"]
 Sense:: ["max", "min", "max"]
 Deviation:: [10, 4, 20] 
 Priority:: [3, 2, 1]
 
 Goal(1):=   5*x +  2*y - 20
 Goal(2):=  -3*x + 15*y - 48
 Goal(3):= 1.5*x + 21*y - 3.8
 archimedian                        ! Archimedian goal programming
 preemptive                         ! Pre-emptive goal programming
 
! Priority:: [1, 2, 3]               ! Inverse priority order
! preemptive                         ! Resolve the pre-emptive formulation
!***********************************************************************
 
procedure archimedian
  writeln("Archimedian:")
  
 ! Define the objective function as weighted sum of the goals
  forall(g in GOALS)
   if(Sense(g)="max") then
     ObjCfg(g).weight:=-Weight(g)
   else 
     ObjCfg(g).weight:=Weight(g)
   end-if  
  minimize(Goal,ObjCfg)             ! Solve the multi-objective problem
 
                                    ! Solution printout 
  writeln(" Solution: x: ", x.sol, ", y: ", y.sol)
  writeln(" Goal", textfmt("Target",9), textfmt("Value",12))
  forall(g in GOALS)
   writeln(formattext("%4d %8s %12.6f", g, Sense(g), 
     Goal(g).act + Goal(g).coeff ))
end-procedure
!***********************************************************************
(! 
  Optimize successively the goals in given priority order. 
  After optimizing a goal turn it into a constraint applying the specified
  tolerances to the limit given by the solution value.
!)
procedure preemptive
  writeln("\nPre-emptive:")
  forall(g in GOALS) 
   ! Specify inversed objective sense (max vs min) via negative weight values
    case Type(g) of     
      "perc": ObjCfg(g):=
        objconfig(Priority(g), if(Sense(g)="max",-1,1), 0, Deviation(g)/100)
      "abs": ObjCfg(g):= if(Sense(g)="max",
        objconfig(Priority(g), -1, -Deviation(g), 0),
	objconfig(Priority(g), 1, Deviation(g), 0))
      else writeln("Unknown tolerance type")
    end-case
  localsetparam("XPRS_multiobjops", 3)  ! Disable reduced cost fixing (req. with multiple runs)
  minimize(Goal,ObjCfg)             ! Solve the multi-objective problem
                                    ! Solution printout 
  localsetparam("realfmt","%12.6f")
  if(getprobstat=XPRS_OPT) then
    writeln("Solved for all goals (", getparam("XPRS_SOLVEDOBJS"),")")
  elif getparam("XPRS_SOLVEDOBJS")>=1 then
    writeln("Solved for ", getparam("XPRS_SOLVEDOBJS"), " goals")
  else
    writeln("No solution found")
    return
  end-if
  forall(i in GOALS)
    writeln("  Iteration ", i, ": status=", getobjintattr(i, "XPRS_SOLSTATUS"), 
      "/", getobjintattr(i, "XPRS_SOLVESTATUS"), 
      ", val=", getobjrealattr(i, "XPRS_LPOBJVAL"))
  writeln(" Solution: x: ", x.sol, ", y: ", y.sol)
  writeln(" Goal", textfmt("Target",9), textfmt("Value",12), textfmt("(Activity)",13))
  forall(g in GOALS)
    writeln(formattext("%4d %8s %12.6f %12.6f", g, Sense(g), Goal(g).sol, Goal(g).act))
end-procedure
end-model
 |