diff --git a/Makefile b/Makefile index d9db864..f7514d0 100644 --- a/Makefile +++ b/Makefile @@ -6,10 +6,10 @@ submission.zip: zip $@ .git *.py -r 1o: 1 - python main.py $< + python reborn.py $< 2o: 2 python reborn.py $< 3o: 3 - python main.py $< + python reborn.py $< .PHONY: submission.zip 1o 2o 3o diff --git a/reborn.py b/reborn.py index dd4d408..9056f55 100755 --- a/reborn.py +++ b/reborn.py @@ -5,7 +5,7 @@ import math import copy import progressbar -DEBUG = True +DEBUG = False outLines = [] @@ -54,11 +54,46 @@ class Warehouse: self.items = items self.plannedItems = self.items.copy() + self.clients = [] def plan(self, items): for i in items: self.plannedItems.remove(i) + 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 + # Set functions def near(pos): couples = [] @@ -86,6 +121,8 @@ class Client: self.needs = needs self.plannedNeeds = self.needs.copy() + self.warehouse = Warehouse.near(self.pos)[0] + self.warehouse.clients.append(self) def plan(self, needs): for n in needs: @@ -282,6 +319,21 @@ def readFile(filename): for d in range(D): Drone() + # 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 + readFile(sys.argv[1]) def newTurn(): @@ -306,6 +358,23 @@ def efficiency(pack, time): #return 1 / time def route(roadmap): + # 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 + + # Find the nearest client that still has things to be delivered remainingClients = [c for c in Client.near(roadmap['pos']) if c.plannedNeeds and c not in roadmap['clients']] #for client in remainingClients: @@ -336,7 +405,6 @@ def route(roadmap): if not roadmap['stops']: # If it is the first stop, don't provide any alternative break - if options: # Choose the best option (i.e. the max efficiency) #option = sorted(options, key=lambda c: c['efficiency'])[-1] @@ -370,9 +438,8 @@ def think(): if not roadmap['stops']: done = True - if len(Client.UNSATISFIED) == 0: - done = False - break + #if len(Client.UNSATISFIED) == 0: + # done = False if done: break @@ -382,8 +449,9 @@ def think(): for client, items in roadmap['stops']: itemsOcc = dict((j, items.count(j)) for j in items) + action = 'deliver' if type(client).__name__ is 'Client' else 'unload' for i in itemsOcc: - drone.addTask('deliver', client, Product.get(i), itemsOcc[i]) + drone.addTask(action, client, Product.get(i), itemsOcc[i])