Exemplo n.º 1
0
    def update_input(self):
        logger.info(f"Start to update the input of {datetime.datetime.fromtimestamp(self.cur_time)}")

        # 获取车辆的位置信息和订单状态
        # Get the updated status of vehicles and orders according to the simulator
        self.vehicle_simulator.run(self.id_to_vehicle, self.pre_time)
        self.vehicle_simulator.parse_simulation_result(self.id_to_vehicle, self.cur_time)
        # 增加历史记录, add history
        self.history.add_history_of_vehicles(self.id_to_vehicle, self.cur_time)
        self.history.add_history_of_order_items(self.id_to_vehicle, self.cur_time)

        # 更新订单状态
        self.update_status_of_orders(self.vehicle_simulator.completed_item_ids, self.vehicle_simulator.ongoing_item_ids)

        # 更新车辆状态
        self.update_status_of_vehicles(self.vehicle_simulator.vehicle_id_to_cur_position_info,
                                       self.vehicle_simulator.vehicle_id_to_destination,
                                       self.vehicle_simulator.vehicle_id_to_carrying_items)

        # 根据当前时间选择待分配订单的物料集合
        # Select the item collection of the orders to be allocated according to the current time
        self.id_to_generated_order_item = get_order_items_to_be_dispatched_of_cur_time(self.id_to_order_item,
                                                                                       self.cur_time)

        # 汇总车辆、订单和路网信息, 作为派单算法的输入
        # create the input of algorithm
        updated_input_info = InputInfo(self.id_to_generated_order_item, self.id_to_ongoing_order_item,
                                       self.id_to_vehicle, self.id_to_factory, self.route_map)
        logger.info(f"Get {len(self.id_to_generated_order_item)} unallocated order items, "
                    f"{len(self.id_to_ongoing_order_item)} ongoing order items, "
                    f"{len(self.id_to_completed_order_item)} completed order items")

        return updated_input_info
Exemplo n.º 2
0
def __initial_position_of_vehicles(id_to_factory: dict, id_to_vehicle: dict,
                                   ini_time: int):
    factory_id_list = [*id_to_factory]
    random.seed(Configs.RANDOM_SEED)
    for vehicle_id, vehicle in id_to_vehicle.items():
        index = random.randint(0, len(factory_id_list) - 1)
        factory_id = factory_id_list[index]
        vehicle.set_cur_position_info(factory_id, ini_time, ini_time, ini_time)
        logger.info(f"Initial position of {vehicle_id} is {factory_id}")
Exemplo n.º 3
0
 def __contain_duplicate_nodes(route):
     node_id_list = []
     for node in route:
         if node.id not in node_id_list:
             node_id_list.append(node.id)
         else:
             logger.info(f"Duplicate node {node.id}")
             return True
     return False
Exemplo n.º 4
0
 def complete_the_dispatch_of_all_orders(self):
     for item in self.id_to_order_item.values():
         if item.delivery_state <= 1:
             logger.info(f"{datetime.datetime.fromtimestamp(self.cur_time)}, Item {item.id}: "
                         f"state = {item.delivery_state} < 2, we can not finish the simulation")
             return False
     logger.info(f"{datetime.datetime.fromtimestamp(self.cur_time)}, the status of all items is greater than 1, "
                 f"we could finish the simulation")
     return True
