def assign_transporter(self, container):
    # """the function 'find closest transporter' is called and the closest and available transporter is matched to
    # the container"""
        closest_transporter = self.find_closest_transporter(container)
        if closest_transporter is not None:
            for transporter in self.transporters:
                if transporter == closest_transporter:
                    # the status of the entities is updated
                    transporter.state = TransporterState.PICKUP
                    transporter.transport_contract.append(container)
                    transporter.route_length = \
                        route_euclidean_distance(self.env,container.location,
                                                 transporter.location)

                    if container.state == ContainerState.NEEDING_TRANSPORT:
                        container.state = ContainerState.AWAITING_TRANSPORT

                    elif container.state == ContainerState.RELOCATION_NEED:
                        container.state = ContainerState.AWAITING_RELOCATION

                        if self.env.config.debug is True:
                            print("Transporter %s is assigned to pickup "
                                  "container %s that is in need of relocation"
                                  %(transporter.id, container.id))
        return
    def reached_shipment_pickup(self):
        # UPDATE TRANSPORTER INFO
        # location and state info with shipment info from container contract
        self.region = self.load.shipment_contracts[0].region
        self.location = self.load.shipment_contracts[0].location
        self.route_length += route_euclidean_distance(
            self.env, self.location,
            self.load.shipment_contracts[0].destination)

        # UPDATE CONTAINER INFO (= self.load)
        # location and state info update with updated transporter info (above)
        self.load.region = self.region
        self.load.location = self.location
        self.load.state = ContainerState.DELIVERING
        # add shipment to container load
        self.load.load = self.load.shipment_contracts[0]

        # UPDATE SHIPMENT INFO (= container.load, therefore self.load.load)
        self.load.load.state = ShipmentState.ON_ROUTE

        # UPDATE PRODUCER INFO
        # remove picked up shipment from producer's storage
        self.env.producers[self.load.load.producer_id].storage = \
            [shipment for shipment in
             self.env.producers[self.load.load.producer_id].storage
             if shipment.id != self.load.load.id]

        if self.env.config.debug is True:
            print("Transporter %s reached shipment %s pickup location"
                  "and has an updated route length of: %s"
                  % (self.id, self.load.shipment_contracts[0].id,
                     self.route_length))
    def find_closest_transporter(self, container):
        #each transporter's status from the list in the init is checked
        available_transporters = [transporter for transporter in
                                  self.transporters if transporter.state ==
                                  TransporterState.EMPTY]

        if len(available_transporters) > 0:
            closest_distance_to_pickup = \
                [route_euclidean_distance(self.env, container.location,
                                            available_transporters[0].location),
                 available_transporters[0]]
            for transporter in available_transporters:
                distance_to_pickup = \
                    route_euclidean_distance(self.env,
                                             container.location,
                                             transporter.location)
                if distance_to_pickup < closest_distance_to_pickup[0]:
                    closest_distance_to_pickup = \
                        [distance_to_pickup,transporter]
            return closest_distance_to_pickup[1]
        return
