Initializing help system before first use

Pre-emptive and Archimedian goal programming


Type: Goal Programming
Rating: 3 (intermediate)
Description: goalctr.mos: goal programming using constraints
  • (un)hiding constraints
  • adding and deleting constraint terms
  • getting solution information
  • case statement
  • use of procedures
goalobj.mos: goal programming using objective functions
  • changing constraint type
  • changing the objective function
goalobjmo.mos: same as goalobj.mos, using multi-objective solving functionality
File(s): goalctr.mos, goalobj.mos, goalobjmo.mos


goalctr.mos
(!*******************************************************
  * 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

goalobj.mos
(!*******************************************************
  * 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

goalobjmo.mos
(!*******************************************************
   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

© 2001-2025 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.