Initializing help system before first use

Resource usage profiles


Type: Scheduling
Rating: 3 (intermediate)
Description: Special cases of resource constraints:
  • residle.mos: Preemptive scheduling ('resource idle times'); definition of resource usage profiles.
  • resprofile.mos: Scheduling with resource usage profiles; 'requires' constraints with sets of 'resusage'
  • altresource.mos: Scheduling with resource choice; 'requires' constraints with sets of 'resusage'
File(s): residle.mos, resprofile.mos, resprofile_graph.mos, altresource.mos, altresource_graph.mos


residle.mos
(!****************************************************************
   CP example problems
   ===================
   
   file residle.mos
   ````````````````
   Preemptive scheduling.

   (c) 2008 Artelys S.A. and Fair Isaac Corporation
       Creation: 2008, rev. Sep. 2018        
*****************************************************************!)
model "Preemption"
 uses "kalis"
 
 setparam("KALIS_DEFAULT_LB", 0)

 declarations
  aprofile,bprofile: list of integer
  a,b: cptask
  R: cpresource
 end-declarations 
 
! Define a discrete resource
 set_resource_attributes(R, KALIS_DISCRETE_RESOURCE, 3)

! Create a 'hole' in the availability of the resource:
! Uncomment one of the following two lines to compare their effect
! setcapacity(R, 1, 2, 0);  setcapacity(R, 7, 8, 0)
 setidletimes(R, (1..2)+(7..8))

! Define two tasks (a: constant resource use, b: resource profile) 
 a.duration >= 4
 a.name:= "task_a"
 aprofile:= [1,1,1,1]
 
 b.duration >= 8
 b.name:= "task_b"
 bprofile:= [1,1,1,2,2,2,1,1]
 
! Resource usage constraints 
 requires(a, resusage(R,aprofile))
 requires(b, resusage(R,bprofile)) 

 cp_set_solution_callback("print_solution")   

! Solve the problem 
 if cp_schedule(getmakespan)<>0 then
  cp_show_sol
 else
  writeln("No solution") 
 end-if

! ****************************************************************

 public procedure print_solution    
  writeln("Solution: ", getsol(getmakespan))
  writeln("Schedule: a: ", getsol(getstart(a)), "-", getsol(getend(a))-1,  
          ", b: ", getsol(getstart(b)), "-", getsol(getend(b))-1)
  writeln("Resource usage:")
  forall(t in 0..getsol(getmakespan)-1)
   writeln(strfmt(t,5), ": Cap: ", getcapacity(R,t), ", a:", 
           getrequirement(a, R, t), ", b:", getrequirement(b, R, t)) 
 end-procedure

end-model