示例#4
0
    def bid(self, registrationkey, item: Shipment):
        ''' Minimum shipment biddingvalue consists of:
        1) transport costs from hub to pickup location
        2) transport costs from pickup location to destination'''
        producerbid = namedtuple('producerbid',
                                 'registration_key biddingvalue')
        hub_coords = find_hub_coordinates(self.region)
        transport_cost_from_hub = self.env.config.transport_cost * \
                                  route_euclidean_distance(self.env,
                                                           hub_coords,
                                                           item.location)
        transport_cost_to_destination = self.env.config.transport_cost * \
                                        route_euclidean_distance(self.env,
                                                                 item.location,
                                                                 item.destination)
        #TODO improve biddingvalue based on shipping urgency
        storage_utilisation = len(self.storage) / self.storage_capacity
        # using steps of 10% for urgency
        storage_utilisation = ceil(storage_utilisation * 10)
        urgency = storage_utilisation / 10
        # urgency cost based on region size
        shipping_urgency_cost = urgency * \
                                self.env.config.region_size * \
                                self.env.config.transport_cost
        #TODO add standard fees for container functionalties
        total_value = transport_cost_from_hub + transport_cost_to_destination \
                      + shipping_urgency_cost

        producerbid = producerbid(registration_key=registrationkey,
                                  biddingvalue=total_value)

        if self.env.config.debug is True and self.region.id < 1:
            print("producer %s in region: %s enters bid: %s "
                  "for shipment with id: %s" %
                  (self.id, self.region.id, producerbid, item.id))

        return producerbid
    def create_bids(self, best_shipments, registrationkey):
        """ creates the list with bids. The return function leaves the current function call with the list with bids as
        return value """

        containerbid = namedtuple(
            'containerbid',
            'container_registration_key shipment_registration_key biddingvalue'
        )
        containerbids = []
        for entry in best_shipments:
            shipment_registration_key = entry[0]
            shipment = entry[2]
            transport_cost_empty = route_euclidean_distance(
                self.env, self.location, shipment.location)
            transport_cost_shipment = route_euclidean_distance(
                self.env, shipment.location, shipment.destination)
            biddingvalue = transport_cost_empty + transport_cost_shipment
            #TODO add additional profit margin for container or decrease of biddingvalue based on urgency
            container_bid = containerbid(
                container_registration_key=registrationkey,
                shipment_registration_key=shipment_registration_key,
                biddingvalue=biddingvalue)
            containerbids.append(container_bid)
        return containerbids
    def reached_relocating_container(self):
        # UPDATE TRANSPORTER INFO
        # update location and state info from transport contract
        self.region = self.transport_contract[0].region
        self.location = self.transport_contract[0].location
        self.state = TransporterState.TRANSPORTING
        # Add container to load from contract
        self.load = self.transport_contract[0]
        #  new route is from container location to region hub
        self.route_length += route_euclidean_distance(
            self.env, self.location, find_hub_coordinates(self.region))

        # UPDATE CONTAINER INFO
        self.transport_contract[0].state = ContainerState.RELOCATING

        if self.env.config.debug is True:
            print("Container % is picked up and will be relocated"
                  % (self.load.id))
    def reached_empty_container(self):
        # UPDATE TRANSPORTER INFO
        # location and state info
        self.region = self.transport_contract[0].region
        self.location = self.transport_contract[0].location
        self.state = TransporterState.TRANSPORTING
        # assign container to load
        self.load = self.transport_contract[0]
        # new route is from container pick up location to shipment
        # pick up location
        self.route_length += route_euclidean_distance(
            self.env, self.location, self.load.shipment_contracts[0].location)

        # UPDATE CONTAINER INFO
        self.transport_contract[0].state = ContainerState.PICKUP

        if self.env.config.debug is True:
            print("Transporter %s reached container %s and "
                  "has an updated route length of: %s"
                  % (self.id, self.transport_contract[0].id,
                     self.route_length))
    def select_best_shipments(self, available_shipments):
        ''' In the final model, the container should make transport reservations for each shipment it bids on,
        therefore the container places a limited number of bids. The container makes a selection based on the
        distance to the shipments. The closer a container is to a shipment, the lower it can bid.'''
        distance_to_shipments = []

        for key in available_shipments.keys():
            shipment = self.region.auctioneer.entities[
                EntityTypes.SHIPMENT][key]
            distance = route_euclidean_distance(self.env, self.location,
                                                shipment.location)
            registrationkey = key
            distance_to_shipments.append([registrationkey, distance, shipment])

        distance_to_shipments.sort(key=lambda item: item[1])
        best_shipments = distance_to_shipments[:self.env.config.number_of_bids]

        if self.env.config.debug and self.id < 1:
            print("\n", distance_to_shipments)
            print("from this list, the container should select the %s "
                  "closest shipments" % (self.env.config.number_of_bids))
            print(best_shipments, "\n")
        return best_shipments
def calculate_matching_distance(matches, auctioneer, matching_distances: list,
                                day):
    if matches is None:
        return

    if day < Config.warmup_period:
        return

    for match in matches:
        # first determine container location
        for key in auctioneer.entities[EntityTypes.CONTAINER]:
            if match.container_registration_key == key:
                container_location = \
                    auctioneer.entities[EntityTypes.CONTAINER][key].location
        # determine shipment location
        for key in auctioneer.entities[EntityTypes.SHIPMENT]:
            if match.shipment_registration_key == key:
                shipment_location = \
                    auctioneer.entities[EntityTypes.SHIPMENT][key].location
        match_distance = route_euclidean_distance(auctioneer.env,
                                                  container_location,
                                                  shipment_location)
        matching_distances.append(match_distance)
    return matching_distances