Ejemplo n.º 1
0
def is_route_efficient_to_chunk(route, chunk):
    distance_w2o = distance(route.w.pos, route.o.pos)
    for ch_route in chunk.routes:
        distance_o2o = distance(ch_route.o.pos, route.o.pos)

        if (distance_w2o < distance_o2o):
            return False

    return True
Ejemplo n.º 2
0
 def update(self):
     self._i -= 1
     if distance(self.owner, self.target) > self.owner.shoot_range:
         self.chase_target()
     elif self._i > 0:
         self.stop()
     else:
         self.owner.attack(self.target)
         self._i = self.reload_time
     super().update()
Ejemplo n.º 3
0
def o_fulfilment_cost(o_fulfilment):
    cost = 0
    o, o_fulfilment = o_fulfilment

    # give me all the warehouse IDs from which this fulfilment would
    # get the product
    w_ids = [o_item_fulfilment[1] for o_item_fulfilment in o_fulfilment]

    for w_id in w_ids:
        cost += 2 * distance(initial_state.warehouses[w_id].pos, o.pos)

    return cost
Ejemplo n.º 4
0
def find_drone_action_for_warehouse(state, d, w):
    o_deliverable_fully = []
    o_other = []

    for o in state.open_orders:
        if o.delivered():
            continue

        o_deliverable_weight = 0
        o_deliverable_items = []
        o_undeliverable_weight = 0

        # lets create copy of warehouse so we can check that the stock
        # is enough
        temp_w = copy.deepcopy(w)

        for item in o.items:
            if o.delivered():
                continue

            if item.delivered:
                continue

            pt_weight = world.pt_weights[item.pt_id]

            if temp_w.stock[item.pt_id] > 0:
                # item in warehouse stock
                temp_w.stock[item.pt_id] -= 1
                o_deliverable_weight += pt_weight
                o_deliverable_items.append(item)
            else:
                # item not in warehouse stock
                o_undeliverable_weight += pt_weight

        # print('@')
        # print(str(o.id))
        # print(str(o_deliverable_weight))
        # print((o_undeliverable_weight == 0 and o_deliverable_weight < world.d_max_payload))

        if o_deliverable_weight == 0:
            # nothing in this warehouse for the order
            pass
        elif o_undeliverable_weight == 0 and o_deliverable_weight < world.d_max_payload:
            # lets log orders which we can fully deliver from this warehouse
            # by just one drone flight
            o_deliverable_fully.append(o)
        else:
            o_other.append((o, o_deliverable_items, o_deliverable_weight, o_undeliverable_weight))

    # if there are some orders which can be delivered fully, do that!
    if len(o_deliverable_fully) > 0:
        o_deliverable_fully.sort(key = lambda o: distance(o.pos, d.pos))
        o = o_deliverable_fully[0]
        return (w, o, [i for i in o.items if not i.delivered])

    if len(o_other) == 0:
        # there is no order, we got it all!
        return None

    # otherwise find the order with lowest deliverable weight
    o_other.sort(key = lambda x: x[2])
    o, o_deliverable_items, a, b = o_other[0]

    # and limit the number of items based on max payload
    deliver_items = []
    deliver_weight = 0
    for item in o_deliverable_items:
        pt_weight = world.pt_weights[item.pt_id]
        if (deliver_weight + pt_weight) <= world.d_max_payload:
            deliver_items.append(item)
            deliver_weight += pt_weight

    return (w, o, deliver_items)
Ejemplo n.º 5
0
    idle_drones = [d for d in state.drones if d.turns_to_pos == 0]

    for d in idle_drones:
        # find action to do
        action = find_drone_action(state, d)

        if action == None:
            continue

        w, o, items_to_deliver = action

        turns_till_idle_again = 0

        # drone has to get to the warehouse first
        turns_till_idle_again += distance(d.pos, w.pos)
        print("  * sending drone " + str(d.id) + " to warehouse " + str(w.id) +  " at " + str(w.pos[0]) + "-" + str(w.pos[1]) + " (distance: " + str(distance(d.pos, w.pos)) + ")")

        # load stuff from warehouse
        for item in items_to_deliver:
            output.load(d.id, w.id, item.pt_id, 1)
            print("  * loading drone " + str(d.id) + " with product " + str(item.pt_id))

            print("  $ stock of " + str(item.pt_id) + " at warehouse " + str(w.id) + " was " + str(w.stock[item.pt_id]) + ", is now " + str(w.stock[item.pt_id] - 1))
            w.stock[item.pt_id] -= 1

            # every load command takes one turn
            turns_till_idle_again += 1

        # drone has to get to order
        turns_till_idle_again += distance(w.pos, o.pos)
