Forum Discussion

FICO's avatar
FICO
Community Manager
10 years ago

Container separation

Hi,

I have a problem that I cannot solve for about a week. I have defined a set of Containers =[1,2,3,4,5,6] where bins have to be loaded. Bins come from differen suppliers = [L1,L2,L3], are loaded into containers and shipped to production plant. Since bins are from different suppliers that are located in different countries, it is clear that bins from different suppliers cannot be loaded into the same container. Despite this fact, my model loads all of them into the same container. I was thinking that maybe it makes sense to introduce a binay variable that is 1 if container belongs to arc (i,j) (from supplier to plant) and is 0 otherwise and number of containers per arc available, put I am not sure how I can possibly programm that.

Could you please help me with that?

P.S. Number of bins as well as flow on each arc are known.

Thank you!

2 Replies

  • FICO's avatar
    FICO
    Community Manager

    Assuming you have got binary variables ifuse(i,j) that indicate whether an arc is used, you could associate variables for the container selection with these as follows:

    declarations

      Plants: range

      Suppliers = {"L1","L2","L3"}

      Containers = 1..6

      ifuse: dynamic array(Suppliers,Plants) of mpvar

      assign: dynamic array(Containers,Suppliers,Plants) of mpvar

    end-declarations

    !... create variables 'ifuse' ...

    forall(c in Containers, i in Suppliers,j in Plants | exists(ifuse(i,j))) do

       create(assign(c,i,j))

       assign(c,i,j) is_binary

    end-do

    ! Use container on at most one arc

    forall(c in Containers)

      sum(i in Suppliers,j in Plants | exists(assign(c,i,j))) assign(c,i,j)<=1

    ! If arc is used, assign at least one container to it

    forall(i in Suppliers,j in Plants | exists(ifuse(i,j)))

       ifuse(i,j) <= sum(c in Containers) assign(c,i,j)

    ! Only assign containers to arcs that are used

    forall(c in Containers, i in Suppliers,j in Plants | exists(assign(c,i,j)))

       assign(c,i,j) <= ifuse(i,j)

    You might want to try adding some additional constraints for breaking symmetry if all containers are equivalent, for example:

    forall(c in Containers | c>1) do

       ct:=1

       sum(ct as counter, i in Suppliers,j in Plants | exists(ifuse(i,j)))

        ct*(assign(c-1,i,j) - assign(c,i,j)) <= 0

    end-do

  • FICO's avatar
    FICO
    Community Manager

    Thank you very much! As usual, your suggestion was very helpful!