2016-02-11 18:43:32 +01:00
|
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
|
2016-02-11 19:18:29 +01:00
|
|
|
|
import math
|
2016-02-11 20:35:07 +01:00
|
|
|
|
import sys
|
2016-02-11 19:18:29 +01:00
|
|
|
|
|
2016-02-11 22:27:01 +01:00
|
|
|
|
def print(*a):
|
|
|
|
|
return
|
|
|
|
|
|
2016-02-11 18:43:32 +01:00
|
|
|
|
print("#hashcode2016")
|
2016-02-11 19:18:29 +01:00
|
|
|
|
|
|
|
|
|
X = 0 # Nb rows
|
|
|
|
|
Y = 0 # Nb columns
|
|
|
|
|
D = 0 # Nb drones
|
|
|
|
|
T = 0 # Deadline
|
|
|
|
|
M = 0 # Maximum load
|
|
|
|
|
P = 0 # Nb products
|
|
|
|
|
W = 0 # Nb warehouses
|
|
|
|
|
C = 0 # Nb customers
|
|
|
|
|
|
2016-02-11 21:00:42 +01:00
|
|
|
|
t = 0 # Turn
|
2016-02-11 23:35:05 +01:00
|
|
|
|
s = 0 # Score
|
2016-02-11 19:56:36 +01:00
|
|
|
|
|
2016-02-11 20:38:29 +01:00
|
|
|
|
Dp = [] # Positions of drones
|
2016-02-11 19:18:29 +01:00
|
|
|
|
# (x, y)
|
2016-02-11 20:38:29 +01:00
|
|
|
|
Di = [] # Items of drones
|
2016-02-11 19:18:29 +01:00
|
|
|
|
# {product number: qt}
|
2016-02-11 20:38:29 +01:00
|
|
|
|
Dd = [] # Turn avaibility of drone
|
2016-02-11 19:18:29 +01:00
|
|
|
|
# int
|
2016-02-11 20:38:29 +01:00
|
|
|
|
Da = [] # Avaibles drones
|
2016-02-11 21:00:42 +01:00
|
|
|
|
# bool
|
2016-02-11 19:18:29 +01:00
|
|
|
|
|
2016-02-11 20:38:29 +01:00
|
|
|
|
Pw = [] # Weight of products
|
2016-02-11 19:18:29 +01:00
|
|
|
|
# int
|
|
|
|
|
|
2016-02-11 20:38:29 +01:00
|
|
|
|
Wp = [] # Positions of warehouses
|
2016-02-11 19:18:29 +01:00
|
|
|
|
# (x, y)
|
2016-02-11 20:38:29 +01:00
|
|
|
|
Wi = [] # Items of warehouses
|
2016-02-11 19:18:29 +01:00
|
|
|
|
# {product number: qt}
|
|
|
|
|
|
2016-02-11 20:38:29 +01:00
|
|
|
|
Cp = [] # Positions of customers
|
2016-02-11 19:18:29 +01:00
|
|
|
|
# (x, y)
|
2016-02-11 20:38:29 +01:00
|
|
|
|
Ci = [] # Needs of customers
|
2016-02-11 19:18:29 +01:00
|
|
|
|
# {product number: qt}
|
|
|
|
|
|
2016-02-11 20:35:07 +01:00
|
|
|
|
# Reading raw data
|
|
|
|
|
f = open(sys.argv[1], 'r')
|
|
|
|
|
|
|
|
|
|
line = f.readline()
|
|
|
|
|
info = line.split(' ')
|
|
|
|
|
|
|
|
|
|
GRILLE = (int(info[0]), int(info[1]))
|
|
|
|
|
X, Y = GRILLE
|
|
|
|
|
D = int(info[2])
|
|
|
|
|
T = int(info[3])
|
|
|
|
|
M = int(info[4])
|
|
|
|
|
|
|
|
|
|
line = f.readline()
|
|
|
|
|
P = int(line)
|
|
|
|
|
|
|
|
|
|
line = f.readline()
|
|
|
|
|
info = line.split(' ')
|
|
|
|
|
for i in range(0, P):
|
|
|
|
|
Pw.append(int(info[i]))
|
|
|
|
|
|
|
|
|
|
line = f.readline()
|
|
|
|
|
W = int(line)
|
|
|
|
|
|
|
|
|
|
for i in range(0, W):
|
|
|
|
|
line = f.readline()
|
|
|
|
|
info = line.split(' ')
|
|
|
|
|
Wp.append((int(info[0]), int(info[1])))
|
|
|
|
|
line = f.readline()
|
|
|
|
|
info = line.split(' ')
|
|
|
|
|
productQ = {}
|
|
|
|
|
for j in range(0, len(info)):
|
|
|
|
|
productQ[j] = int(info[j])
|
|
|
|
|
Wi.append(productQ)
|
|
|
|
|
|
|
|
|
|
line = f.readline()
|
|
|
|
|
C = int(line)
|
|
|
|
|
|
|
|
|
|
for i in range(0, C):
|
|
|
|
|
line = f.readline()
|
|
|
|
|
info = line.split(' ')
|
|
|
|
|
Cp.append((int(info[0]), int(info[1])))
|
|
|
|
|
line = f.readline()
|
|
|
|
|
nbP = int(line)
|
|
|
|
|
line = f.readline()
|
|
|
|
|
info = line.split(' ')
|
|
|
|
|
orderQ = {}
|
|
|
|
|
for k in range(0, P):
|
|
|
|
|
orderQ[k] = 0
|
|
|
|
|
for j in range(0, nbP):
|
2016-02-11 21:24:25 +01:00
|
|
|
|
orderQ[int(info[j])] += -1
|
2016-02-11 20:35:07 +01:00
|
|
|
|
Ci.append(orderQ)
|
|
|
|
|
|
|
|
|
|
f.close()
|
|
|
|
|
|
|
|
|
|
# Constituting data
|
|
|
|
|
for d in range(D):
|
|
|
|
|
Dp.append(Wp[0])
|
|
|
|
|
Di.append(dict((p, 0) for p in range(P)))
|
|
|
|
|
Dd.append(0)
|
2016-02-11 21:00:42 +01:00
|
|
|
|
Da.append(True)
|
2016-02-11 20:35:07 +01:00
|
|
|
|
|
2016-02-11 20:48:54 +01:00
|
|
|
|
Out = [] # Drones commands
|
|
|
|
|
|
2016-02-11 20:10:18 +01:00
|
|
|
|
# Debug
|
|
|
|
|
|
2016-02-11 21:00:42 +01:00
|
|
|
|
assert(len(Dp) == len(Di) == len(Dd) == len(Da) == D)
|
2016-02-11 20:10:18 +01:00
|
|
|
|
assert(len(Pw) == P)
|
|
|
|
|
assert(len(Wp) == len(Wi) == W)
|
|
|
|
|
assert(len(Cp) == len(Ci) == C)
|
|
|
|
|
|
|
|
|
|
#def droneInfos(d):
|
|
|
|
|
# print("- Drone", d, "carries", ", ".join([p + ": " + q + "×" + Dw[p] for
|
|
|
|
|
|
|
|
|
|
def showGrid():
|
|
|
|
|
for y in range(Y):
|
|
|
|
|
for x in range(X):
|
|
|
|
|
if (x, y) in Wp:
|
|
|
|
|
print("W", end="")
|
|
|
|
|
if (x, y) in Cp:
|
|
|
|
|
print("C", end="")
|
|
|
|
|
else:
|
|
|
|
|
print("·", end="")
|
2016-02-11 20:35:07 +01:00
|
|
|
|
print()
|
2016-02-11 20:10:18 +01:00
|
|
|
|
|
2016-02-11 19:56:36 +01:00
|
|
|
|
# Utilities
|
2016-02-11 19:18:29 +01:00
|
|
|
|
def distance(A, B):
|
2016-02-11 21:24:25 +01:00
|
|
|
|
return math.ceil(math.sqrt(pow(B[0] - A[0], 2) + pow(B[1] - A[1], 2)))
|
2016-02-11 19:18:29 +01:00
|
|
|
|
|
2016-02-11 19:56:36 +01:00
|
|
|
|
def weight(d):
|
2016-02-11 21:24:25 +01:00
|
|
|
|
return sum(Di[d][p]*Pw[p]for p in range(P))
|
2016-02-11 19:56:36 +01:00
|
|
|
|
|
|
|
|
|
# Actions
|
|
|
|
|
def load(d, w, p, q):
|
|
|
|
|
# drone number, warehouse, product, qt
|
2016-02-11 21:00:42 +01:00
|
|
|
|
assert(Da[d])
|
2016-02-11 19:56:36 +01:00
|
|
|
|
if (Dp[d] != Wp[w]):
|
|
|
|
|
Dd[d] += distance(Dp[d], Wp[w])
|
2016-02-11 22:27:01 +01:00
|
|
|
|
Dp[d] = Wp[w]
|
2016-02-11 19:56:36 +01:00
|
|
|
|
Wi[w][p] += -q
|
|
|
|
|
Di[d][p] += +q
|
2016-02-11 21:24:25 +01:00
|
|
|
|
assert(Wi[w][p] >= 0)
|
2016-02-11 19:56:36 +01:00
|
|
|
|
assert(weight(d) <= M)
|
2016-02-11 20:38:29 +01:00
|
|
|
|
assert(Dd[d] <= T)
|
2016-02-11 19:56:36 +01:00
|
|
|
|
print("Drone", d, "loads", q, "of", p, "from warehouse", w, "→", Dd[d])
|
2016-02-11 20:59:22 +01:00
|
|
|
|
Out.append(str(d) + ' L ' + str(w) + ' ' + str(p) + ' ' + str(q))
|
2016-02-11 19:56:36 +01:00
|
|
|
|
|
|
|
|
|
def unload(d, w, p, q):
|
|
|
|
|
# drone number, warehouse, product, qt
|
2016-02-11 21:00:42 +01:00
|
|
|
|
assert(Da[d])
|
2016-02-11 19:56:36 +01:00
|
|
|
|
if (Dp[d] != Wp[w]):
|
|
|
|
|
Dd[d] += distance(Dp[d], Wp[w])
|
2016-02-11 22:27:01 +01:00
|
|
|
|
Dp[d] = Wp[w]
|
2016-02-11 19:56:36 +01:00
|
|
|
|
Wi[w][p] += +q
|
|
|
|
|
Di[d][p] += -q
|
2016-02-11 20:38:29 +01:00
|
|
|
|
assert(Dd[d] <= T)
|
2016-02-11 19:56:36 +01:00
|
|
|
|
print("Drone", d, "unloads", q, "of", p, "from warehouse", w, "→", Dd[d])
|
2016-02-11 20:58:52 +01:00
|
|
|
|
Out.append(str(d) + ' U ' + str(w) + ' ' + str(p) + ' ' + str(q))
|
2016-02-11 19:56:36 +01:00
|
|
|
|
|
|
|
|
|
def deliver(d, c, p, q):
|
|
|
|
|
# drone number, customer, product, qt
|
2016-02-11 21:00:42 +01:00
|
|
|
|
assert(Da[d])
|
2016-02-11 19:56:36 +01:00
|
|
|
|
if (Dp[d] != Cp[c]):
|
|
|
|
|
Dd[d] += distance(Dp[d], Cp[c])
|
2016-02-11 22:27:01 +01:00
|
|
|
|
Dp[d] = Cp[c]
|
2016-02-11 21:24:25 +01:00
|
|
|
|
Ci[c][p] += +q
|
2016-02-11 19:56:36 +01:00
|
|
|
|
Di[d][p] += -q
|
|
|
|
|
Dd[d] += 1
|
2016-02-11 20:38:29 +01:00
|
|
|
|
assert(Dd[d] <= T)
|
2016-02-11 21:24:25 +01:00
|
|
|
|
print("Drone", d, "delivers", q, "of", p, "to client", c, "→", Dd[d])
|
2016-02-11 20:58:52 +01:00
|
|
|
|
Out.append(str(d) + ' D ' + str(c) + ' ' + str(p) + ' ' + str(q))
|
2016-02-11 23:35:05 +01:00
|
|
|
|
# Score
|
|
|
|
|
if Ci[c][p] == 0:
|
|
|
|
|
global s
|
|
|
|
|
s += math.ceil((T-t)/T*100)
|
|
|
|
|
|
2016-02-11 19:56:36 +01:00
|
|
|
|
|
|
|
|
|
def wait(d, w=1):
|
2016-02-11 21:00:42 +01:00
|
|
|
|
global Dd, Da
|
2016-02-11 22:27:01 +01:00
|
|
|
|
assert(Da[d])
|
2016-02-11 19:56:36 +01:00
|
|
|
|
Dd[d] += w
|
2016-02-11 21:00:42 +01:00
|
|
|
|
Da[d] = False
|
2016-02-11 19:56:36 +01:00
|
|
|
|
print("Drone", d, "waits", w, "turn" + ('s' if w >= 2 else ''), "→", Dd[d])
|
2016-02-11 20:48:54 +01:00
|
|
|
|
Out.append(str(d) + ' W ' + str(w))
|
|
|
|
|
|
2016-02-11 19:56:36 +01:00
|
|
|
|
|
|
|
|
|
# Control
|
|
|
|
|
def newTurn():
|
2016-02-11 20:48:54 +01:00
|
|
|
|
global t
|
2016-02-11 21:00:42 +01:00
|
|
|
|
# Finishing turn
|
|
|
|
|
for d in [d for d in range(len(Da)) if Da[d]]:
|
|
|
|
|
print(d)
|
|
|
|
|
wait(d)
|
|
|
|
|
assert(sum(Da) == 0)
|
|
|
|
|
# New turn
|
2016-02-11 19:56:36 +01:00
|
|
|
|
t += 1
|
|
|
|
|
print("--- Turn", t)
|
|
|
|
|
for d in range(D):
|
|
|
|
|
if Dd[d] <= t:
|
2016-02-11 21:00:42 +01:00
|
|
|
|
Da[d] = True
|
|
|
|
|
print("Drones", ", ".join([str(d) for d in range(len(Da)) if Da[d]]), "(", len(Da), ")", "are avaible")
|
2016-02-11 19:56:36 +01:00
|
|
|
|
|
|
|
|
|
def end():
|
|
|
|
|
print("--- End!")
|
2016-02-11 19:18:29 +01:00
|
|
|
|
|
2016-02-11 19:56:36 +01:00
|
|
|
|
# IA
|
2016-02-11 21:45:48 +01:00
|
|
|
|
Dt = [[] for d in range(D)] # Drone tasks
|
2016-02-11 21:44:56 +01:00
|
|
|
|
# (client, product)
|
|
|
|
|
|
2016-02-11 21:40:06 +01:00
|
|
|
|
def nearestW(p, pos):
|
|
|
|
|
minDist = math.inf
|
|
|
|
|
selW = None
|
|
|
|
|
for w in range(W):
|
|
|
|
|
if Wi[w][p] > 0:
|
|
|
|
|
dist = distance(Wp[w], pos)
|
|
|
|
|
if dist < minDist:
|
|
|
|
|
minDist = dist
|
|
|
|
|
selW = w
|
|
|
|
|
return selW
|
|
|
|
|
|
2016-02-11 21:44:56 +01:00
|
|
|
|
def listItems(d):
|
|
|
|
|
items = []
|
|
|
|
|
for p in range(P):
|
|
|
|
|
for cp in range(abs(Di[d][p])):
|
|
|
|
|
items.append(p)
|
|
|
|
|
return items
|
2016-02-11 21:40:06 +01:00
|
|
|
|
|
2016-02-11 22:27:01 +01:00
|
|
|
|
N = [] # Needs
|
|
|
|
|
# client, product
|
|
|
|
|
for c in range(C):
|
|
|
|
|
for p in range(P):
|
|
|
|
|
for cp in range(abs(Ci[c][p])):
|
|
|
|
|
N.append((c, p))
|
|
|
|
|
|
|
|
|
|
try:
|
2016-02-11 23:35:05 +01:00
|
|
|
|
while t < T-100:
|
2016-02-11 22:27:01 +01:00
|
|
|
|
for d in [d for d in range(D) if Da[d]]:
|
|
|
|
|
for tk in Dt[d]:
|
|
|
|
|
c, p = tk
|
|
|
|
|
deliver(d, c, p, 1)
|
|
|
|
|
Dt[d].remove(tk)
|
|
|
|
|
if len([d for d in range(D) if Da[d]]) > 1:
|
|
|
|
|
for n in N:
|
|
|
|
|
c, p = n
|
|
|
|
|
w = nearestW(p, Cp[c])
|
|
|
|
|
if w != None:
|
|
|
|
|
minDist = math.inf;
|
|
|
|
|
selD = None
|
|
|
|
|
for d in [d for d in range(D) if Da[d] and len(listItems(d)) < 1]:
|
|
|
|
|
dist = distance(Dp[d], Wp[w])
|
|
|
|
|
if dist < minDist:
|
|
|
|
|
minDist = dist
|
|
|
|
|
print(d)
|
|
|
|
|
selD = d
|
|
|
|
|
print(244, selD)
|
|
|
|
|
if selD != None:
|
|
|
|
|
load(selD, w, p, 1)
|
|
|
|
|
N.remove(n)
|
|
|
|
|
Dt[selD].append((c, p))
|
|
|
|
|
else:
|
|
|
|
|
break
|
|
|
|
|
newTurn()
|
|
|
|
|
except KeyboardInterrupt:
|
|
|
|
|
pass
|
2016-02-11 20:35:35 +01:00
|
|
|
|
|
2016-02-11 20:38:29 +01:00
|
|
|
|
# Output
|
|
|
|
|
f = open(sys.argv[1] + 'o', 'w')
|
2016-02-11 21:00:42 +01:00
|
|
|
|
f.write(str(len(Out)) + '\n' + '\n'.join(Out) + '\n')
|
2016-02-11 20:38:29 +01:00
|
|
|
|
f.close()
|
2016-02-11 21:43:28 +01:00
|
|
|
|
|
|
|
|
|
def SortCustomer():
|
|
|
|
|
CpSort = []
|
|
|
|
|
for i in range(0, len(Cp)):
|
|
|
|
|
CpSort.append((i, Cp[i], distance(Wp[0], Cp[i])))
|
|
|
|
|
CpSort.sort(key=lambda tup: tup[2])
|
|
|
|
|
|
|
|
|
|
def WarehouseHasItems(w, items):
|
2016-02-11 22:27:01 +01:00
|
|
|
|
for i in range(0, len(items)):
|
2016-02-11 21:43:28 +01:00
|
|
|
|
if Wi[w][items[i][0]] < items[i][1]:
|
|
|
|
|
return False
|
2016-02-11 21:45:48 +01:00
|
|
|
|
return True
|
2016-02-11 23:35:05 +01:00
|
|
|
|
|
|
|
|
|
sys.stdout.write(str(s)+'\n')
|