resprofile.mos
(!****************************************************************
   CP example problems
   ===================
   
   file resprofile.mos
   ```````````````````
   Scheduling tasks with resource usage profiles.

   (c) 2008 Artelys S.A. and Fair Isaac Corporation
       Creation: 2008, rev. Sep. 2018        
*****************************************************************!)
model "Task resource usage profiles"
 uses "kalis"
 
 setparam("KALIS_DEFAULT_LB", 0)
 
 declarations
  TASKS = {"a","b","c","d"}           ! Index set of tasks
  Profile: array(TASKS) of list of integer   ! Task profiles
  DUR: array(TASKS) of integer        ! Durations of tasks
 
  T: array(TASKS) of cptask           ! Tasks
  R: cpresource                       ! Cumulative resource
 end-declarations 

 DUR::(["a","b","c","d"])[7, 9, 8, 5]
 Profile("a"):= [12, 12, 6, 2, 2, 2, 2]
 Profile("b"):= [12, 12, 6, 2, 2, 2, 2, 2, 2]
 Profile("c"):= [12, 12, 3, 3, 3, 3, 3, 3]
 Profile("d"):= [6, 6, 6, 6, 6]
 
! Define a discrete resource
 set_resource_attributes(R, KALIS_DISCRETE_RESOURCE, 18)
 R.name:="machine"
 
! Define tasks with profiled resource usage 
 forall(t in TASKS) do
  T(t).duration:= DUR(t)
  T(t).name:= t
  requires(T(t), resusage(R, Profile(t)))   
 end-do

 cp_set_solution_callback("print_solution")   
 starttime:=timestamp
 
! Solve the problem 
 if cp_schedule(getmakespan)=0 then
  writeln("No solution")
  exit(0)
 end-if

! Solution printing
 writeln("Schedule with makespan ", getsol(getmakespan), ":")
 forall(t in TASKS)
  writeln(t, ": ", getsol(getstart(T(t))), " - ", getsol(getend(T(t))))

! ****************************************************************

! Print solutions during enumeration at the node where they are found. 
! 'getrequirement' can only be used here to access solution information,
! not after the enumeration (it returns a value corresponding to the  
! current state, that is, 0 after the enumeration).
 public procedure print_solution    
  writeln(timestamp-starttime, "sec. Solution: ", getsol(getmakespan))

  forall(i in 0..getsol(getmakespan)-1) do
   write(strfmt(i,2), ": ")
   forall(t in TASKS | getrequirement(T(t), R, i)>0) 
    write(t, ":", getrequirement(T(t), R, i), "  " )
   writeln(" (total ", sum(t in TASKS) getrequirement(T(t), R, i), ")" )
  end-do   
 end-procedure

end-model

resprofile_graph.mos
(!****************************************************************
   CP example problems
   ===================
   
   file resprofile_graph.mos
   `````````````````````````
   Scheduling tasks with resource usage profiles.
   - Graphical solution representation -

   (c) 2008 Artelys S.A. and Fair Isaac Corporation
       Creation: 2008, rev. Sep. 2017        
*****************************************************************!)
model "Task resource usage profiles"
 uses "kalis", "mmsvg"
 
 setparam("KALIS_DEFAULT_LB", 0)
 
 declarations
  TASKS = {"a","b","c","d"}           ! Index set of tasks
  Profile: array(TASKS) of list of integer   ! Task profiles
  DUR: array(TASKS) of integer        ! Durations of tasks
 
  T: array(TASKS) of cptask           ! Tasks
  R: cpresource                       ! Cumulative resource
 end-declarations 

 DUR::(["a","b","c","d"])[7, 9, 8, 5]
 Profile("a"):= [12, 12, 6, 2, 2, 2, 2]
 Profile("b"):= [12, 12, 6, 2, 2, 2, 2, 2, 2]
 Profile("c"):= [12, 12, 3, 3, 3, 3, 3, 3]
 Profile("d"):= [6, 6, 6, 6, 6]
 
! Define a discrete resource
 set_resource_attributes(R, KALIS_DISCRETE_RESOURCE, 18)
 R.name:="machine"
 
! Define tasks with profiled resource usage 
 forall(t in TASKS) do
  T(t).duration:= DUR(t)
  T(t).name:= t
  requires(T(t), resusage(R, Profile(t)))   
 end-do

! Solve the problem 
 if cp_schedule(getmakespan)=0 then
  writeln("No solution")
  exit(0)
 end-if

 writeln("Solution: ", getsol(getmakespan))

! ************ Drawing a resource usage diagram ************

 declarations
  AProfile: array(TASKS) of array(S:range) of integer   ! Task profile arrays
 end-declarations 

 forall(t in TASKS) do
  ct:=1
  forall(l in Profile(t), ct as counter) AProfile(t,ct):=l
 end-do  

 L:=getsol(getmakespan)

 svgaddgroup("Res", "Resource capacity", SVG_RED)
 forall(i in 2..L)
  svgaddline([i-1, getcapacity(R,i-1), i-1, getcapacity(R,i), i, getcapacity(R,i)]) 

 declarations
  TLIST: list of string
 end-declarations 	

 ! Task graph colors
 ct:= 0
 forall(t in TASKS, ct as counter) do
  svgaddgroup(t, "Task "+t, svgcolor(25+ct*25, 25+ct*25, 50+ct*50))
  svgsetstyle(SVG_FILL,SVG_CURRENT)
 end-do 

 ! Order tasks by start times to obtain a nicer graph
 TCopy:= TASKS
 while (TCopy<>{}) do
  val:=L
  forall(t in TCopy)
   if getsol(getstart(T(t)))<val then
    val:=getsol(getstart(T(t)))
    ind:=t
   end-if 
  TLIST += [ind]
  TCopy-= {ind}
 end-do 

 ! Drawing task graphs
 forall(i in 1..L) do
  CUM:=0

  ! We cannot use 'getrequirement' here to access solution information
  ! if this graph is not drawn directly at the solution node
  forall(t in TLIST | i>getsol(getstart(T(t))) and i<=getsol(getend(T(t))) ) do
   REQ:= AProfile(t,i-getsol(getstart(T(t))))
   svgaddrectangle(t, i-1, CUM, 1, REQ)
   CUM+= REQ
  end-do 
 end-do 
 
 svgsetgraphscale(10)
 svgsetgraphviewbox(svggetgraphviewbox)
 svgsetgraphlabels("Time","Resource usage")

 svgsave("resprof.svg")
 svgrefresh
 svgwaitclose("Close browser window to terminate model execution.", 1)
