Forum Discussion

FICO's avatar
FICO
Community Manager
5 years ago

mpvar variables and identifiers

Hi,

Is it possible to sum a mpvar and an integer variable into an index of another mpvar ?

Example:

declarations
x: array(1..10,1..5) of mpvar
y: mpvar
end-declarations
 
y is_integer
y <= 2
 
forall(i in 1..10, j in 1..5 | exists(x(i,j+y)))do
x(i,j+y) <= 1
end-do
 

mosel raises the error E-151  Incompatible type for subscript num of `identifier'.

5 Replies

  • FICO's avatar
    FICO
    Community Manager

    It is indeed not possible to use a decision variable as index value for another variable - however, it is probably possible to reformulate your constraints, for example using indicator constraints or logic constraints. Could you perhaps provide a textual description of what exactly is the relation that you wish to state?

  • FICO's avatar
    FICO
    Community Manager

    Thank you.

    I'll try to provide more detailed info.

    For instance, consider 2 decision variables. Start(i,j) is 1 if task i starts at j and Finish(i,j) is 1 if task i finish the job at j.

    If the time between start and finish is known, I can perform the following constraint:

    declarations
    Start: array(1..nTask, 1..nTime) of mpvar
    Finish: array(1..nTask, 1..nTime) of mpvar
    time: array(1..nTask) of integer
    end-declarations
     
    forall(i in 1..nTask, j in 1..nTime)Start(i,j) = Finish(i,j+time(i))

    But now, if several options of time are available, for instance between 1 and 4, I want also to optimize the best choices of it.

  • FICO's avatar
    FICO
    Community Manager

    I would suggest to work with additional variables representing the actual values per task that are selected via the 'Start' (-> 'ifstart') and 'Finish' (-> 'iffinish') variables - assuming that one of these is meant to be non-zero per task, being defined as binaries or SOS-1:

        declarations
          ifstart: array(1..nTask, 1..nTime) of mpvar   ! Start time selectors ('Start')
          iffinish: array(1..nTask, 1..nTime) of mpvar  ! Completion time selectors ('Finish')
          tstart: array(1..nTask) of mpvar              ! Start time value per (aggregation of 'ifstart' per task)
          tfinish: array(1..nTask) of mpvar             ! Completion time (aggregation of 'iffinish' per task)
          wait: array(1..nTask) of mpvar                ! Variable time in between start and finish
        end-declarations
     
        forall(i in 1..nTask) do
          ! ... define ifstart and iffinish as binary or as one SOS-1 per task ...
          sum(j in 1..nTime) ifstart(i,j) = 1     
          sum(j in 1..nTime) j*ifstart(i,j) = tstart(i)
          sum(j in 1..nTime) iffinish(i,j) = 1
          sum(j in 1..nTime) j*iffinish(i,j) = tfinish(i)
          tstart(i) = tfinish(i)+wait(i)          ! The actual relation to be stated
        end-do
       

    Note that I have changed the name of the array from 'time' to 'wait' in order to avoid any clashes with the type 'time' that is defined by the Mosel module 'mmsystem'.

  • FICO's avatar
    FICO
    Community Manager

    Hello Susanne,

    Sorry for my delayed answer and thanks for your help 

    How can I relate a binary variable x : array(1..nTask, 1..nTime) of mpvar to be 1 when j>= tstart(i) and j<= tfinish(i) ?

    forall(i in nTask, j in nTime| j>= tstart(i) and j <= tfinish(i))x(i,j) == 1
    forall(i in nTask)sum(j in 1..nTime)x(i,j) = wait(i)

    Thanks in advance!

  • FICO's avatar
    FICO
    Community Manager

    Binary variables that indicate whether a task 'i' is in process at time 'j' could be connected up as follows using the 'ifstart' and 'iffinish' variables (NB: I am using 'duration' for the task processing duration which, I assume, is a more suitable name in place of the 'wait' from my previous code example). I am also correcting the relation linking start, duration, and finish times per task from my previous example:

        declarations
          x: array(1..nTask, 1..nTime) of mpvar   ! Processing indicators 
          duration: array(1..nTask) of mpvar      ! Task processing duration 
        end-declarations
     
        forall(i in 1..nTask,j in 1..nTime) do
          x(i,j) is_binary
          sum(k in 1..j) ifstart(i,k) >= x(i,j)     
          sum(k in 1..j) (ifstart(i,k)-iffinish(i,k)) <= x(i,j)
        end-do
     
        forall(i in 1..nTask) do
          sum(j in 1..nTime) x(i,j) = duration(i)
          tstart(i)+duration(i) = tfinish(i)
        end-do