示例#1
0
    def get_mask(self, vehicle_count):
        """
        Gets a (batch_size, n_loc + 1) mask with the feasible actions (0 = depot), depends on already visited and
        remaining capacity. 0 = feasible, 1 = infeasible
        Forbids to visit depot twice in a row, unless all nodes have been visited
        :return:
        """

        if self.visited_.dtype == torch.uint8:
            visited_loc = self.visited_[:, :, vehicle_count:]
        else:
            visited_loc = mask_long2bool(self.visited_, n=self.demand.size(-1))

        demands = (self.demand.view(-1, 1).repeat(1, vehicle_count).view(
            self.ids.shape[0], -1))[self.ids, :]
        used_cap = (self.used_capacity.view(
            self.used_capacity.shape[0], 1,
            vehicle_count).repeat(1, 1, demands.shape[-1] // vehicle_count))
        # For demand steps_dim is inserted by indexing with id, for used_capacity insert node dim for broadcasting
        exceeds_cap = (demands + used_cap > self.VEHICLE_CAPACITY)
        # Nodes that cannot be visited are already visited or too much demand to be served now
        mask_loc = visited_loc.to(exceeds_cap.dtype) | exceeds_cap

        # Cannot visit the depot if just visited and still unserved nodes
        mask_depot = (self.prev_a == 0) & (
            (mask_loc == 0).int().sum(-1) > 0)[:, :, None]
        return torch.cat((mask_depot, mask_loc), -1)
示例#2
0
    def get_mask(self):
        """
        Gets a (batch_size, n_loc + 1) mask with the feasible actions (0 = depot), depends on already visited and
        remaining capacity. 0 = feasible, 1 = infeasible
        Forbids to visit depot twice in a row, unless all nodes have been visited
        :return:
        """

        if self.visited_.dtype == torch.uint8:
            visited_loc = self.visited_[:, :, 1:]
        else:
            visited_loc = mask_long2bool(self.visited_, n=self.demand.size(-1))

        # For demand steps_dim is inserted by indexing with id, for used_capacity insert node dim for broadcasting
        exceeds_cap = (self.demand[self.ids, :] +
                       self.used_capacity[:, :, None] > self.VEHICLE_CAPACITY)
        # eta = (self.coords[:, 1:, :] - self.cur_coord).norm(p=2, dim=-1)
        # not_started_time = (self.time_window_start[self.ids, 1:] > self.cur_time[:, :, None] + eta[:, None, :])
        # closed_time = (self.time_window_finish[self.ids, 1:] < self.cur_time[:, :, None] + eta[:, None, :])
        # Nodes that cannot be visited are already visited or too much demand to be served now
        mask_loc = visited_loc.to(exceeds_cap.dtype) | exceeds_cap
        # | not_started_time | closed_time

        # Cannot visit the depot if just visited and still unserved nodes
        mask_depot = (self.prev_a == 0) & ((mask_loc == 0).int().sum(-1) > 0)
        return torch.cat((mask_depot[:, :, None], mask_loc), -1)
示例#3
0
    def get_mask(self):
        """
        Gets a (batch_size, n_loc + 1) mask with the feasible actions (0 = depot), depends on already visited and
        remaining capacity. 0 = feasible, 1 = infeasible
        Forbids to visit depot twice in a row, unless all nodes have been visited
        :return:
        """

        if self.visited_.dtype == torch.uint8:
            visited_loc = self.visited_[:, :, 1:]
        else:
            visited_loc = mask_long2bool(self.visited_, n=self.demand.size(-1))

        # Nodes that cannot be visited are already visited or too much demand to be served now
        mask_loc = (
            visited_loc |
            # For demand steps_dim is inserted by indexing with id, for used_capacity insert node dim for broadcasting
            (self.demand[self.ids, :] + self.used_capacity[:, :, None] >
             self.VEHICLE_CAPACITY))

        # Cannot visit the depot if just visited and still unserved nodes
        mask_depot = (self.prev_a == 0) & ((mask_loc == 0).int().sum(-1) > 0)
        return torch.cat((mask_depot[:, :, None], mask_loc), -1)
示例#4
0
 def visited(self):
     if self.visited_.dtype == torch.uint8:
         return self.visited_
     else:
         return mask_long2bool(self.visited_, n=self.coords.size(-2))
示例#5
0
 def visited(self):
     if self.visited_.dtype == torch.bool:
         return self.visited_
     else:
         return mask_long2bool(self.visited_, n=self.loc.size(-2))
示例#6
0
 def visited(self):
     if self.visited_.dtype == torch.uint8:
         return self.visited_
     else:
         return mask_long2bool(self.visited_, n=self.demand.size(-1))