| import json |
|
|
| from greedrl import Problem, Solver |
| from greedrl.feature import * |
| from greedrl.variable import * |
|
|
| features = [local_feature('task_area'), |
| local_feature('task_roadway'), |
| local_feature('task_area_group'), |
| sparse_local_feature('task_item_id', 'task_item_num'), |
| sparse_local_feature('task_item_owner_id', 'task_item_num'), |
| variable_feature('worker_task_item'), |
| variable_feature('worker_used_roadway'), |
| variable_feature('worker_used_area')] |
|
|
| variables = [task_demand_now('task_demand_now', feature='task_demand'), |
| task_demand_now('task_demand_this', feature='task_demand', only_this=True), |
| feature_variable('task_item_id'), |
| feature_variable('task_item_num'), |
| feature_variable('task_item_owner_id'), |
| feature_variable('task_area'), |
| feature_variable('task_area_group'), |
| feature_variable('task_load'), |
| feature_variable('task_group'), |
| worker_variable('worker_load_limit'), |
| worker_variable('worker_area_limit'), |
| worker_variable('worker_area_group_limit'), |
| worker_task_item('worker_task_item', item_id='task_item_id', item_num='task_item_num'), |
| worker_task_item('worker_task_item_owner', item_id='task_item_owner_id', item_num='task_item_num'), |
| worker_used_resource('worker_used_load', task_require='task_load'), |
| worker_used_resource('worker_used_area', task_require='task_area'), |
| worker_used_resource('worker_used_roadway', task_require='task_roadway'), |
| worker_used_resource('worker_used_area_group', task_require='task_area_group')] |
|
|
|
|
| class Constraint: |
|
|
| def do_task(self): |
| return self.task_demand_this |
|
|
| def mask_worker_end(self): |
| return self.worker_used_load < self.worker_load_limit |
|
|
| def mask_task(self): |
| |
| mask = self.task_demand_now <= 0 |
| |
|
|
| NT = self.task_item_id.size(1) |
| worker_task_item = self.worker_task_item[:, None, :] |
| worker_task_item = worker_task_item.expand(-1, NT, -1) |
| task_item_in_worker = worker_task_item.gather(2, self.task_item_id.long()) |
| task_item_in_worker = (task_item_in_worker > 0) & (self.task_item_num > 0) |
|
|
| worker_task_item_owner = self.worker_task_item_owner[:, None, :] |
| worker_task_item_owner = worker_task_item_owner.expand(-1, NT, -1) |
| task_item_owner_in_worker = worker_task_item_owner.gather(2, self.task_item_owner_id.long()) |
| task_item_owner_in_worker = (task_item_owner_in_worker > 0) & (self.task_item_num > 0) |
|
|
| |
| mask |= torch.any(task_item_in_worker & ~task_item_owner_in_worker, 2) |
|
|
| worker_load_limit = self.worker_load_limit - self.worker_used_load |
| mask |= (self.task_load > worker_load_limit[:, None]) |
|
|
| task_area = self.task_area + self.worker_used_area[:, None, :] |
| task_area_num = task_area.clamp(0, 1).sum(2, dtype=torch.int32) |
| mask |= (task_area_num > self.worker_area_limit[:, None]) |
|
|
| tak_area_group = self.task_area_group + self.worker_used_area_group[:, None, :] |
| tak_area_group_num = tak_area_group.clamp(0, 1).sum(2, dtype=torch.int32) |
| mask |= (tak_area_group_num > self.worker_area_group_limit[:, None]) |
|
|
| return mask |
|
|
| def finished(self): |
| return torch.all(self.task_demand_now <= 0, 1) |
|
|
|
|
| class Objective: |
|
|
| def step_worker_end(self): |
| area_num = self.worker_used_area.clamp(0, 1).sum(1) |
| roadway_num = self.worker_used_roadway.clamp(0, 1).sum(1) |
| item_num = self.worker_task_item.clamp(0, 1).sum(1) |
| penalty = (self.worker_load_limit - self.worker_used_load) * 10 |
| return area_num * 100 + roadway_num * 10 + item_num + penalty |
|
|
|
|
| def make_problem_from_json(data): |
| if isinstance(data, str): |
| data = json.loads(data) |
| problem = Problem() |
| problem.id = data["id"] |
| if 'uuid' in data: |
| problem.uuid = data["uuid"] |
|
|
| problem.task_item_id = torch.tensor(data["task_item_id"], dtype=torch.int32) |
| problem.task_item_owner_id = torch.tensor(data["task_item_owner_id"], dtype=torch.int32) |
| problem.task_item_num = torch.tensor(data["task_item_num"], dtype=torch.int32) |
| problem.task_area = torch.tensor(data["task_area"], dtype=torch.int32) |
| problem.task_roadway = torch.tensor(data["task_roadway"], dtype=torch.int32) |
| problem.task_out_stock_time = torch.tensor(data["task_out_stock_time"], dtype=torch.int32) |
| problem.task_area_group = torch.tensor(data["task_area_group"], dtype=torch.int32) |
|
|
| NT = problem.task_item_id.size(0) |
| problem.task_load = torch.ones(NT, dtype=torch.int32) |
| problem.task_group = torch.zeros(NT, dtype=torch.int32) |
| problem.task_demand = torch.ones(NT, dtype=torch.int32) |
|
|
| problem.worker_load_limit = torch.tensor(data["worker_load_limit"], dtype=torch.int32) |
| problem.worker_area_limit = torch.tensor(data["worker_area_limit"], dtype=torch.int32) |
| problem.worker_area_group_limit = torch.tensor(data["worker_area_group_limit"], dtype=torch.int32) |
|
|
| problem.features = features |
| problem.variables = variables |
| problem.constraint = Constraint |
| problem.objective = Objective |
|
|
| return problem |
|
|
|
|
| def make_problem(batch_count, batch_size=1, task_count=100): |
| assert batch_size == 1 |
|
|
| NT = task_count |
| problem_list = [] |
| for i in range(batch_count): |
| problem = Problem() |
| problem.id = i |
|
|
| device = Solver().device |
| p = torch.ones(NT, 1000, dtype=torch.float32, device=device) |
| problem.task_item_id = torch.multinomial(p, 10).to(torch.int32).cpu() |
| problem.task_item_owner_id = torch.multinomial(p, 10).to(torch.int32).cpu() |
| problem.task_item_num = torch.randint(0, 5, (NT, 10), dtype=torch.int32) |
| problem.task_area = torch.randint(0, 5, (NT, 10), dtype=torch.int32).clamp(0, 1) |
| problem.task_roadway = torch.randint(0, 5, (NT, 200), dtype=torch.int32).clamp(0, 1) |
| problem.task_area_group = torch.randint(0, 5, (NT, 10), dtype=torch.int32).clamp(0, 1) |
|
|
| problem.task_load = torch.ones(NT, dtype=torch.int32) |
| problem.task_group = torch.zeros(NT, dtype=torch.int32) |
| problem.task_demand = torch.ones(NT, dtype=torch.int32) |
|
|
| problem.worker_load_limit = torch.tensor([20], dtype=torch.int32) |
| problem.worker_area_limit = torch.tensor([10], dtype=torch.int32) |
| problem.worker_area_group_limit = torch.tensor([10], dtype=torch.int32) |
|
|
| problem.features = features |
| problem.variables = variables |
| problem.constraint = Constraint |
| problem.objective = Objective |
|
|
| problem_list.append(problem) |
|
|
| return problem_list |
|
|
|
|
| if __name__ == '__main__': |
| import sys |
| import os.path as osp |
| sys.path.append(osp.join(osp.dirname(__file__), '../')) |
| import runner |
|
|
| runner.run(make_problem) |
|
|