I made a loop that needs to stop once the list U has no values in it. Once it reaches that point, the loop doesnt stop and it gives an error, because there is a value by 0 (the len(U) in the last loop)
def ATC(instance,K):
pi=[]
U = [i for i in range(instance.jobs)]
t=0
p= sum(instance.pt) / len(U)
while len(U)!=0:
I=[]
for j in U:
I.append((instance.w[j]/instance.pt[j])*exp(-(max(instance.dd[j]-instance.pt[j]-t,0))/(K*p)))
k = np.argmax(I)
pi.append(U[k])
U.pop(k)
print(U,len(U))
t = instance.Cmax(pi)
p = sum([instance.pt[i] for i in U])/len(U) ################################
obj = instance.SumWjTj(pi)
return pi,obj
Here the print of the list U and len(U) during the loop, showing it reaches 0 but the while condition doesnt work:
[0, 1, 2, 3, 4, 5, 7, 8, 9] 9
[0, 1, 2, 4, 5, 7, 8, 9] 8
[0, 1, 4, 5, 7, 8, 9] 7
[0, 1, 4, 7, 8, 9] 6
[0, 1, 4, 7, 9] 5
[0, 1, 4, 7] 4
[1, 4, 7] 3
[4, 7] 2
[7] 1
[] 0
Using a If len(U)!=0: p = sum([instance.pt[i] for i in U])/len(U) works, but I don’t understand why the while isn’t enough
>Solution :
The loop doesn’t exit as soon as len(U) is zero and will go on to complete that current iteration of the loop. So, in your case, once U is empty it will still try do the lines:
t = instance.Cmax(pi)
p = sum([instance.pt[i] for i in U])/len(U) ################################
obj = instance.SumWjTj(pi)
before it re-tests for len(U)!=0 and exits. So, when calculating p it’ll try and divide by zero, which I assume is the error you are getting.
Instead you could put a break clause in your loop like:
while True:
I=[]
for j in U:
I.append((instance.w[j]/instance.pt[j])*exp(-(max(instance.dd[j]-instance.pt[j]-t,0))/(K*p)))
k = np.argmax(I)
pi.append(U[k])
U.pop(k)
print(U,len(U))
# break out the loop here
if len(U) == 0:
break
t = instance.Cmax(pi)
p = sum([instance.pt[i] for i in U])/len(U) ################################
obj = instance.SumWjTj(pi)