Ejemplo n.º 6
0
def warehouses_closest_first(warehouses, o_pos):
    return sorted(warehouses, key = lambda w: distance(w.pos, o_pos))
Ejemplo n.º 7
0
def chunk_routes(world, routes):
    routes_by_w = grouped_routes_by_warehouse_id(routes)
    chunks = []

    for w_id, w_routes in routes_by_w.items():
        w_routes_heaviest_first = sorted_routes_heaviest_first(w_routes)
        w = w_routes_heaviest_first[0].w

        chunk = RoutesChunk()
        chunk.w = w
        chunk.routes = []
        chunk.weight = 0

        while True:
            rel_route = w_routes_heaviest_first.pop(0)
            chunk.routes.append(rel_route)
            chunk.weight += rel_route.weight

            routes_with_closest_o = sorted(w_routes_heaviest_first, key = lambda r: distance(r.o.pos, rel_route.o.pos))

            for route in routes_with_closest_o:
                if (chunk.weight + route.weight) > world.d_max_payload:
                    continue

                if distance(route.o.pos, rel_route.o.pos) > distance(route.o.pos, route.w.pos):
                    continue

                # TODO: also! if we will chunk together routes with same products,
                # it will in the end save turns on loading (might be interesting?)

                # print("distance " + str(distance(route.o.pos, rel_route.o.pos)))

                w_routes_heaviest_first.remove(route)
                chunk.routes.append(route)
                chunk.weight += route.weight

            chunks.append(chunk)

            chunk = RoutesChunk()
            chunk.w = w
            chunk.routes = []
            chunk.weight = 0

            if len(w_routes_heaviest_first) == 0:
                break

    for chunk in chunks:
        chunk.items_by_o_id_and_pt_id = {}
        chunk.items_by_pt_id = {}

        for route in chunk.routes:

            if route.o.id not in chunk.items_by_o_id_and_pt_id:
                chunk.items_by_o_id_and_pt_id[route.o.id] = {}

            for item in route.items:
                if item.pt_id not in chunk.items_by_o_id_and_pt_id[route.o.id]:
                    chunk.items_by_o_id_and_pt_id[route.o.id][item.pt_id] = []

                if item.pt_id not in chunk.items_by_pt_id:
                    chunk.items_by_pt_id[item.pt_id] = []

                chunk.items_by_o_id_and_pt_id[route.o.id][item.pt_id].append(item)
                chunk.items_by_pt_id[item.pt_id].append(item)

    for chunk in chunks:
        chunk.avg_routes_per_order = 0
        chunk.min_routes_per_order = chunk.routes[0].routes_per_order
        for route in chunk.routes:
            chunk.avg_routes_per_order += route.routes_per_order
            if route.routes_per_order < chunk.min_routes_per_order:
                chunk.min_routes_per_order = route.routes_per_order
        chunk.avg_routes_per_order = chunk.avg_routes_per_order / len(chunk.routes)


    # chunks1 = sorted(chunks, key = lambda ch: ch.weight, reverse = True)
    # for chunk in chunks1:
    #     print(str(chunk.weight) + " " + str(len(chunk.routes)))

    # print('all: ' + str(len(chunks)))
    #
    # chunks2 = list(filter(lambda ch: ch.weight == world.d_max_payload, chunks))
    # print('full weight: ' + str(len(chunks2)))
    #
    # chunks3 = list(filter(lambda ch: ch.weight > 190, chunks))
    # print('> 190: ' + str(len(chunks3)))
    #
    # chunks4 = list(filter(lambda ch: ch.weight > 180, chunks))
    # print('> 180: ' + str(len(chunks4)))
    #
    # chunks5 = list(filter(lambda ch: ch.weight > 170, chunks))
    # print('> 170: ' + str(len(chunks5)))
    #
    # sys.exit(0)

    return chunks