-1

I would like to add a constraint to my optimization problem that I am building using pulp. The constraint should count the number of "streaks" of non-zero numbers, i.e.,

[1,1,1,1,0] = 1 because there us 1 group of 1s
[1,1,1,0,1] = 2 because there are 2 group of 1s
[1,0,1,0,1] = 3 because there are 3 group of 1s

The constraint should limit the group # to 1 or 0 (if the array is all 0s)

As some context on my problem, it is a scheduling problem with 3 timeslots (columns). There are 2 people we are considering and 2 possible positions they could work (rows). my_array = something like

([x1,x2,x3], [x4, x5, x6], [x7, x9, x9], [x10, x11, x12])

Row 0 = person 1, working role A. Row 1= person 2 working role A. Row 3= person 1 working role B. Row 3 = person 2 working role B. If 1, the person works, if 0 the person does not work.

I would like for the sum of the hours that a person works across roles (e.g., for person 1, sum of role 0 and row 2), have only 1 consecutive streak of 1s, or 0. Not more than that.

I have added this constraint:

for p in range(num_people):
prob += len([ sum( 1 for _ in group ) for key, group in itertools.groupby(sum(my_array[p+x*num_people] for x in range(num_positions))) if key ]) == 1

However, the output of the optimization problem has rows where an individual is working non-consecutive rows. i.e.,

([1,0,0], [1, 1, 0], [0, 0, 1], [0, 0, 0])

Summing row 0 +row 2 and row 1 + row 3 we get

([1,0,1], [1, 1, 0])

Here, person 1 works timeslot 0 and timeslot 2, but not timeslot 1, which is what I would like to avoid. it appears that the constraint is not registering, although there are no errors. Are there any recommendations on other approaches to adding this constraint to my linear optimization problem?

  • Are you able to share a minimum complete and verifiable example - https://stackoverflow.com/help/mcve – kabdulla Jan 27 '19 at 22:21

1 Answers1

0

In machine scheduling this is sometimes called: restrict the number of start-ups. There are some interesting formulations for this.

In this special case we only have three time periods (this is explicitly stated in the question). So the only pattern we need to forbid is: [1,0,1]. Let x[t] be our binary variable. Then we can introduce the cut:

 x[0]-x[1]+x[2] <= 1

This will forbid [1,0,1] but will allow any other pattern.

A different approach is shown here.

Erwin Kalvelagen
  • 15,677
  • 2
  • 14
  • 39
  • that's helpful, thanks. The problem I presented above is simplified so this will not work (there are really 10 columns) but I will look into the method you suggested. – SA181818 Jan 29 '19 at 02:29
  • 1
    We can only work with what is in the question. If the actual problem is different, I would suggest not to invent a different problem in the question, – Erwin Kalvelagen Jan 29 '19 at 14:34