2016-02-12 16:44:38 +00:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
|
|
|
import sys
|
2016-02-13 11:54:59 +00:00
|
|
|
import math
|
|
|
|
import copy
|
2016-02-13 14:36:44 +00:00
|
|
|
import progressbar
|
|
|
|
|
2016-02-16 22:48:59 +00:00
|
|
|
DEBUG = False
|
2016-02-13 11:54:59 +00:00
|
|
|
|
|
|
|
outLines = []
|
|
|
|
|
|
|
|
def log(*data):
|
2016-02-13 14:36:44 +00:00
|
|
|
if DEBUG:
|
2016-02-13 11:54:59 +00:00
|
|
|
print(*data)
|
|
|
|
|
|
|
|
def output(*values):
|
|
|
|
global outLines
|
|
|
|
outLines.append(' '.join([str(val) for val in values]))
|
|
|
|
|
|
|
|
def distance(A, B):
|
|
|
|
return math.ceil(math.sqrt(pow(B[0] - A[0], 2) + pow(B[1] - A[1], 2)))
|
2016-02-12 16:44:38 +00:00
|
|
|
|
|
|
|
class Product:
|
|
|
|
|
|
|
|
ALL = []
|
|
|
|
|
|
|
|
def __init__(self, weight):
|
2016-02-13 11:54:59 +00:00
|
|
|
self.id = len(self.ALL)
|
2016-02-12 16:44:38 +00:00
|
|
|
self.ALL.append(self)
|
|
|
|
|
|
|
|
self.weight = weight
|
|
|
|
|
2016-02-13 15:43:54 +00:00
|
|
|
def totalWeight(items):
|
|
|
|
s = 0
|
|
|
|
for i in items:
|
|
|
|
s += Product.get(i).weight
|
|
|
|
return s
|
|
|
|
|
2016-02-12 16:44:38 +00:00
|
|
|
def get(pid):
|
|
|
|
return __class__.ALL[pid]
|
|
|
|
|
|
|
|
def len():
|
|
|
|
return len(__class__.ALL)
|
|
|
|
|
|
|
|
class Warehouse:
|
|
|
|
|
|
|
|
ALL = []
|
|
|
|
|
|
|
|
def __init__(self, pos, items):
|
2016-02-13 11:54:59 +00:00
|
|
|
self.id = len(self.ALL)
|
2016-02-12 16:44:38 +00:00
|
|
|
self.ALL.append(self)
|
|
|
|
|
|
|
|
self.pos = pos
|
|
|
|
self.items = items
|
|
|
|
|
2016-02-13 14:36:44 +00:00
|
|
|
self.plannedItems = self.items.copy()
|
2016-02-16 22:48:59 +00:00
|
|
|
self.clients = []
|
2016-02-13 14:36:44 +00:00
|
|
|
|
|
|
|
def plan(self, items):
|
|
|
|
for i in items:
|
|
|
|
self.plannedItems.remove(i)
|
2016-02-13 12:44:11 +00:00
|
|
|
|
2016-02-16 22:48:59 +00:00
|
|
|
def planRefill(self, items):
|
|
|
|
for i in items:
|
|
|
|
self.plannedNeeds.remove(i)
|
|
|
|
|
|
|
|
def planUnload(self, items):
|
|
|
|
for i in items:
|
|
|
|
self.plannedExtra.remove(i)
|
|
|
|
|
|
|
|
def pack(self, payload=-1, rests=[]):
|
|
|
|
if payload == -1:
|
|
|
|
payload = Drone.PAYLOAD
|
|
|
|
p = []
|
|
|
|
load = 0
|
|
|
|
rests = rests.copy()
|
|
|
|
needs = []
|
|
|
|
for need in self.plannedNeeds:
|
|
|
|
if need in rests:
|
|
|
|
needs.append(need)
|
|
|
|
rests.remove(need)
|
|
|
|
# # Sort occurences
|
|
|
|
# occ = [(i, self.plannedNeeds.count(i)) for i in self.plannedNeeds]
|
|
|
|
# occ.sort(key=lambda c: c[1])
|
|
|
|
# # TODO Optimise for same product wanted more than once
|
|
|
|
# Looks like it's not necessary for set 2, we'll see that later
|
|
|
|
# Sort needs by weight
|
|
|
|
couples = [(i, Product.get(i).weight) for i in needs]
|
|
|
|
couples.sort(key=lambda c: c[1])
|
|
|
|
for couple in couples:
|
|
|
|
need, weight = couple
|
|
|
|
if load + weight <= payload:
|
|
|
|
p.append(need)
|
|
|
|
load += weight
|
|
|
|
return p
|
|
|
|
|
2016-02-13 13:07:13 +00:00
|
|
|
# Set functions
|
2016-02-13 12:09:14 +00:00
|
|
|
def near(pos):
|
|
|
|
couples = []
|
|
|
|
for el in __class__.ALL:
|
|
|
|
couples.append([el, distance(el.pos, pos)])
|
|
|
|
return [couple[0] for couple in sorted(couples, key=lambda c: c[1])]
|
|
|
|
|
2016-02-12 16:44:38 +00:00
|
|
|
def get(pid):
|
|
|
|
return __class__.ALL[pid]
|
|
|
|
|
|
|
|
def len():
|
|
|
|
return len(__class__.ALL)
|
|
|
|
|
|
|
|
class Client:
|
|
|
|
|
|
|
|
ALL = []
|
2016-02-16 19:30:10 +00:00
|
|
|
UNSATISFIED = []
|
2016-02-12 16:44:38 +00:00
|
|
|
|
|
|
|
def __init__(self, pos, needs):
|
2016-02-13 11:54:59 +00:00
|
|
|
self.id = len(self.ALL)
|
2016-02-12 16:44:38 +00:00
|
|
|
self.ALL.append(self)
|
2016-02-16 19:30:10 +00:00
|
|
|
self.UNSATISFIED.append(self)
|
2016-02-12 16:44:38 +00:00
|
|
|
|
|
|
|
self.pos = pos
|
2016-02-13 11:54:59 +00:00
|
|
|
self.needs = needs
|
|
|
|
|
2016-02-13 14:36:44 +00:00
|
|
|
self.plannedNeeds = self.needs.copy()
|
2016-02-16 22:48:59 +00:00
|
|
|
self.warehouse = Warehouse.near(self.pos)[0]
|
|
|
|
self.warehouse.clients.append(self)
|
2016-02-13 14:36:44 +00:00
|
|
|
|
|
|
|
def plan(self, needs):
|
|
|
|
for n in needs:
|
|
|
|
self.plannedNeeds.remove(n)
|
2016-02-13 12:44:11 +00:00
|
|
|
|
2016-02-13 11:54:59 +00:00
|
|
|
def satisfied(self):
|
|
|
|
return len(self.needs) == 0
|
2016-02-12 16:44:38 +00:00
|
|
|
|
2016-02-13 19:12:03 +00:00
|
|
|
def pack(self, payload=-1, rests=[]):
|
2016-02-13 13:07:13 +00:00
|
|
|
if payload == -1:
|
|
|
|
payload = Drone.PAYLOAD
|
|
|
|
p = []
|
|
|
|
load = 0
|
2016-02-13 19:12:03 +00:00
|
|
|
rests = rests.copy()
|
|
|
|
needs = []
|
|
|
|
for need in self.plannedNeeds:
|
|
|
|
if need in rests:
|
|
|
|
needs.append(need)
|
|
|
|
rests.remove(need)
|
2016-02-13 15:43:54 +00:00
|
|
|
# # Sort occurences
|
|
|
|
# occ = [(i, self.plannedNeeds.count(i)) for i in self.plannedNeeds]
|
|
|
|
# occ.sort(key=lambda c: c[1])
|
|
|
|
# # TODO Optimise for same product wanted more than once
|
|
|
|
# Looks like it's not necessary for set 2, we'll see that later
|
2016-02-13 13:07:13 +00:00
|
|
|
# Sort needs by weight
|
2016-02-13 19:12:03 +00:00
|
|
|
couples = [(i, Product.get(i).weight) for i in needs]
|
2016-02-13 13:07:13 +00:00
|
|
|
couples.sort(key=lambda c: c[1])
|
|
|
|
for couple in couples:
|
|
|
|
need, weight = couple
|
|
|
|
if load + weight <= payload:
|
|
|
|
p.append(need)
|
|
|
|
load += weight
|
|
|
|
return p
|
|
|
|
|
|
|
|
# Set functions
|
2016-02-13 12:09:14 +00:00
|
|
|
def near(pos):
|
|
|
|
couples = []
|
2016-02-16 19:30:10 +00:00
|
|
|
for el in __class__.UNSATISFIED:
|
2016-02-13 12:09:14 +00:00
|
|
|
couples.append([el, distance(el.pos, pos)])
|
|
|
|
return [couple[0] for couple in sorted(couples, key=lambda c: c[1])]
|
|
|
|
|
2016-02-12 16:44:38 +00:00
|
|
|
def get(pid):
|
|
|
|
return __class__.ALL[pid]
|
|
|
|
|
|
|
|
def len():
|
|
|
|
return len(__class__.ALL)
|
|
|
|
|
|
|
|
class Drone:
|
|
|
|
|
|
|
|
ALL = []
|
|
|
|
PAYLOAD = 0
|
|
|
|
|
|
|
|
def __init__(self):
|
2016-02-13 11:54:59 +00:00
|
|
|
self.id = len(self.ALL)
|
2016-02-12 16:44:38 +00:00
|
|
|
self.ALL.append(self)
|
|
|
|
|
|
|
|
self.pos = Warehouse.get(0).pos
|
|
|
|
self.items = []
|
|
|
|
self.avail = 0
|
2016-02-13 12:44:11 +00:00
|
|
|
|
2016-02-12 16:44:38 +00:00
|
|
|
self.tasks = []
|
|
|
|
|
2016-02-13 12:44:11 +00:00
|
|
|
def addTask(self, *task):
|
|
|
|
self.tasks.append(task)
|
|
|
|
|
|
|
|
def executeTask(self):
|
|
|
|
if self.available():
|
|
|
|
if len(self.tasks):
|
|
|
|
task = self.tasks[0]
|
|
|
|
getattr(self, task[0])(*task[1:])
|
|
|
|
self.tasks = self.tasks[1:]
|
|
|
|
else:
|
|
|
|
self.wait()
|
|
|
|
|
2016-02-13 11:54:59 +00:00
|
|
|
def weight(self):
|
2016-02-13 15:43:54 +00:00
|
|
|
return Product.totalWeight(self.items)
|
2016-02-13 11:54:59 +00:00
|
|
|
|
|
|
|
def busyFor(self, time):
|
|
|
|
self.avail += time
|
|
|
|
assert(self.avail < T)
|
|
|
|
|
|
|
|
def available(self):
|
|
|
|
return self.avail <= turn
|
|
|
|
|
|
|
|
def load(self, warehouse, product, qt):
|
|
|
|
assert(self.available())
|
|
|
|
if (self.pos != warehouse.pos):
|
|
|
|
self.busyFor(distance(self.pos, warehouse.pos))
|
|
|
|
self.pos = warehouse.pos
|
|
|
|
for q in range(qt):
|
|
|
|
warehouse.items.remove(product.id)
|
|
|
|
self.items.append(product.id)
|
|
|
|
self.busyFor(1)
|
|
|
|
assert(self.weight() <= __class__.PAYLOAD)
|
|
|
|
log("Drone", self.id, "loads", qt, "of", product.id, "from warehouse", warehouse.id, "→", self.avail)
|
|
|
|
output(self.id, 'L', warehouse.id, product.id, qt)
|
|
|
|
|
|
|
|
def unload(self, warehouse, product, qt):
|
|
|
|
assert(self.available())
|
|
|
|
if (self.pos != warehouse.pos):
|
|
|
|
self.busyFor(distance(self.pos, warehouse.pos))
|
|
|
|
self.pos = warehouse.pos
|
|
|
|
for q in range(qt):
|
|
|
|
self.items.remove(product.id)
|
|
|
|
warehouse.items.append(product.id)
|
|
|
|
self.busyFor(1)
|
|
|
|
log("Drone", self.id, "unloads", qt, "of", product.id, "to warehouse", warehouse.id, "→", self.avail)
|
|
|
|
output(self.id, 'U', warehouse.id, product.id, qt)
|
|
|
|
|
|
|
|
def deliver(self, client, product, qt):
|
|
|
|
assert(self.available())
|
|
|
|
if (self.pos != client.pos):
|
|
|
|
self.busyFor(distance(self.pos, client.pos))
|
|
|
|
self.pos = client.pos
|
|
|
|
for q in range(qt):
|
|
|
|
self.items.remove(product.id)
|
|
|
|
client.needs.remove(product.id)
|
|
|
|
self.busyFor(1)
|
|
|
|
log("Drone", self.id, "delivers", qt, "of", product.id, "to client", client.id, "→", self.avail)
|
|
|
|
output(self.id, 'D', client.id, product.id, qt)
|
|
|
|
if client.satisfied():
|
|
|
|
global score
|
2016-02-13 15:48:53 +00:00
|
|
|
score += math.ceil((T-(self.avail+1))/T*100)
|
2016-02-16 19:30:10 +00:00
|
|
|
Client.UNSATISFIED.remove(client)
|
2016-02-13 11:54:59 +00:00
|
|
|
log("Client", client.id, "satisfied!", "New score:", score)
|
|
|
|
|
|
|
|
def wait(self, turns=1):
|
|
|
|
assert(self.available())
|
|
|
|
self.busyFor(1)
|
2016-02-13 14:36:44 +00:00
|
|
|
log("Drone", self.id, "waits", turns, "turn" + ('s' if turns >= 2 else ''), "→", self.avail)
|
2016-02-13 11:54:59 +00:00
|
|
|
output(self.id, 'W', turns)
|
|
|
|
|
2016-02-13 13:07:13 +00:00
|
|
|
# Set functions
|
2016-02-13 12:09:14 +00:00
|
|
|
def near(pos):
|
|
|
|
couples = []
|
|
|
|
for el in __class__.ALL:
|
|
|
|
couples.append([el, distance(el.pos, pos)])
|
|
|
|
return [couple[0] for couple in sorted(couples, key=lambda c: c[1])]
|
|
|
|
|
2016-02-12 16:44:38 +00:00
|
|
|
def get(pid):
|
|
|
|
return __class__.ALL[pid]
|
|
|
|
|
|
|
|
def len():
|
|
|
|
return len(__class__.ALL)
|
|
|
|
|
|
|
|
|
|
|
|
X = 0 # Nb rows
|
|
|
|
Y = 0 # Nb columns
|
|
|
|
T = 0 # Deadline
|
|
|
|
|
2016-02-13 11:54:59 +00:00
|
|
|
turn = 0 # Turn
|
|
|
|
score = 0 # Score
|
2016-02-13 14:36:44 +00:00
|
|
|
done = False
|
2016-02-13 11:54:59 +00:00
|
|
|
|
2016-02-12 16:44:38 +00:00
|
|
|
def readFile(filename):
|
|
|
|
global X, Y, T
|
|
|
|
|
|
|
|
with open(filename, 'r') as f:
|
|
|
|
# Parameters
|
|
|
|
X, Y, D, T, Drone.PAYLOAD = [int(i) for i in f.readline().split(' ')]
|
|
|
|
|
|
|
|
# Products
|
|
|
|
P = int(f.readline())
|
2016-02-13 11:54:59 +00:00
|
|
|
weights = [int(i) for i in f.readline().split(' ')]
|
2016-02-12 16:44:38 +00:00
|
|
|
assert(len(weights) == P)
|
|
|
|
for w in weights:
|
|
|
|
Product(w)
|
|
|
|
|
|
|
|
# Warehouses
|
|
|
|
for i in range(0, int(f.readline())):
|
|
|
|
pos = [int(i) for i in f.readline().split(' ')]
|
|
|
|
qtItems = [int(i) for i in f.readline().split(' ')]
|
|
|
|
assert(len(qtItems) == P)
|
|
|
|
|
|
|
|
items = []
|
|
|
|
for p in range(P):
|
|
|
|
for i in range(qtItems[p]):
|
|
|
|
items.append(p)
|
|
|
|
|
|
|
|
Warehouse(pos, items)
|
|
|
|
|
|
|
|
# Clients
|
|
|
|
for i in range(0, int(f.readline())):
|
|
|
|
pos = [int(i) for i in f.readline().split(' ')]
|
|
|
|
|
|
|
|
N = int(f.readline())
|
|
|
|
|
|
|
|
needs = [int(i) for i in f.readline().split(' ')]
|
|
|
|
assert(len(needs) == N)
|
|
|
|
|
|
|
|
Client(pos, needs)
|
|
|
|
|
|
|
|
# Create drones
|
|
|
|
for d in range(D):
|
|
|
|
Drone()
|
|
|
|
|
2016-02-16 22:48:59 +00:00
|
|
|
# Find warehouse needs
|
|
|
|
for warehouse in Warehouse.ALL:
|
|
|
|
needs = []
|
|
|
|
extra = warehouse.items.copy()
|
|
|
|
for client in warehouse.clients:
|
|
|
|
needs += client.needs
|
|
|
|
for item in needs:
|
|
|
|
if item in extra:
|
|
|
|
extra.remove(item)
|
|
|
|
for item in warehouse.items:
|
|
|
|
if item in needs:
|
|
|
|
needs.remove(item)
|
|
|
|
warehouse.needs = warehouse.plannedNeeds = needs
|
|
|
|
warehouse.extra = warehouse.plannedExtra = extra
|
|
|
|
|
2016-02-12 16:44:38 +00:00
|
|
|
readFile(sys.argv[1])
|
2016-02-13 11:54:59 +00:00
|
|
|
|
|
|
|
def newTurn():
|
|
|
|
global turn
|
|
|
|
# Finishing turn
|
2016-02-13 12:44:11 +00:00
|
|
|
for drone in Drone.ALL:
|
|
|
|
drone.executeTask()
|
2016-02-13 11:54:59 +00:00
|
|
|
# New turn
|
|
|
|
turn += 1
|
|
|
|
log("--- Turn", turn)
|
|
|
|
availableDrones = [str(drone.id) for drone in Drone.ALL if drone.available()]
|
2016-02-13 13:07:13 +00:00
|
|
|
#log("Drones", ", ".join(availableDrones), "("+str(len(availableDrones))+")", "are available")
|
2016-02-13 11:54:59 +00:00
|
|
|
|
2016-02-13 14:36:44 +00:00
|
|
|
# Algorithm that only works for 1 warehouse
|
2016-02-13 17:51:47 +00:00
|
|
|
|
|
|
|
# Determined by trial and error. Not really reliable
|
|
|
|
CLIENT_TRIES = 3
|
2016-02-13 19:12:03 +00:00
|
|
|
CLIENT_TRIES = 100
|
2016-02-13 17:51:47 +00:00
|
|
|
def efficiency(pack, time):
|
|
|
|
return Product.totalWeight(pack) / time
|
|
|
|
#return len(pack) / time
|
|
|
|
#return 1 / time
|
|
|
|
|
2016-02-13 15:43:54 +00:00
|
|
|
def route(roadmap):
|
2016-02-16 22:48:59 +00:00
|
|
|
# Refill warehouse first
|
|
|
|
# TODO Merge both (this is actually more for testin.idg)
|
|
|
|
remainingWarehouses = [w for w in Warehouse.near(roadmap['pos']) if w.plannedNeeds and w not in roadmap['clients'] and w != roadmap['warehouse']]
|
|
|
|
for warehouse in remainingWarehouses[:CLIENT_TRIES]:
|
|
|
|
pack = warehouse.pack(Drone.PAYLOAD - Product.totalWeight(roadmap['loads']), roadmap['warehouse'].plannedExtra)
|
|
|
|
if not pack:
|
|
|
|
continue
|
|
|
|
roadmap['warehouse'].planUnload(pack)
|
|
|
|
warehouse.planRefill(pack)
|
|
|
|
roadmap['deliverTime'] += 42
|
|
|
|
roadmap['pos'] = warehouse.pos
|
|
|
|
roadmap['loads'] += pack
|
|
|
|
roadmap['clients'].append(warehouse)
|
|
|
|
roadmap['stops'].append((warehouse, pack))
|
|
|
|
return roadmap
|
|
|
|
|
|
|
|
|
2016-02-13 15:43:54 +00:00
|
|
|
# Find the nearest client that still has things to be delivered
|
2016-02-13 16:16:33 +00:00
|
|
|
remainingClients = [c for c in Client.near(roadmap['pos']) if c.plannedNeeds and c not in roadmap['clients']]
|
2016-02-13 16:40:19 +00:00
|
|
|
#for client in remainingClients:
|
2016-02-13 17:22:16 +00:00
|
|
|
options = []
|
2016-02-13 16:40:19 +00:00
|
|
|
for client in remainingClients[:CLIENT_TRIES]:
|
2016-02-13 19:12:03 +00:00
|
|
|
#for client in remainingClients:
|
2016-02-13 15:43:54 +00:00
|
|
|
# Create a pack to deliver
|
2016-02-13 19:12:03 +00:00
|
|
|
pack = client.pack(Drone.PAYLOAD - Product.totalWeight(roadmap['loads']), roadmap['warehouse'].plannedItems)
|
2016-02-13 16:16:33 +00:00
|
|
|
if not pack:
|
2016-02-13 16:40:19 +00:00
|
|
|
continue
|
2016-02-13 16:59:31 +00:00
|
|
|
|
2016-02-13 17:22:16 +00:00
|
|
|
# Calcultes the efficiency of adding a stop
|
2016-02-13 16:59:31 +00:00
|
|
|
routeTime = distance(roadmap['pos'], client.pos) + len(list(set(pack)))
|
2016-02-13 17:51:47 +00:00
|
|
|
routeEfficiency = efficiency(pack, routeTime)
|
2016-02-13 16:59:31 +00:00
|
|
|
if roadmap['stops']:
|
|
|
|
# Calculates the efficiency of coming back to warehouse and to the client again
|
2016-02-13 19:12:03 +00:00
|
|
|
backPack = client.pack(rests=roadmap['warehouse'].items)
|
2016-02-13 17:22:16 +00:00
|
|
|
backTime = len(list(set(backPack))) + distance(roadmap['pos'], roadmap['warehouse'].pos) + distance(roadmap['warehouse'].pos, client.pos)
|
2016-02-13 17:51:47 +00:00
|
|
|
backEfficiency = efficiency(backPack, backTime)
|
2016-02-13 16:59:31 +00:00
|
|
|
if backEfficiency > routeEfficiency:
|
|
|
|
continue
|
2016-02-13 17:22:16 +00:00
|
|
|
options.append({
|
|
|
|
'client': client,
|
|
|
|
'efficiency': routeEfficiency,
|
|
|
|
'routeTime': routeTime,
|
|
|
|
'pack': pack
|
|
|
|
})
|
2016-02-13 17:54:19 +00:00
|
|
|
if not roadmap['stops']: # If it is the first stop, don't provide any alternative
|
|
|
|
break
|
|
|
|
|
2016-02-13 17:22:16 +00:00
|
|
|
if options:
|
|
|
|
# Choose the best option (i.e. the max efficiency)
|
2016-02-13 17:51:47 +00:00
|
|
|
#option = sorted(options, key=lambda c: c['efficiency'])[-1]
|
|
|
|
option = options[0]
|
2016-02-13 15:43:54 +00:00
|
|
|
# Plan the delivery
|
2016-02-13 17:22:16 +00:00
|
|
|
roadmap['warehouse'].plan(option['pack'])
|
|
|
|
option['client'].plan(option['pack'])
|
|
|
|
roadmap['deliverTime'] += option['routeTime']
|
|
|
|
roadmap['pos'] = option['client'].pos
|
|
|
|
roadmap['loads'] += option['pack']
|
|
|
|
roadmap['clients'].append(option['client'])
|
|
|
|
roadmap['stops'].append((option['client'], option['pack']))
|
2016-02-13 16:16:33 +00:00
|
|
|
return route(roadmap)
|
2016-02-13 17:22:16 +00:00
|
|
|
else:
|
|
|
|
return roadmap
|
2016-02-13 15:43:54 +00:00
|
|
|
|
|
|
|
|
2016-02-13 14:36:44 +00:00
|
|
|
def think():
|
|
|
|
# For each drone that has nothing to do
|
|
|
|
for drone in [d for d in Drone.ALL if d.available() and not d.tasks]:
|
|
|
|
# Find the nearest warehouse
|
|
|
|
warehouse = Warehouse.near(drone.pos)[0]
|
2016-02-13 15:43:54 +00:00
|
|
|
roadmap = route({
|
|
|
|
'pos': warehouse.pos,
|
|
|
|
'warehouse': warehouse,
|
|
|
|
'deliverTime': 0,
|
|
|
|
'loads': [],
|
2016-02-13 16:16:33 +00:00
|
|
|
'clients': [],
|
2016-02-13 15:43:54 +00:00
|
|
|
'stops': []
|
|
|
|
})
|
|
|
|
|
|
|
|
if not roadmap['stops']:
|
2016-02-13 14:36:44 +00:00
|
|
|
done = True
|
2016-02-16 22:48:59 +00:00
|
|
|
#if len(Client.UNSATISFIED) == 0:
|
|
|
|
# done = False
|
2016-02-16 19:30:10 +00:00
|
|
|
if done:
|
|
|
|
break
|
2016-02-13 14:36:44 +00:00
|
|
|
|
2016-02-13 15:43:54 +00:00
|
|
|
loadOcc = dict((i, roadmap['loads'].count(i)) for i in roadmap['loads'])
|
|
|
|
for i in loadOcc:
|
|
|
|
drone.addTask('load', warehouse, Product.get(i), loadOcc[i])
|
|
|
|
|
|
|
|
for client, items in roadmap['stops']:
|
|
|
|
itemsOcc = dict((j, items.count(j)) for j in items)
|
2016-02-16 22:48:59 +00:00
|
|
|
action = 'deliver' if type(client).__name__ is 'Client' else 'unload'
|
2016-02-13 15:43:54 +00:00
|
|
|
for i in itemsOcc:
|
2016-02-16 22:48:59 +00:00
|
|
|
drone.addTask(action, client, Product.get(i), itemsOcc[i])
|
2016-02-13 15:43:54 +00:00
|
|
|
|
|
|
|
|
2016-02-13 14:36:44 +00:00
|
|
|
|
|
|
|
if DEBUG:
|
|
|
|
SIMULATION = 1000
|
|
|
|
else:
|
|
|
|
SIMULATION = 8*T/10
|
|
|
|
|
2016-02-13 11:54:59 +00:00
|
|
|
try:
|
2016-02-13 14:36:44 +00:00
|
|
|
if not DEBUG:
|
|
|
|
bar = progressbar.ProgressBar(max_value=SIMULATION)
|
|
|
|
while turn < SIMULATION and not done:
|
|
|
|
think()
|
2016-02-13 12:44:11 +00:00
|
|
|
newTurn()
|
2016-02-13 14:36:44 +00:00
|
|
|
if not DEBUG:
|
|
|
|
bar.update(turn)
|
2016-02-13 16:24:47 +00:00
|
|
|
while turn < SIMULATION and [d for d in Drone.ALL if d.tasks]:
|
|
|
|
newTurn()
|
2016-02-16 19:30:10 +00:00
|
|
|
#if not DEBUG:
|
|
|
|
# bar.update(turn)
|
2016-02-13 14:36:44 +00:00
|
|
|
if not DEBUG:
|
|
|
|
bar.finish()
|
2016-02-13 11:54:59 +00:00
|
|
|
|
|
|
|
|
|
|
|
except KeyboardInterrupt:
|
|
|
|
pass
|
|
|
|
|
|
|
|
with open(sys.argv[1] + 'o', 'w') as f:
|
|
|
|
f.write(str(len(outLines)) + '\n' + '\n'.join(outLines) + '\n')
|
2016-02-13 14:36:44 +00:00
|
|
|
print("Turn:", turn)
|
2016-02-13 11:54:59 +00:00
|
|
|
print("Score:", score)
|
|
|
|
|