Exemplo n.º 5
0
def __initialize(factory_info_file_name: str, route_info_file_name: str,
                 instance_folder: str):
    """
    模拟器初始化, Initialize the simulator
    :param factory_info_file_name: 工厂数据文件名, name of the file containing information of factories
    :param route_info_file_name: 地图数据文件名, name of the file containing information of route map
    :param instance_folder: 测试例对应的文件夹, folder name of the instance
    :return: SimulateEnvironment
    """
    route_info_file_path = os.path.join(Configs.benchmark_folder_path,
                                        route_info_file_name)
    factory_info_file_path = os.path.join(Configs.benchmark_folder_path,
                                          factory_info_file_name)
    instance_folder_path = os.path.join(Configs.benchmark_folder_path,
                                        instance_folder)

    # 车辆数据文件名, name of the file containing information of vehicles
    vehicle_info_file_path = ""
    # 订单数据文件名, name of the file containing information of orders
    data_file_path = ""
    for file_name in os.listdir(instance_folder_path):
        if file_name.startswith("vehicle"):
            vehicle_info_file_path = os.path.join(instance_folder_path,
                                                  file_name)
        else:
            data_file_path = os.path.join(instance_folder_path, file_name)

    # 初始化时间, initial the start time of simulator
    now = datetime.datetime.now()
    initial_datetime = datetime.datetime(now.year, now.month, now.day)
    initial_time = int(time.mktime(initial_datetime.timetuple()))
    time_interval = Configs.ALG_RUN_FREQUENCY * 60
    logger.info(
        f"Start time of the simulator: {initial_datetime}, time interval: {time_interval: .2f}"
    )

    try:
        # 获取初始化数据, get the input
        id_to_order, id_to_vehicle, route_map, id_to_factory = get_initial_data(
            data_file_path, vehicle_info_file_path, route_info_file_path,
            factory_info_file_path, initial_time)
        # 初始化车辆位置, set the initial position of vehicles
        __initial_position_of_vehicles(id_to_factory, id_to_vehicle,
                                       initial_time)

        # return the instance of the object SimulateEnvironment
        return SimulateEnvironment(initial_time, time_interval, id_to_order,
                                   id_to_vehicle, id_to_factory, route_map)
    except Exception as exception:
        logger.error("Failed to read initial data")
        logger.error(f"Error: {exception}, {traceback.format_exc()}")
        return None
Exemplo n.º 6
0
def get_initial_data(data_file_path: str, vehicle_info_file_path: str,
                     route_info_file_path: str, factory_info_file_path: str,
                     initial_time: int):
    """
    获取模拟器的输入数据, get the input of simulator
    :param data_file_path: 订单数据文件路径, path of the file containing information of orders
    :param vehicle_info_file_path: 车辆数据文件路径,  path of the file containing information of vehicles
    :param route_info_file_path: 地图数据文件路径,  path of the file containing information of route map
    :param factory_info_file_path: 工厂数据文件路径,  path of the file containing information of factories
    :param initial_time: unix timestamp
    :return: id_to_order: dict, id_to_vehicle: dict, route_map, id_to_factory: dict
    """
    # 获取工厂信息, get the factories
    id_to_factory = get_factory_info(factory_info_file_path)
    logger.info(f"Get {len(id_to_factory)} factories")

    # 获取地图信息, get the route map containing distance and time matrix between factories
    code_to_route = get_route_map(route_info_file_path)
    logger.info(f"Get {len(code_to_route)} routes")
    route_map = Map(code_to_route)

    # 车辆基本信息, get the vehicles
    id_to_vehicle = get_vehicle_info(vehicle_info_file_path)
    logger.info(f"Get {len(id_to_vehicle)} vehicles")

    # 获取订单信息, get the orders
    id_to_order = get_order_info(data_file_path, initial_time)
    logger.info(f"Get {len(id_to_order)} orders")

    return id_to_order, id_to_vehicle, route_map, id_to_factory
Exemplo n.º 7
0
    def calculate_total_distance(vehicle_id_to_node_list: dict, route_map):
        total_distance = 0
        if not vehicle_id_to_node_list:
            return total_distance

        for vehicle_id, nodes in vehicle_id_to_node_list.items():
            travel_factory_list = []
            for node in nodes:
                travel_factory_list.append(node['factory_id'])
            distance = calculate_traveling_distance_of_routes(
                travel_factory_list, route_map)
            total_distance += distance
            logger.info(
                f"Traveling Distance of Vehicle {vehicle_id} is {distance: .3f}, "
                f"visited node list: {len(travel_factory_list)}")
        return total_distance