end-model

altresource.mos
(!****************************************************************
   CP example problems
   ===================
   
   file altresource.mos
   ````````````````````
   Scheduling tasks with resource choice.

   (c) 2008 Artelys S.A. and Fair Isaac Corporation
       Creation: 2008, rev. Sep. 2018       
*****************************************************************!)
model "Alternative resources"
 uses "kalis"
 
 setparam("KALIS_DEFAULT_LB", 0)
 
 declarations
  TASKS = {"a","b","c","d"}           ! Index set of tasks
  MACH = {"M1", "M2"}                 ! Index set of resources
  USE: array(TASKS,MACH) of integer   ! Machine-dependent res. requirement
  DUR: array(TASKS) of integer        ! Durations of tasks
 
  T: array(TASKS) of cptask           ! Tasks
  R: array(MACH) of cpresource        ! Resources
 end-declarations 

 DUR::(["a","b","c","d"])[7, 9, 8, 5]
 USE::(["a","b","c","d"],["M1","M2"])[
      4, 3,
      2, 3,
      2, 1,
      4, 5]

! Define discrete resources
 forall(m in MACH)
  set_resource_attributes(R(m), KALIS_DISCRETE_RESOURCE, 5) 

! Define tasks with machine-dependent resource usages 
 forall(j in TASKS) do
  T(j).duration:= DUR(j)
  T(j).name:= j
  requires(T(j), union(m in MACH) {resusage(R(m), USE(j,m))})   
 end-do

 cp_set_solution_callback("print_solution")   
 starttime:=timestamp

! Solve the problem 
 if cp_schedule(getmakespan)=0 then
  writeln("No solution")
  exit(0)
 end-if

! Solution printing
 forall(j in TASKS)
  writeln(j, ": ", getsol(getstart(T(j))), " - ", getsol(getend(T(j))))
 forall(t in 1..getsol(getmakespan)) do
  write(strfmt(t-1,2), ": ")

  ! We cannot use 'getrequirement' here to access solution information
  ! (it returns a value corresponding to the current state, that is 0)
  forall(j in TASKS | t>getsol(getstart(T(j))) and t<=getsol(getend(T(j)))) 
   write(j, ":", 
         sum(m in MACH) USE(j,m)*getsol(getassignment(T(j),R(m))), "  " )
  writeln
 end-do   

! ****************************************************************

! Print solutions during enumeration at the node where they are found 
 public procedure print_solution    
  writeln(timestamp-starttime, "sec. Solution: ", getsol(getmakespan))

  forall(m in MACH) do
   writeln(m, ":")

   forall(t in 0..getsol(getmakespan)-1) do
    write(strfmt(t,2), ": ")
    forall(j in TASKS | getrequirement(T(j), R(m), t)>0) 
     write(j, ":", getrequirement(T(j), R(m), t), "  " )
    writeln(" (total ", sum(j in TASKS) getrequirement(T(j), R(m), t), ")" )
   end-do

  end-do 
 end-procedure

end-model

altresource_graph.mos
(!****************************************************************
   CP example problems
   ===================
   
   file altresource_graph.mos
   ``````````````````````````
   Scheduling tasks with resource choice.
   - Graphical solution representation -

   (c) 2008 Artelys S.A. and Fair Isaac Corporation
       Creation: 2008, rev. Sep. 2018       
*****************************************************************!)
model "Alternative resources"
 uses "kalis", "mmsvg"
 
 setparam("KALIS_DEFAULT_LB", 0)
 
 declarations
  TASKS = {"a","b","c","d"}           ! Index set of tasks
  MACH = {"M1", "M2"}                 ! Index set of resources
  USE: array(TASKS,MACH) of integer   ! Machine-dependent res. requirement
  DUR: array(TASKS) of integer        ! Durations of tasks
 
  T: array(TASKS) of cptask           ! Tasks
  R: array(MACH) of cpresource        ! Resources
 end-declarations 

 DUR::(["a","b","c","d"])[7, 9, 8, 5]
 USE::(["a","b","c","d"],["M1","M2"])[
      4, 3,
      2, 3,
      2, 1,
      4, 5]

! Define discrete resources
 forall(m in MACH) do
  set_resource_attributes(R(m), KALIS_DISCRETE_RESOURCE, 5)
  R(m).name:=m
 end-do 

! Define tasks with machine-dependent resource usages 
 forall(j in TASKS) do
  T(j).duration:= DUR(j)
  T(j).name:= j
  requires(T(j), union(m in MACH) {resusage(R(m), USE(j,m))})   
 end-do

 cp_set_solution_callback("print_solution")   
 starttime:=timestamp

! Solve the problem 
 if cp_schedule(getmakespan)=0 then
  writeln("No solution")
  exit(0)
 end-if

! Solution printing
 forall(j in TASKS)
  writeln(j, ": ", getsol(getstart(T(j))), " - ", getsol(getend(T(j))))
 forall(t in 1..getsol(getmakespan)) do
  write(strfmt(t-1,2), ": ")

  ! We cannot use 'getrequirement' here to access solution information
  ! (it returns a value corresponding to the current state, that is 0)
  forall(j in TASKS | t>getsol(getstart(T(j))) and t<=getsol(getend(T(j)))) 
   write(j, ":", 
         sum(m in MACH) USE(j,m)*getsol(getassignment(T(j),R(m))), "  " )
  writeln
 end-do   

! ****************************************************************

! Print solutions during enumeration at the node where they are found 
 public procedure print_solution    
  writeln(timestamp-starttime, "sec. Solution: ", getsol(getmakespan))

  forall(m in MACH) do
   writeln(m, ":")

   forall(t in 0..getsol(getmakespan)-1) do
    write(strfmt(t,2), ": ")
    forall(j in TASKS | getrequirement(T(j), R(m), t)>0) 
     write(j, ":", getrequirement(T(j), R(m), t), "  " )
    writeln(" (total ", sum(j in TASKS) getrequirement(T(j), R(m), t), ")" )
   end-do

  end-do 
 end-procedure

! ************ Drawing a resource usage diagram ************

 L:=maxlist(15,getsol(getmakespan))
 C:=5

 ct:=-1
 forall(m in MACH, ct as counter) do
  svgaddgroup(m, "Resource "+m, svgcolor(255,255-50*ct,200-75*ct))
  svgsetstyle(SVG_FILL,SVG_CURRENT)
  svgaddpolygon([0, C*ct]+sum(t in 0..L) [t, getcapacity(R(m),t)+C*ct]+ [L,C*ct])
 end-do
 
 declarations
  TLIST: list of string
 end-declarations 	

 ! Task graph colors
 ct:= 0
 forall(j in TASKS, ct as counter) do
  svgaddgroup(j, "Task "+j, svgcolor(75+ct*25, 75+ct*25, minlist(100+ct*50,255)))
  svgsetstyle(SVG_FILL,SVG_CURRENT)
 end-do

 ! Order tasks by start times to obtain a nicer graph
 TCopy:= TASKS
 while (TCopy<>{}) do
  val:=L
  forall(j in TCopy)
   if getsol(getstart(T(j)))<val then
    val:=getsol(getstart(T(j)))
    ind:=j
   end-if 
  TLIST += [ind]
  TCopy-= {ind}
 end-do 

 ! Drawing task graphs
 forall(t in 1..L) do
  ct:=-1
  forall(m in MACH, ct as counter) do
   CUM:=ct*C

  ! We cannot use 'getrequirement' here to access solution information
  ! if this graph is not drawn directly at the solution node
   forall(j in TLIST | getsol(getassignment(T(j),R(m)))>0 and
                       t>getsol(getstart(T(j))) and t<=getsol(getend(T(j))) ) do
    REQ:= USE(j,m)*getsol(getassignment(T(j),R(m)))
!    svgaddrectanglec(j, t-1, CUM, t, CUM+REQ)
    svgaddrectangle(j, t-1, CUM, 1, REQ)
    CUM+= REQ
   end-do 
  end-do
 end-do 
 
 svgsetgraphscale(20)
 svgsetgraphviewbox(0,0,L,2*C+1)
 svgsetgraphlabels("Time", "Resource usage")

 svgsave("altres.svg")
 svgrefresh
 svgwaitclose("Close browser window to terminate model execution.", 1)

end-model

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