Machine shop scheduling problem, how to introduce a binaray variable that shows if you have production?
Dear all,
I'm quite new to Aimms, therefore I don’t know if my problem is easy to solve or a difficult one. My end goal is to be able to generate an automated production planning for a big pizza bakery. The machine shop scheduling example is in the direction for what I’m looking for, see the link below.
The machine shop scheduling example determines the optimal machine and start time for each order, so that the makespan is minimized.
I want to expand this model, so that more contraints can be added. An important binary variable for me is ‘DoYouHaveProductionInAPeriod(i,o,i_hc)’: do you have production at a certain machine i, for a spefic order o, at a certain time period i_hc. An example of a constraint that I want to add and using the variable ‘DoYouHaveProductionInAPeriod(i,o,i_hc)’ is if I have 4 workers available, only 4 machines can run at the same time → for each i_hc, sum((i,o),DoYouHaveProductionInAPeriod(i,o,i_hc) <= 4.
But how do generate the variable ‘DoYouHaveProductionInAPeriod(i,o,i_hc)’?
In my mind it should be possible, because the binary variable StartProductionOnProductionLine(i,o,i_hc) indicates when production starts and the parameter ActivityLength(i,o) states the duration of an order o on a specific machine i.
I was thinking of adding a constraint, which only works at time i_hc when StartProductionOnProductionLine(i,o,i_hc) is 1: sum((i_hc1)| (i_hc1>= (StartProductionOnProductionLine(i,o,i_hc)*i_hc1) and i_hc1<= StartProductionOnProductionLine(i,o,i_hc)*(i_hc1+ActivityLength(i,o))), DoYouHaveProductionInAPeriod(i,o,i_hc))=ActivityLength(i,o)
But I got an error: There is no operation defined for operator "*" with arguments of data type numeric and data type element; the arguments themselves are "StartProductionOnProductionLine(i,o,i_hc) $ domStartProductionProductionLine(i,o,i_hc)" and "i_hc1".
Who can help me to define the binary variable ‘DoYouHaveProductionInAPeriod(i,o,i_hc)’? Is it possible or not?
Page 1 / 1
Hello Harm,
I see this is your first post, so let me first off welcome you to our community :)
Some pointers I can already see:
You cannot use your variable StartProductionOnProductionLine as a condition of the sum, as you are trying to do within your constraint. This would be very non-linear modelling and I believe this is a MIP model.
If you want to use i_hcl as you are doing so, please make sure to make to make the set a subset of integers. This way you will be able to directly place it in an expression.
Additionally, I would seek out a formulation that will “force” your DoYouHaveProductionInAPeriod to be one based on if there is production starting in this period or some previous period, but you still have production happening. Since I don't know the model, this is just a rough idea.
(the second StartProductionOnProductionLine is only if it takes 2 periods to produce the product, hence it will still be going at i_hcl).
I hope this helps you get started off.
Hi Luispinto,
Thank you for replying. I'm learning how to use Aimms, so maybe I ask stupid questions. 1. You cannot use variables in a condition of a sum. Thank you, I didn't know that. Indeed, this is a MILP problem. 2. i_hc, i_hc1, i_hc2 are an index for the hour calender of the machines. So if you want to use the index more versitale, make it an interger. Ok, thank you.
I learn a lot from examples, therefore I’m going to use them here.
For example, if you have only 1 machine and 2 orders and the result of the MILP for StartProductionOnProductionLine(o,i_hcl) is:
If I implement your solution (DoYouHaveProductionInAPeriod(o,i_hcl) >= StartProductionOnProductionLine(o, i_hcl) + StartProductionOnProductionLine(o, i_hcl-1) +...).
For order 1 it would be DoYouHaveProductionInAPeriod(1,i_hcl) >= StartProductionOnProductionLine(1, i_hcl) + StartProductionOnProductionLine(1, i_hcl-1) + StartProductionOnProductionLine(1, i_hcl-2)
For order 2 it would be DoYouHaveProductionInAPeriod(2,i_hcl) >= StartProductionOnProductionLine(2, i_hcl) + StartProductionOnProductionLine(2, i_hcl-1) + StartProductionOnProductionLine(2, i_hcl-2) + StartProductionOnProductionLine(2, i_hcl-3)
This looks like the result I want to see. Thank you very much!!!
Hi Luispinto,
This is what I used for the constraint:
sum((i_hc2)| (i_hc2>= (i_hc - ActivityLengthM1(i,o))) and (i_hc2>= begHourCal) and (i_hc2 <= i_hc), StartProductionOnProductionLine(i,o,i_hc2)) = DoYouHaveProductionInAPeriod(i,o,i_hc)
Some questions:
The hour calender starts at 2016-05-09 00. This is when order 7 starts. Why is the hour calender for the variable DoYouHaveProductionInAPeriod(i,o,i_hc) not showing hours 00, 01, 02 and 04.
Other question is about using the equal sign (=) and greater than (>=) in the constraint. The optimal solution had a difference. When using the equal sign the result was 126. When using the greater than the result was 116. So, the preference is to us >= sign. But the variable had no Upper Bound → Variable was not restricted and didn't show the correct result. So I added the UB, but then I got the 126 result again. So what to do?
I solved the first question → the condition in the constraint ensured that i_hc got out of bound (time period was not in the HourCalender). I created a new parameter, that compensates when i_hc gets out of bound, which has the name CompensateOutOfBoundHourCalender(i,o,i_hc). For example, when i_hc is the second time period, and the activity length is 5 → 2-5 = -3 (out of bound). CompensateOutOfBoundHourCalender in this case will be 3. Then you have 2+3-5 = 0, you remain in bounds.
If we use the = sign, you are defining that DoYouHaveProductionInAPeriod has to be exactly 0 or 1 depending on if the previous periods had something start.
If you use the >= sign, you defining that DoYouHaveProductionInAPeriod has to be 0 when the left hand side is 0, and can be either 1 or 0 if the left hand side is 1.
If you use the <= sign, you defining that DoYouHaveProductionInAPeriod has to be 1 when the left hand side is 1, and can be either 1 or 0 if the left hand side is 0.
Which one suits your representation.
Btw., I do believe that you defined DoYouHaveProductionInAPeriod as binary, correct?
DoYouHaveProductionInAPeriod as binary, correct? Yes, it is a binary variable. It needs to be ‘=’, because If you have production in a certain time period, I want it to show with 1. And if there is no production, I want to see 0. Which solution is better?
Solution 1 is using 1 constraint with the ‘=’, sum((i_hc2)| (i_hc2>= (i_hc + CompensateOutOfBoundHourCalender(i,o,i_hc) - ActivityLengthM1(i,o))) and (i_hc2 <= i_hc), StartProductionOnProductionLine(i,o,i_hc2)) = DoYouHaveProductionInAPeriod(i,o,i_hc)
Solutioon 2 is using two constraints with >= and <= sum((i_hc2)| (i_hc2>= (i_hc + CompensateOutOfBoundHourCalender(i,o,i_hc) - ActivityLengthM1(i,o))) and (i_hc2 <= i_hc), StartProductionOnProductionLine(i,o,i_hc2)) >= DoYouHaveProductionInAPeriod(i,o,i_hc)