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
No related branches found
No related tags found
No related merge requests found
No preview for this file type
......@@ -3,9 +3,8 @@ from gurobipy import GRB
import copy
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)
blackout_count = len(blackouts)
if blackout_count == 0:
......@@ -24,11 +23,11 @@ def Solve(images, blackouts):
br = blackouts # tuples (b^L_br, b^U_br) = [start, end)
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"\njs {image_count} = {js}")
print(f"\nts {whitebox_count} = {ts}")
print(f"br |{blackout_count}| = {br}")
print(f"\njs |{image_count}| = {js}")
print(f"\nts |{whitebox_count}| = {white_boxes}")
"""PARAMETERS"""
h = GRB.INFINITY # time horizon = infinite
......@@ -42,105 +41,201 @@ def Solve(images, blackouts):
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)
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_t = model.addVars(whitebox_count,lb=0,vtype=GRB.CONTINUOUS) # finish of all images in whitebox t
Ts_j = model.addVars(image_count,lb=0,vtype=GRB.CONTINUOUS) # start of image j
Ts_t = model.addVars(whitebox_count,lb=0,vtype=GRB.CONTINUOUS) # start of timeslot t, probably redundant
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 time of ALL images in whitebox t
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
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
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
YB_j_br = model.addVars(image_count, blackout_count,vtype=GRB.BINARY) # order j finishes before blackbox br
"""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
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]
for j in range(image_count)),
name="Eq(3)")
# (4)
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 jprime in range(image_count)),
name="Eq(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]
# for j in range(image_count)
# for jprime in range(image_count)),
# name="Eq(4)")
# (4 v2)
# model.addConstrs((Tf_j[j] <= Ts_j[jprime] + tfU_j * (1 - Y_j_jprime[j,jprime])
# for j in range(image_count)
# for jprime in range(image_count)),
# name="Eq(4 v2)")
# (4 v3)
# for j in range(image_count):
# for jprime in range(j+1,image_count):
# model.addConstr((Tf_j[j] <= Ts_j[jprime] + tfU_j * (1 - Y_j_jprime[j,jprime])),
# name="Eq(4 v2)")
# # (5 v3)
# for j in range(image_count):
# for jprime in range(j+1,image_count):
# model.addConstr((Tf_j[jprime] <= Ts_j[j] + tfU_j * (1 + Y_j_jprime[j,jprime])),
# name="Eq(5 v3)")
# (5)
# model.addConstrs((Tf_j[jprime] * Y_j_jprime[j,jprime] <= Ts_j[j] * Y_j_jprime[j,jprime]
# for j in range(image_count)
# for jprime in range(image_count)),
# name="Eq(5)")
"""
penalty:
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)
model.addConstrs((ms >= Tf_j[j]
for j in range(image_count)),
name="Eq(9)")
# (11)
model.addConstrs((Ts_t[t+1] >= Tf_t[t]
for t in range(whitebox_count - 1)),
name="Eq(11)")
# (13)
model.addConstrs((Tf_t[t] - Ts_t[t] == PV_t[t]
# model.addConstrs((ms >= Tf_j[j]
# for j in range(image_count)),
# name="Eq(9)")
# (9 V2)
model.addConstrs((ms >= (PV_t[t] + white_boxes[t][0]) * (1-Xfree_t[t])
for t in range(whitebox_count)),
name="Eq(9 V2)")
# # (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)),
name="Eq(13)")
# (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))
+ 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)),
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]
for t in range (whitebox_count)) == 1
for j in range (image_count)),
name="Eq(19)")
# (20)
# # (20)
model.addConstrs((PV_t[t] == gp.quicksum(js[j] * X_j_t[j,t]
for j in range(image_count))
for t in range(whitebox_count)),
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)
# 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 t in range (whitebox_count)
# for br_index in range(blackout_count)),
# name="Eq(32)")
# (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)),
# name="Eq(33)")
# (34)
model.addConstrs((br[br_index][1] * YA_j_br[j,br_index] <= Ts_j[j]
for br_index in range(blackout_count)
for j in range(image_count)),
name="Eq(34)")
# (35)
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 br_index in range(blackout_count)),
name="Eq(35)")
# (36)
model.addConstrs((br[br_index][1] * YA_j_br[j,br_index] <= Tf_j[j]
for br_index in range(blackout_count)
for j in range(image_count)),
name="Eq(36)")
# (37)
model.addConstrs((Tf_j[j] <= br[br_index][0] * YB_j_br[j, br_index]
for j in range(image_count)
for br_index in range(blackout_count)),
name="Eq(37)")
# model.addConstrs((br[br_index][1] * YA_j_br[j,br_index] <= Ts_j[j]
# for br_index in range(blackout_count)
# for j in range(image_count)),
# name="Eq(34)")
# # (35)
# 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 br_index in range(blackout_count)),
# name="Eq(35)")
# # (36)
# model.addConstrs((br[br_index][1] * YA_j_br[j,br_index] <= Tf_j[j]
# for br_index in range(blackout_count)
# for j in range(image_count)),
# name="Eq(36)")
# # (37)
# model.addConstrs((Tf_j[j] <= br[br_index][0] * YB_j_br[j, br_index]
# for j in range(image_count)
# for br_index in range(blackout_count)),
# name="Eq(37)")
# SOLVE AND PRINT THE RESULTS
model.optimize()
......@@ -150,36 +245,46 @@ def Solve(images, blackouts):
if model.status == GRB.OPTIMAL:
deletus = starts.pop()
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:
print(f"(im{j},wb{t}) = {X_j_t[j,t].X}")
print('\nTimes:')
for im in Ts_j:
ts = Ts_j[im].X
tf = Tf_j[im].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('\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:')
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:')
print('\nImage before/after blackbox:')
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"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:
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-
print(iis)
......@@ -194,7 +299,7 @@ def calculate_whiteboxes(blackouts):
if (len(blackouts) == 0): # no black boxes, so whitebox length is infinite
return [(0, GRB.INFINITY)]
current_blackout = blackouts.pop()
current_blackout = blackouts[0]
begin = 0
end = current_blackout[0]
wb.append((begin, end - begin))
......@@ -202,7 +307,7 @@ def calculate_whiteboxes(blackouts):
for i in range(1, len(blackouts) + 2):
begin = current_blackout[1]
if (i < length):
current_blackout = blackouts.pop()
current_blackout = blackouts[i]
end = current_blackout[0]
wb.append((begin, end - begin))
else:
......
2
10
15
10
1
25, 5
\ No newline at end of file
100, 25
\ No newline at end of file
15.0
1
1
\ No newline at end of file
50.0
\ 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