| (!******************************************************
   Mosel User Guide Example Problems
   ================================= 
   file goalctrp.mos 
   ````````````````` 
   Pre-emptive Goal Programming with constraints,
   using function 'sethidden'.
 
   (c) 2008 Fair Isaac Corporation
       author: S. Heipcke, 2001, rev. Jun. 2022
*******************************************************!)
model GoalCtrPreempt
 uses "mmxprs", "mmsystem"
 forward procedure preemptive
 forward procedure printsol(i:integer)
 declarations
   NGOALS=3                          ! Number of goals
   x,y: mpvar                        ! Variables
   dev: array(1..2*NGOALS) of mpvar  ! Deviation from goals
   MinDev: linctr                    ! Objective function
   Goal: array(1..NGOALS) of linctr  ! Goal constraints
 end-declarations
 
 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
  
 preemptive                          ! Pre-emptive Goal Programming
!***********************************************************************
 procedure preemptive
(! 
  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 1..NGOALS) sethidden(Goal(i), true)
  i:=0
  while (i<NGOALS) do
    i+=1
    sethidden(Goal(i), 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)
    if getobjval>0 then
      writeln("Cannot satisfy goal ", i)
      break
    end-if  
    Goal(i)-= Deviation              ! Remove deviation variable(s) from goal
  end-do
  printsol(i)                        ! Solution printout
 end-procedure
!***********************************************************************
 procedure printsol(i:integer)
   declarations
     STypes={CT_GEQ, CT_LEQ, CT_EQ}
     ATypes: array(STypes) of string
   end-declarations
 
   ATypes::([CT_GEQ, CT_LEQ, CT_EQ])[">=", "<=", "="]
 
   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)) 
   forall(g in 1..NGOALS)
     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
end-model
 | 
| (!*******************************************************
   Mosel Example Problems
   ======================
   file goalobjp.mos
   `````````````````
   Using the Xpress multi-objective functionality
   for pre-emptive goal programming with objective functions  
   (c) 2022 Fair Isaac Corporation
       author: S. Heipcke, June 2022
  *******************************************************!)
model GoalObjPreempt
uses "mmxprs", "mmsystem"
forward procedure preemptive
declarations
 NGOALS=3                           ! Number of goals
 GOALS=1..NGOALS                    ! Set of goals
 x,y: mpvar                         ! Variables
 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 
 Goal(1):=   5*x +  2*y - 20
 Goal(2):=  -3*x + 15*y - 48
 Goal(3):= 1.5*x + 21*y - 3.8
! Configuration of the goal objectives
 ObjCfg(1):= objconfig(3, -1, 0, 0.1)  ! 1st, maximize, 10% tolerance 
 ObjCfg(2):= objconfig(2,  1, 4, 0)    ! 2nd, minimize, absolute tolerance of 4
 ObjCfg(3):= objconfig(1, -1, 0, 0.2)  ! 3rd, maximize, 20% tolerance
 preemptive                         ! Pre-emptive goal programming
 
! Inverse priority order (goal 1 becomes last, goal 3 becomes first) 
 forall(g in GOALS) ObjCfg(g).priority:=g        
 preemptive                         ! Resolve the pre-emptive formulation
!***********************************************************************
(! 
  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
  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")=XPRS_SOLSTATUS_OPTIMAL, "/",
      getobjintattr(i, "XPRS_SOLVESTATUS")=XPRS_SOLVESTATUS_COMPLETED, 
      ", val=", getobjrealattr(i, "XPRS_LPOBJVAL"))
  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, if(ObjCfg(g).weight=1,"min","max"),
      Goal(g).sol))
end-procedure
end-model
 |