Initializing help system before first use

Implementation

The Original Unit Commitment Implementation

The Mosel code printed below implements and solves the original formulation of the unit commitment problem.

 declarations
  NT = 7                              ! Number of time periods
  TIME = 1..NT                        ! Time periods
  PLANTS = 1..4                       ! Power generation plant
  UNITS: set of string                ! Power generation units

  LEN, DEM: array(TIME) of integer    ! Length and demand of time periods
  PMIN,PMAX: array(PLANTS) of integer ! Min. and max output of a generator type
  CSTART: array(PLANTS) of integer    ! Start-up cost of a generator
  CMIN: array(PLANTS) of integer      ! Hourly cost of gen. at min. output
  CADD: array(PLANTS) of real         ! Cost/hour/MW of prod. above min. level
  PLANT: array(UNITS) of integer      ! Unit generation plant

  YEARS: range                        ! Historical years
  HDEM: array(YEARS,TIME) of integer  ! Historical demand profiles

  start: array(UNITS,TIME) of mpvar   ! Is generation unit starting ?
  work: array(UNITS,TIME) of mpvar    ! Is generation unit up ?
  padd: array(UNITS,TIME) of mpvar    ! Production above min. output level
 end-declarations

 initializations from 'a6electr_ro_simple.dat'
  LEN DEM PMIN PMAX CSTART CMIN CADD PLANT HDEM
 end-initializations
! Create decision variables
 forall(u in UNITS, t in TIME) do
  start(u,t) is_binary
  work(u,t) is_binary
 end-do

! Objective function: total daily cost
 Cost:= sum(u in UNITS, t in TIME) (CSTART(PLANT(u))*start(u,t) +
  LEN(t)*(CMIN(PLANT(u))*work(u,t) + CADD(PLANT(u))*padd(u,t)))

! Number of generators started per period and per type
 forall(u in UNITS, t in TIME)
  start(u,t) >= work(u,t) - if(t>1, work(u,t-1), work(u,NT))

! Limit on power production range
 forall(u in UNITS, t in TIME)
  padd(u,t) <= (PMAX(PLANT(u))-PMIN(PLANT(u)))*work(u,t)

! Power balance
 forall(t in TIME)
  sum(u in UNITS) (PMIN(PLANT(u))*work(u,t) + padd(u,t)) = DEM(t)

! Symmetry breaker
 forall(t in TIME, p in PLANTS)
  forall(u1, u2 in UNITS | PLANT(u1) = PLANT(u2) and u1<u2)
   work(u1,t) >= work(u2,t)

!**** Solving and solution reporting ****
! Solve the original problem
 minimize(Cost)

 writeln("\n=== Nominal case ===\n")
 print_solution

! Add robust constraints
 robust_demand

! Solve robust the problem
 setparam("ROBUST_UNCERTAIN_OVERLAP", true)
 minimize(Cost)

 writeln("\n=== Robust against demand variation ===\n")
 print_solution

The following output printing routines are invoked from the model shown above:

!**** Print highest loss of load in case of worst case scenario realization
 procedure print_risk
   write("\n", strfmt("Loss of load",20))
   forall(t in TIME) do
     s:= sum(u in UNITS) (work(u,t).sol*PMAX(PLANT(u))) ! Total capacity
     v:= maxlist(DEM(t), max(y in YEARS) HDEM(y,t))     ! Hist. peak demand
     if(s < v) then
       write(strfmt(v-s,8))
     else
       write(strfmt("",8))
     end-if
   end-do
 end-procedure

!**** Solution printing ****
 procedure print_solution
   writeln("Total cost: ", getobjval)

   write(strfmt("Time period ",-20))
   ct:=0
   forall(t in TIME) do
     write(strfmt(ct,5), "-", strfmt(ct+LEN(t),2), "")
     ct+=LEN(t)
   end-do

   write("\n",strfmt("Up Units",-20))
   forall(t in TIME) write(strfmt(sum(u in UNITS) work(u,t).sol,8))
   write("\n", strfmt("Gen. Pwr.",20))
   forall(t in TIME)
     write(strfmt(sum(u in UNITS) (work(u,t).sol*PMIN(PLANT(u))+padd(u,t).sol),8))
   write("\n", strfmt("Gen. Cap.",20))
   forall(t in TIME)
     write(strfmt(sum(u in UNITS) (work(u,t).sol*PMAX(PLANT(u))),8))
   write("\n", strfmt("Res. Dn",20))
   forall(t in TIME) write(strfmt(sum(u in UNITS) (padd(u,t).sol),8))
   write("\n", strfmt("Res. Up",20))
   forall(t in TIME)
     write(strfmt(sum(u in UNITS) work(u,t).sol*PMAX(PLANT(u)) - DEM(t),8))

   print_risk	
   writeln	
 end-procedure

The Load Robust Unit Commitment Implementation

The extension to scenario-based robust optimization is implemented by the following subroutines.

!**** Helper routine to create scenario uncertain set ****
  public procedure makescenario(a:array(r1:range,c1:range) of integer,
	  u:array(c2:range) of uncertain)
    declarations
      aa:dynamic array(r0:range,U:set of uncertain) of real
    end-declarations
    forall(i in r1, j in c1|exists(a(i,j)) and exists(u(j)),n as counter) do
      aa(n,u(j)):=a(i,j)
    end-do
    scenario(aa)
  end-procedure


!**** Robust against past scenario ****
 public procedure robust_demand
   declarations
     demand: array(TIME) of uncertain    ! Uncertain power demand
   end-declarations

  ! Add uncertainty set (time correlation)
   makescenario(HDEM,demand)

  ! Security reserve upward
   forall(t in TIME) sum(u in UNITS) PMAX(PLANT(u))*work(u,t) >= demand(t)

 end-procedure

The N-k Contingency-Constrained Unit Commitment Implementation

Replacing the call to the procedure robust_demand by a call to the procedure robust_contingency printed below will turn the problem formulation into a N-k contingency-constrained unit commitment model.

The example also demonstrates how to use the value of the uncertain to extract meaningful information about the units which are the most critical ones for the system.

!**** Ensure enough power production capacity allows to
!**** satisfy load even if 'k' units are forced in outage.
 procedure robust_contingency(k: integer)

   forall(t in TIME, u in UNITS) create(outage(u,t))
   forall(t in TIME, u in UNITS) outage(u,t) >= 0
   ! If the unit is forced in outage, the total capacity
   ! of the generating units are lost
   forall(t in TIME, u in UNITS) outage(u,t) <= 1

   ! forall(t in TIME) sum(u in UNITS) outage(u,t) <= k
   forall(t in TIME) cardinality(union(u in UNITS | exists(outage(u,t))) {outage(u,t)}, k)

   forall(t in TIME)
     RobCtrMaxDem(t) := 	
       sum(u in UNITS) PMAX(PLANT(u))*work(u,t) -
       sum(u in UNITS) PMAX(PLANT(u))*work(u,t)*outage(u,t) >= DEM(t)

   ! In order to reduce the number of variables we reuse
   ! outage() and let the solver do the variable duplication
   ! by setting the ROBUST_UNCERTAIN_OVERLAP parameter
   setparam("ROBUST_UNCERTAIN_OVERLAP",true)
   forall(t in TIME)
     RobCtrMinDem(t) :=
       sum(u in UNITS) PMIN(PLANT(u))*work(u,t) -
       sum(u in UNITS) PMIN(PLANT(u))*work(u,t)*outage(u,t) <= DEM(t)

 end-procedure

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