Skip to content
Snippets Groups Projects
Commit 789f16e4 authored by Hamers,G.C.A. (Glenn)'s avatar Hamers,G.C.A. (Glenn)
Browse files

probably working ILP algorithm (thanks to Sander)

parent 19ebcccd
Branches master
No related tags found
No related merge requests found
No preview for this file type
...@@ -3,9 +3,8 @@ from gurobipy import GRB ...@@ -3,9 +3,8 @@ from gurobipy import GRB
import copy import copy
def Solve(images, blackouts): def Solve(images, blackouts):
# TODO: if there are no blackouts, no need for the LP, just take the sum of all lengths and put images in random order
# now the LP crashes if this is the case because there are no indices for the blackouts # if there are no blackouts, just send the images in a random order after eachother
image_count = len(images) image_count = len(images)
blackout_count = len(blackouts) blackout_count = len(blackouts)
if blackout_count == 0: if blackout_count == 0:
...@@ -24,11 +23,11 @@ def Solve(images, blackouts): ...@@ -24,11 +23,11 @@ def Solve(images, blackouts):
br = blackouts # tuples (b^L_br, b^U_br) = [start, end) br = blackouts # tuples (b^L_br, b^U_br) = [start, end)
js = images # real number p_j = image size js = images # real number p_j = image size
ts = calculate_whiteboxes(copy.deepcopy(blackouts)) # tuples (time_t, δ_t) = [start, end) white_boxes = calculate_whiteboxes(copy.deepcopy(blackouts)) # tuples (time_t, δ_t) = [start, duration)
print(f"br {blackout_count} = {br}") print(f"br |{blackout_count}| = {br}")
print(f"\njs {image_count} = {js}") print(f"\njs |{image_count}| = {js}")
print(f"\nts {whitebox_count} = {ts}") print(f"\nts |{whitebox_count}| = {white_boxes}")
"""PARAMETERS""" """PARAMETERS"""
h = GRB.INFINITY # time horizon = infinite h = GRB.INFINITY # time horizon = infinite
...@@ -42,105 +41,201 @@ def Solve(images, blackouts): ...@@ -42,105 +41,201 @@ def Solve(images, blackouts):
ms = model.addVar(lb=0,vtype=GRB.CONTINUOUS) # makespan, objective function minimization value, bounded with constraints ms = model.addVar(lb=0,vtype=GRB.CONTINUOUS) # makespan, objective function minimization value, bounded with constraints
# P_j_br = model.addVars(image_count, blackout_count,lb=0,vtype=GRB.CONTINUOUS) # preemption time, will be set to 0 in Eq (33) # P_j_br = model.addVars(image_count, blackout_count,lb=0,vtype=GRB.CONTINUOUS) # preemption time, will be set to 0 in Eq (33)
PV_t = model.addVars(whitebox_count,lb=0,vtype=GRB.CONTINUOUS) # sum of length of images in whitebox t PV_t = model.addVars(whitebox_count,lb=0,vtype=GRB.CONTINUOUS) # sum of length of images in whitebox t
Tf_j = model.addVars(image_count,lb=0,vtype=GRB.CONTINUOUS) # finish of image j Tf_j = model.addVars(image_count,lb=0,vtype=GRB.CONTINUOUS) # finish time of image j
Tf_t = model.addVars(whitebox_count,lb=0,vtype=GRB.CONTINUOUS) # finish of all images in whitebox t Tf_t = model.addVars(whitebox_count,lb=0,vtype=GRB.CONTINUOUS) # finish time of ALL images in whitebox t
Ts_j = model.addVars(image_count,lb=0,vtype=GRB.CONTINUOUS) # start of image j Ts_j = model.addVars(image_count,lb=0,vtype=GRB.CONTINUOUS) # start of processing of image j
Ts_t = model.addVars(whitebox_count,lb=0,vtype=GRB.CONTINUOUS) # start of timeslot t, probably redundant # Ts_t = model.addVars(whitebox_count,lb=0,vtype=GRB.CONTINUOUS) # start of timeslot t, probably redundant
X_j_t = model.addVars(image_count, whitebox_count,vtype=GRB.BINARY) # order j in whitebox t X_j_t = model.addVars(image_count, whitebox_count,vtype=GRB.BINARY) # order j in whitebox t
Xfree_t = model.addVars(whitebox_count,vtype=GRB.BINARY) # whitebox t has no images in it Xfree_t = model.addVars(whitebox_count,vtype=GRB.BINARY) # whitebox t has no images in it
Y_j_jprime = model.addVars(image_count, image_count,vtype=GRB.BINARY) # image j comes before image j' in the global order # Y_j_jprime = model.addVars(image_count, image_count,vtype=GRB.BINARY) # image j comes before image j' in the global order
YA_j_br = model.addVars(image_count, blackout_count,vtype=GRB.BINARY) # order j starts after blackbox br YA_j_br = model.addVars(image_count, blackout_count,vtype=GRB.BINARY) # order j starts after blackbox br
YB_j_br = model.addVars(image_count, blackout_count,vtype=GRB.BINARY) # order j finishes before blackbox br YB_j_br = model.addVars(image_count, blackout_count,vtype=GRB.BINARY) # order j finishes before blackbox br
"""CONSTRAINTS""" """CONSTRAINTS"""
# model.addConstr(Y_j_jprime[0,0] == 0)
# model.addConstr(Y_j_jprime[0,1] == 0)
# model.addConstr(Y_j_jprime[1,0] == 1)
# model.addConstr(Y_j_jprime[1,1] == 0)
# (1) minimize makespan # (1) minimize makespan
model.setObjective(ms, GRB.MINIMIZE) model.setObjective(ms, GRB.MINIMIZE)
# (3) # (3) make sure the starttime and endtime are exactly picture size apart
model.addConstrs((Tf_j[j] - Ts_j[j] == js[j] model.addConstrs((Tf_j[j] - Ts_j[j] == js[j]
for j in range(image_count)), for j in range(image_count)),
name="Eq(3)") name="Eq(3)")
# (4) # (4) let the finishtime of a picture scheduled before another be lower or equal to the starting time of the later picture
model.addConstrs((Tf_j[j] * Y_j_jprime[j,jprime] <= Ts_j[jprime] * Y_j_jprime[j,jprime] # model.addConstrs((Tf_j[j] * Y_j_jprime[j,jprime] <= Ts_j[jprime] * Y_j_jprime[j,jprime]
for j in range(image_count) # for j in range(image_count)
for jprime in range(image_count)), # for jprime in range(image_count)),
name="Eq(4)") # name="Eq(4)")
# (4 v2) # (4 v2)
# model.addConstrs((Tf_j[j] <= Ts_j[jprime] + tfU_j * (1 - Y_j_jprime[j,jprime]) # model.addConstrs((Tf_j[j] <= Ts_j[jprime] + tfU_j * (1 - Y_j_jprime[j,jprime])
# for j in range(image_count) # for j in range(image_count)
# for jprime in range(image_count)), # for jprime in range(image_count)),
# name="Eq(4 v2)") # name="Eq(4 v2)")
# (4 v3) # (5)
# for j in range(image_count): # model.addConstrs((Tf_j[jprime] * Y_j_jprime[j,jprime] <= Ts_j[j] * Y_j_jprime[j,jprime]
# for jprime in range(j+1,image_count): # for j in range(image_count)
# model.addConstr((Tf_j[j] <= Ts_j[jprime] + tfU_j * (1 - Y_j_jprime[j,jprime])), # for jprime in range(image_count)),
# name="Eq(4 v2)") # name="Eq(5)")
# # (5 v3)
# for j in range(image_count): """
# for jprime in range(j+1,image_count): penalty:
# model.addConstr((Tf_j[jprime] <= Ts_j[j] + tfU_j * (1 + Y_j_jprime[j,jprime])),
# name="Eq(5 v3)") For all images:
eindtijd <- {begintijd whitbox} + {size of all images in whitebox}
"""
"""
penalty:
For all images:
eindtijd Tf_j <- {PV_T van whitebox waar die in zit}
"""
# (9) # (9)
model.addConstrs((ms >= Tf_j[j] # model.addConstrs((ms >= Tf_j[j]
for j in range(image_count)), # for j in range(image_count)),
name="Eq(9)") # name="Eq(9)")
# (11)
model.addConstrs((Ts_t[t+1] >= Tf_t[t] # (9 V2)
for t in range(whitebox_count - 1)), model.addConstrs((ms >= (PV_t[t] + white_boxes[t][0]) * (1-Xfree_t[t])
name="Eq(11)") for t in range(whitebox_count)),
# (13) name="Eq(9 V2)")
model.addConstrs((Tf_t[t] - Ts_t[t] == PV_t[t]
# # (11)
# model.addConstrs((white_boxes[t+1][0] >= Tf_t[t]
# for t in range(whitebox_count - 1)),
# name="Eq(11)")
# (13) set the PV_T
# model.addConstrs((Tf_t[t] - white_boxes[t][0] >= PV_t[t]
# for t in range(whitebox_count)),
# name="Eq(13)")
# (13) set the PV_T
model.addConstrs((white_boxes[t][1] >= PV_t[t]
for t in range(whitebox_count)), for t in range(whitebox_count)),
name="Eq(13)") name="Eq(13)")
# (17) # (17)
# model.addConstrs((gp.quicksum(X_j_t[j,t] for j in range(image_count))
# + Xfree_t[t]
# == 1
# for t in range(whitebox_count)),
# name="Eq(17)")
# model.addConstrs((bool(gp.quicksum(X_j_t[j,t] for j in range(image_count)))
# + Xfree_t[t]
# == 1
# for t in range(whitebox_count)),
# name="Eq(17)")
# (17 v2) SET Xfree_t
model.addConstrs((gp.quicksum(X_j_t[j,t] for j in range(image_count)) model.addConstrs((gp.quicksum(X_j_t[j,t] for j in range(image_count))
+ Xfree_t[t] + Xfree_t[t]
== 1 >= 1 # don't limit 1 image per whitebox t
for t in range(whitebox_count)),
name="Eq(17)")
# Xfree_t <= 1 to make it binary
model.addConstrs((Xfree_t[t] <= 1
for t in range(whitebox_count)),
name="Eq(17)")
# Set Xfree to 0 if whitebox is not empty
model.addConstrs((gp.quicksum(X_j_t[j,t] for j in range(image_count))
* Xfree_t[t]
== 0
for t in range(whitebox_count)), for t in range(whitebox_count)),
name="Eq(17)") name="Eq(17)")
# (19)
"""
Als som > 0 is
>>> iets * 0 = 0 <<<
0 == som * Xfree_t
0 == 123 * X --> X = 1
0 == 0 * X --> X kan van alles worden
X <= 1
Xfree_t -> 0
"""
"""
for whiteboxes:
Sommeer dit:
PV_T + starttijd whitebox
"""
"""
V Xfree_t -> 1 als whitebox leeg is
X Xfree_t -> 0 als whitebox niet leeg is ==> som over j van X_j_t >= 1 voor alle T
1. test_t <= 1
2. test_t >= som over j van X_j_t
3. Xfree_t == 1 - test_t
(som + 1) * Xfree_t === som * Xfree_t
* (1 - Xfree_t)
gp.quicksum(X_j_t[j,t]) -> aantal images in whitebox
"""
# model.addConstrs((gp.quicksum(X_j_t[j,t] for j in range(image_count))
# + Xfree_t[t]
# <= 1
# for t in range(whitebox_count)),
# name="Eq(17)")
# (19) makes sure each image is send once
model.addConstrs((gp.quicksum(X_j_t[j,t] model.addConstrs((gp.quicksum(X_j_t[j,t]
for t in range (whitebox_count)) == 1 for t in range (whitebox_count)) == 1
for j in range (image_count)), for j in range (image_count)),
name="Eq(19)") name="Eq(19)")
# (20) # # (20)
model.addConstrs((PV_t[t] == gp.quicksum(js[j] * X_j_t[j,t] model.addConstrs((PV_t[t] == gp.quicksum(js[j] * X_j_t[j,t]
for j in range(image_count)) for j in range(image_count))
for t in range(whitebox_count)), for t in range(whitebox_count)),
name="Eq(20)") name="Eq(20)")
# # (20.2)
model.addConstrs((PV_t[t] <= white_boxes[t][1]
for t in range(whitebox_count)),
name="Eq(20.2)")
# (32) # (32)
# model.addConstrs((YB_j_br[j,br_index] + YA_j_br[j,br_index] == X_j_t[j,t] # model.addConstrs((YB_j_br[j,br_index] + YA_j_br[j,br_index] == X_j_t[j,t]
# for j in range(image_count) # for j in range(image_count)
# for t in range (whitebox_count) # for t in range (whitebox_count)
# for br_index in range(blackout_count)), # for br_index in range(blackout_count)),
# name="Eq(32)") # name="Eq(32)")
# (33) # (33)
# model.addConstrs((P_j_br[j,br_index] == 0 for j in range(image_count) # model.addConstrs((P_j_br[j,br_index] == 0 for j in range(image_count)
# for br_index in range(blackout_count)), # for br_index in range(blackout_count)),
# name="Eq(33)") # name="Eq(33)")
# (34) # (34)
model.addConstrs((br[br_index][1] * YA_j_br[j,br_index] <= Ts_j[j] # model.addConstrs((br[br_index][1] * YA_j_br[j,br_index] <= Ts_j[j]
for br_index in range(blackout_count) # for br_index in range(blackout_count)
for j in range(image_count)), # for j in range(image_count)),
name="Eq(34)") # name="Eq(34)")
# (35) # # (35)
model.addConstrs((Ts_j[j] <= br[br_index][0] * YB_j_br[j, br_index] + YA_j_br[j, br_index] * GRB.INFINITY # model.addConstrs((Ts_j[j] <= br[br_index][0] * YB_j_br[j, br_index] + YA_j_br[j, br_index] * GRB.INFINITY
for j in range(image_count) # for j in range(image_count)
for br_index in range(blackout_count)), # for br_index in range(blackout_count)),
name="Eq(35)") # name="Eq(35)")
# (36) # # (36)
model.addConstrs((br[br_index][1] * YA_j_br[j,br_index] <= Tf_j[j] # model.addConstrs((br[br_index][1] * YA_j_br[j,br_index] <= Tf_j[j]
for br_index in range(blackout_count) # for br_index in range(blackout_count)
for j in range(image_count)), # for j in range(image_count)),
name="Eq(36)") # name="Eq(36)")
# (37) # # (37)
model.addConstrs((Tf_j[j] <= br[br_index][0] * YB_j_br[j, br_index] # model.addConstrs((Tf_j[j] <= br[br_index][0] * YB_j_br[j, br_index]
for j in range(image_count) # for j in range(image_count)
for br_index in range(blackout_count)), # for br_index in range(blackout_count)),
name="Eq(37)") # name="Eq(37)")
# SOLVE AND PRINT THE RESULTS # SOLVE AND PRINT THE RESULTS
model.optimize() model.optimize()
...@@ -150,36 +245,46 @@ def Solve(images, blackouts): ...@@ -150,36 +245,46 @@ def Solve(images, blackouts):
if model.status == GRB.OPTIMAL: if model.status == GRB.OPTIMAL:
deletus = starts.pop() deletus = starts.pop()
time = model.ObjVal time = model.ObjVal
print('\nFinish time: %g' % time)
# print('\nWhitebox times:')
# for t in range(whitebox_count):
# wbtimestart = white_boxes[t][0]
# wbtimefinish = Tf_t[t].X
# print(f"Wb {t} starts t={wbtimestart} finishes t={wbtimefinish}")
# starts.append(t)
print("White box decision variables:") print("\nWhite box decision variables:")
for (j,t) in X_j_t: for (j,t) in X_j_t:
print(f"(im{j},wb{t}) = {X_j_t[j,t].X}") print(f"(im{j},wb{t}) = {X_j_t[j,t].X}")
print('\nTimes:') # print('\nOrder:')
for im in Ts_j: # for im in Ts_j:
ts = Ts_j[im].X # for im2 in Ts_j:
tf = Tf_j[im].X # print(f"{im} before {im2}: {Y_j_jprime[im, im2].X}")
print(f"Image {im} starts t={ts} finishes t={tf}")
starts.append(t)
print('\nOrder:')
for im in Ts_j:
for im2 in Ts_j:
print(f"{im} before {im2}: {Y_j_jprime[im, im2].X}")
print('\nWhitebox contains:') print('\nImage before/after blackbox:')
for t in PV_t:
print(f"wb{t} is {Xfree_t[t].X} empty and holds length {PV_t[t].X} of images")
print('\nBlackboxes before/after:')
for (j,br_index) in YA_j_br: for (j,br_index) in YA_j_br:
print(f"YA_{j}_{br_index}: image {j} after blackbox {br_index} = {YA_j_br[j,br_index].X}") print(f"YA_{j}_{br_index}: image {j} after blackbox {br_index} = {YA_j_br[j,br_index].X}")
print(f"YB_{j}_{br_index}: image {j} before blackbox {br_index} = {YB_j_br[j,br_index].X}") print(f"YB_{j}_{br_index}: image {j} before blackbox {br_index} = {YB_j_br[j,br_index].X}")
print(f"(34) {br[br_index][1]} * {YA_j_br[j,br_index].X} <= {Ts_j[j].X}")
print(f"(35) {Ts_j[j].X} <= {br[br_index][0]} * {YB_j_br[j, br_index].X} + {YA_j_br[j, br_index].X} * infinity")
print(f"(36) {br[br_index][1]} * {YA_j_br[j,br_index].X} <= {Tf_j[j].X}")
print(f"(37) {Tf_j[j].X} <= {br[br_index][0]} * {YB_j_br[j, br_index].X}\n")
print('\nFinish time: %g' % time)
print('Whitebox contains:')
for t in PV_t:
print(f"wb{t} is {Xfree_t[t].X} empty and holds length {PV_t[t].X} of images")
# print('\nImage times:')
# for im in Ts_j:
# jtimestart = Ts_j[im].X
# jtimefinish = Tf_j[im].X
# print(f"Image {im} starts t={jtimestart} finishes t={jtimefinish}")
# starts.append(t)
else: else:
print('\nNo solution, reason:') print('\nNo solution, Check input or constraints! Reason:')
iis = model.computeIIS() # Irreducible Infeasible Subsystem, https://support.gurobi.com/hc/en-us/articles/360029969391-How-do-I-determine-why-my-model-is-infeasible- iis = model.computeIIS() # Irreducible Infeasible Subsystem, https://support.gurobi.com/hc/en-us/articles/360029969391-How-do-I-determine-why-my-model-is-infeasible-
print(iis) print(iis)
...@@ -194,7 +299,7 @@ def calculate_whiteboxes(blackouts): ...@@ -194,7 +299,7 @@ def calculate_whiteboxes(blackouts):
if (len(blackouts) == 0): # no black boxes, so whitebox length is infinite if (len(blackouts) == 0): # no black boxes, so whitebox length is infinite
return [(0, GRB.INFINITY)] return [(0, GRB.INFINITY)]
current_blackout = blackouts.pop() current_blackout = blackouts[0]
begin = 0 begin = 0
end = current_blackout[0] end = current_blackout[0]
wb.append((begin, end - begin)) wb.append((begin, end - begin))
...@@ -202,7 +307,7 @@ def calculate_whiteboxes(blackouts): ...@@ -202,7 +307,7 @@ def calculate_whiteboxes(blackouts):
for i in range(1, len(blackouts) + 2): for i in range(1, len(blackouts) + 2):
begin = current_blackout[1] begin = current_blackout[1]
if (i < length): if (i < length):
current_blackout = blackouts.pop() current_blackout = blackouts[i]
end = current_blackout[0] end = current_blackout[0]
wb.append((begin, end - begin)) wb.append((begin, end - begin))
else: else:
......
2 2
10
15 15
10
1 1
25, 5 100, 25
\ No newline at end of file \ No newline at end of file
15.0 50.0
1 \ No newline at end of file
1
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment