Exchange between warehouses

master
Geoffrey Frogeye 2016-02-16 23:48:59 +01:00
父節點 f7246fa3b7
當前提交 e174125024
共有 2 個文件被更改,包括 76 次插入8 次删除

查看文件

@ -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

查看文件

@ -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])