So my music school runs a festival for all student bands to play together. Since there are some family members across diferent bands, I’m trying to create a solution to optimize the schedule of the bands – trying to minimize sum of time between bands that have relatives. Now I think I’ve found a solution. Don’t know if it’s the best but it looks like it’s working. Now I’m trying to find a better way to present the solution.
Relevant infos:
English is not my first language;
I’m not a programmer, and everything I did at the code bellow was what I was able to learn about python last 2 days.
Right now the program is outputing a list of the bands ids and the slot they will perform.
There are 2 new improvements I would love to understand how to do:
-
At some point instead of defining the number of bands (n), get this from the user as a list of bands and make some count to define (n) — (you will understand why in the second point);
-
Instead of outputing the bands ids, output the bands names (from the list the user inputed from point 1)
This would make it a lot more interesting and user friendly for me.
There is another improvment that I will leave to another moment ‘couse for now I don’t think I’m capable of understading (witch is transform the objetive function into something we get from user input too instead of me doing it manually, but I don’t know where to even start)
Laszlo Hunyadi helped me a lot to get to the code bellow.
This is the code I’m using now:
from gekko import GEKKO
import numpy as np
m = GEKKO()
#variables and constrains
n = 10 #n of bands
s = 10 #n of slots to play
t = 25 #time in minutes one band spend on the stage
x = m.Array(m.Var,(n,s),value=0,lb=0,ub=1,integer=True) #matrix of all bands(rows) x slots (columns)
for j in range(s):
m.Equation(m.sum([x[i,j] for i in range(n)])<=1) #since this is the decision I made it binary and sum<=1 to 1 slot can only be ocupied by one band
for i in range(n):
m.Equation(m.sum([x[i,j] for j in range(s)])==1) #since this is the decision I made it binary and sum=1 to 1 band only ocuppie one slot
z = [k for k in range(1,s+1)] #array with slot index to use to calc time
w = z*x*t #time the band will perform ;; used in objetive function
#objective
#in this exemple the band (1,4) and the band (1,5) have a relationship, and so do (3,2) and (1,9), so the objetive function bellow will try to minimize the sum of the time between bands that have relationship
y = m.abs2(w.item(1, 4)-w.item(1, 5))+ m.abs2(w.item(3, 2)-w.item(1, 9))
m.Minimize(y)
#solver
m.options.SOLVER = 1
m.solve()
#prints the schedule
schedule = [(i+1, j+1) for i in range(n) for j in range(s) if x[i,j][0] == 1]
schedule.sort(key=lambda x: x[1])
for band, slot in schedule:
print(f"Band {band} is scheduled to play in slot {slot}")
Lucas Catharino is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.