Exemplo n.º 8
0
    def run(self):
        used_seconds = 0
        # 迭代
        while True:
            logger.info(f"{'*' * 50}")

            # 确定当前时间, 取算法执行时间和模拟器的切片时间的大值
            self.cur_time = self.pre_time + (
                used_seconds // self.time_interval + 1) * self.time_interval
            logger.info(
                f"cur time: {datetime.datetime.fromtimestamp(self.cur_time)}, "
                f"pre time: {datetime.datetime.fromtimestamp(self.pre_time)}")

            # update the status of vehicles and orders in a given interval [self.pre_time, self.cur_time]
            updated_input_info = self.update_input()

            # 派单环节, 设计与算法交互
            used_seconds, dispatch_result = self.dispatch(updated_input_info)
            self.time_to_dispatch_result[self.cur_time] = dispatch_result

            # 校验, 车辆目的地不能改变
            if not Checker.check_dispatch_result(
                    dispatch_result, self.id_to_vehicle, self.id_to_order):
                logger.error("Dispatch result is infeasible")
                return

            # 根据派单指令更新车辆
            self.deliver_control_command_to_vehicles(dispatch_result)

            # 判断是否完成所有订单的派发
            if self.complete_the_dispatch_of_all_orders():
                break

            self.pre_time = self.cur_time

            # 若订单已经超时, 但是算法依旧未分配, 模拟终止
            if self.ignore_allocating_timeout_orders(dispatch_result):
                logger.error('Simulator terminated')
                sys.exit(-1)

        # 模拟完成车辆剩下的订单
        self.simulate_the_left_ongoing_orders_of_vehicles(self.id_to_vehicle)

        # 根据self.history 计算指标
        self.total_score = Evaluator.calculate_total_score(
            self.history, self.route_map, len(self.id_to_vehicle))
Exemplo n.º 9
0
 def calculate_total_score(history, route_map, vehicle_num: int):
     total_distance = Evaluator.calculate_total_distance(
         history.get_vehicle_position_history(), route_map)
     logger.info(f"Total distance: {total_distance: .3f}")
     total_over_time = Evaluator.calculate_total_over_time(
         history.get_order_item_status_history())
     logger.info(f"Sum over time: {total_over_time: .3f}")
     total_score = total_distance / vehicle_num + total_over_time * Configs.LAMDA
     logger.info(f"Total score: {total_score: .3f}")
     return total_score
Exemplo n.º 10
0
    # if you want to traverse all instances, set the selected_instances to []
    selected_instances = Configs.selected_instances

    if selected_instances:
        test_instances = selected_instances
    else:
        test_instances = Configs.all_test_instances

    score_list = []
    for idx in test_instances:
        # Initial the log
        log_file_name = f"dpdp_{datetime.datetime.now().strftime('%y%m%d%H%M%S')}.log"
        ini_logger(log_file_name)

        instance = "instance_%d" % idx
        logger.info(f"Start to run {instance}")

        try:
            score = simulate(Configs.factory_info_file,
                             Configs.route_info_file, instance)
            score_list.append(score)
        except Exception as e:
            logger.error("Failed to run simulator")
            logger.error(f"Error: {e}, {traceback.format_exc()}")

        # 删除日志句柄
        remove_file_handler_of_logging(log_file_name)

    avg_score = np.mean(score_list)
    # with report(True) as logs:
    #     logs.log_metrics('score', [avg_score])
Exemplo n.º 11
0
    # if you want to traverse all instances, set the selected_instances to []
    selected_instances = Configs.selected_instances

    if selected_instances:
        test_instances = selected_instances
    else:
        test_instances = Configs.all_test_instances

    score_list = []
    for idx in test_instances:
        # Initial the log
        log_file_name = f"dpdp_{datetime.datetime.now().strftime('%y%m%d%H%M%S')}.log"
        ini_logger(log_file_name)

        instance = "instance_%d" % idx
        logger.info(f"Start to run {instance}")

        try:
            score = simulate(Configs.factory_info_file, Configs.route_info_file, instance)
            score_list.append(score)
            logger.info(f"Score of {instance}: {score}")
        except Exception as e:
            logger.error("Failed to run simulator")
            logger.error(f"Error: {e}, {traceback.format_exc()}")
            score_list.append(sys.maxsize)

        # 删除日志句柄
        remove_file_handler_of_logging(log_file_name)

    avg_score = np.mean(score_list)
    # with report(True) as logs: