コード例 #1
0
    def get_position_info_of_vehicles(self, id_to_vehicle: dict, to_time: int):
        for vehicle_id, vehicle in id_to_vehicle.items():
            if len(vehicle.cur_factory_id
                   ) == 0 and vehicle.destination is None:
                logger.error(
                    f"Vehicle {vehicle_id}, the current position {vehicle.position_info.cur_factory_id}, "
                    f"the destination is None")
                continue

            node_list = self.get_node_list_of_vehicle(vehicle)

            cur_factory_id = ""
            arrive_time_at_current_factory = 0
            leave_time_at_current_factory = 0
            for node in node_list:
                if node.arr_time <= to_time <= node.leave_time:
                    cur_factory_id = node.id
                    arrive_time_at_current_factory = node.arr_time
                    leave_time_at_current_factory = node.leave_time

            if len(cur_factory_id) == 0 and node_list[-1].leave_time < to_time:
                cur_factory_id = node_list[-1].id
                arrive_time_at_current_factory = node_list[-1].arr_time
                leave_time_at_current_factory = max(node_list[-1].leave_time,
                                                    to_time)

            self.vehicle_id_to_cur_position_info[vehicle_id] = {
                "cur_factory_id": cur_factory_id,
                "arrive_time_at_current_factory":
                arrive_time_at_current_factory,
                "leave_time_at_current_factory": leave_time_at_current_factory,
                "update_time": to_time
            }
コード例 #2
0
    def dispatch(self, input_info):
        # 1. Prepare the input json of the algorithm
        convert_input_info_to_json_files(input_info)

        # 2. Run the algorithm
        command = get_algorithm_calling_command()
        time_start_algorithm = time.time()
        used_seconds, message = subprocess_function(command)

        # 3. parse the output json of the algorithm
        if Configs.ALGORITHM_SUCCESS_FLAG in message:
            if (time_start_algorithm < os.stat(
                    Configs.algorithm_output_destination_path).st_mtime <
                    time.time() and time_start_algorithm < os.stat(
                        Configs.algorithm_output_planned_route_path).st_mtime <
                    time.time()):
                vehicle_id_to_destination, vehicle_id_to_planned_route = get_output_of_algorithm(
                    self.id_to_order_item)
                dispatch_result = DispatchResult(vehicle_id_to_destination,
                                                 vehicle_id_to_planned_route)
                return used_seconds, dispatch_result
            else:
                logger.error('output.json is not the newest')
                sys.exit(-1)
        else:
            logger.error(message)
            raise ValueError('未寻获算法输出成功标识SUCCESS')
コード例 #3
0
    def __meet_order_splitting_constraint(dispatch_result, id_to_vehicle: dict, id_to_order: dict):
        vehicle_id_to_destination = dispatch_result.vehicle_id_to_destination
        vehicle_id_to_planned_route = dispatch_result.vehicle_id_to_planned_route

        vehicle_id_to_item_list = get_item_list_of_vehicles(dispatch_result, id_to_vehicle)

        capacity = 0
        split_order_id_list = Checker.__find_split_orders_from_vehicles(vehicle_id_to_item_list)

        for vehicle_id, vehicle in id_to_vehicle.items():
            logger.debug(f"Find split orders of vehicle {vehicle_id}")

            capacity = vehicle.board_capacity
            carrying_items = copy.deepcopy(vehicle.carrying_items)
            route = []
            if vehicle_id in vehicle_id_to_destination and vehicle_id_to_destination.get(vehicle_id) is not None:
                route.append(vehicle_id_to_destination.get(vehicle_id))
            if vehicle_id in vehicle_id_to_planned_route:
                route.extend(vehicle_id_to_planned_route.get(vehicle_id))
            split_order_id_list.extend(Checker.__find_split_orders_in_vehicle_routes(route, carrying_items))

        for order_id in split_order_id_list:
            if order_id in id_to_order:
                order = id_to_order.get(order_id)
                if order.demand <= capacity:
                    logger.error(f"order {order.id} demand: {order.demand} <= {capacity}, we can not split this order.")
                    return False
        return True
コード例 #4
0
    def get_position_info_of_vehicles(self, id_to_vehicle: dict, to_time: int):
        for vehicle_id, vehicle in id_to_vehicle.items():
            cur_factory_id = ""
            arrive_time_at_current_factory = 0
            leave_time_at_current_factory = 0

            # still in current position
            if len(vehicle.cur_factory_id) > 0:
                if vehicle.leave_time_at_current_factory >= to_time or vehicle.destination is None:
                    cur_factory_id = vehicle.cur_factory_id
                    arrive_time_at_current_factory = vehicle.arrive_time_at_current_factory
                    leave_time_at_current_factory = vehicle.leave_time_at_current_factory

            # in the following node
            if len(cur_factory_id) == 0:
                if vehicle.destination is None:
                    logger.error(
                        f"Vehicle {vehicle_id}, the current position {vehicle.position_info.cur_factory_id}, "
                        f"the destination is None")
                    continue

                if vehicle.destination.arrive_time > to_time:
                    cur_factory_id = ""
                elif vehicle.destination.leave_time > to_time:
                    cur_factory_id = vehicle.destination.id
                    arrive_time_at_current_factory = vehicle.destination.arrive_time
                    leave_time_at_current_factory = vehicle.destination.leave_time
                else:
                    if len(vehicle.planned_route) == 0:
                        cur_factory_id = vehicle.destination.id
                        arrive_time_at_current_factory = vehicle.destination.arrive_time
                        leave_time_at_current_factory = vehicle.destination.leave_time
                    else:
                        cur_factory_id = ""
                        for node in vehicle.planned_route:
                            if node.arrive_time <= to_time <= node.leave_time:
                                cur_factory_id = node.id
                                arrive_time_at_current_factory = node.arrive_time
                                leave_time_at_current_factory = node.leave_time
                                break

                        # Considering boundary conditions
                        if len(cur_factory_id) == 0 and vehicle.planned_route[
                                -1].leave_time < to_time:
                            cur_factory_id = vehicle.planned_route[-1].id
                            arrive_time_at_current_factory = vehicle.planned_route[
                                -1].arrive_time
                            leave_time_at_current_factory = vehicle.planned_route[
                                -1].leave_time

            self.vehicle_id_to_cur_position_info[vehicle_id] = {
                "cur_factory_id": cur_factory_id,
                "arrive_time_at_current_factory":
                arrive_time_at_current_factory,
                "leave_time_at_current_factory": leave_time_at_current_factory,
                "update_time": to_time
            }
コード例 #5
0
 def calculate_transport_time_between_factories(self, src_factory_id,
                                                dest_factory_id):
     if src_factory_id == dest_factory_id:
         return 0
     if (src_factory_id, dest_factory_id) in self.__factory_id_pair_to_time:
         return self.__factory_id_pair_to_time.get(
             (src_factory_id, dest_factory_id))
     else:
         logger.error(
             f"({src_factory_id}, {dest_factory_id}) is not in time matrix")
         return sys.maxsize
コード例 #6
0
def __get_delivery_factory_id(items):
    if len(items) == 0:
        logger.error("Length of items is 0")
        return ""

    factory_id = items[0].delivery_factory_id
    for item in items:
        if item.delivery_factory_id != factory_id:
            logger.error("The delivery factory of these items is not the same")
            return ""

    return factory_id
コード例 #7
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
コード例 #8
0
def subprocess_function(cmd):
    # 开启子进程,并连接到它们的输入/输出/错误管道,获取返回值
    sub_process = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
    try:
        start_time = time.time()
        # 设置超时
        sub_process.wait(Configs.MAX_RUNTIME_OF_ALGORITHM)
        end_time = time.time()
        # 返回算法运行时间和算法返回值
        return end_time - start_time, sub_process.stdout.read().decode()
    except Exception as e:
        logger.error(e)
        sys.exit(-1)
コード例 #9
0
    def calculate_total_over_time(item_id_to_status_list: dict):
        total_over_time = 0

        order_id_to_item_id_list = {}
        item_id_to_complete_time = {}
        order_id_to_committed_completion_time = {}
        failure_flag = False
        for item_id, status_info_list in item_id_to_status_list.items():
            selected_status_info_list = [
                status_info for status_info in status_info_list
                if status_info["state"] == Configs.ORDER_STATUS_TO_CODE.get(
                    "COMPLETED")
            ]

            if len(selected_status_info_list) == 0:
                logger.error(
                    f"Item {item_id} has no history of completion status")
                failure_flag = True
                continue

            selected_status_info_list.sort(key=lambda x: x["update_time"])
            item_id_to_complete_time[item_id] = selected_status_info_list[
                0].get("update_time")

            order_id = selected_status_info_list[0].get("order_id")
            if order_id not in order_id_to_item_id_list:
                order_id_to_item_id_list[order_id] = []
            order_id_to_item_id_list[order_id].append(item_id)
            if order_id not in order_id_to_committed_completion_time:
                order_id_to_committed_completion_time[
                    order_id] = selected_status_info_list[0].get(
                        "committed_completion_time")

        if failure_flag:
            return sys.maxsize

        for order_id, item_id_list in order_id_to_item_id_list.items():
            latest_arr_time = -1
            for item_id in item_id_list:
                if item_id in item_id_to_complete_time:
                    completion_time = item_id_to_complete_time.get(item_id)
                    if completion_time > latest_arr_time:
                        latest_arr_time = completion_time

            committed_completion_time = order_id_to_committed_completion_time.get(
                order_id)
            over_time = latest_arr_time - committed_completion_time
            if over_time > 0:
                total_over_time += over_time

        return total_over_time
コード例 #10
0
ファイル: checker.py プロジェクト: huawei-noah/xingtian
    def __is_returned_destination_valid(returned_destination, vehicle):
        origin_destination = vehicle.destination
        if origin_destination is not None:
            if returned_destination is None:
                logger.error(
                    f"Vehicle {vehicle.id}, returned destination is None, "
                    f"however the origin destination is not None.")
                return False
            else:
                if origin_destination.id != returned_destination.id:
                    logger.error(
                        f"Vehicle {vehicle.id}, returned destination id is {returned_destination.id}, "
                        f"however the origin destination id is {origin_destination.id}."
                    )
                    return False

                if origin_destination.arrive_time != returned_destination.arrive_time:
                    logger.error(
                        f"Vehicle {vehicle.id}, arrive time of returned destination is "
                        f"{returned_destination.arrive_time}, "
                        f"however the arrive time of origin destination is "
                        f"{origin_destination.arrive_time}.")
                    return False
        elif len(vehicle.cur_factory_id) == 0 and returned_destination is None:
            logger.error(
                f"Currently, Vehicle {vehicle.id} is not in the factory(cur_factory_id==''), "
                f"however, returned destination is also None, we cannot locate the vehicle."
            )
            return False

        return True
コード例 #11
0
    def ignore_allocating_timeout_orders(self, dispatch_result):
        vehicle_id_to_item_list = get_item_list_of_vehicles(dispatch_result, self.id_to_vehicle)
        total_item_ids_in_dispatch_result = []
        for vehicle_id, item_list in vehicle_id_to_item_list.items():
            for item in item_list:
                if item.id not in total_item_ids_in_dispatch_result:
                    total_item_ids_in_dispatch_result.append(item.id)

        for item_id, item in self.id_to_generated_order_item.items():
            if item_id not in total_item_ids_in_dispatch_result:
                if item.committed_completion_time < self.cur_time:
                    logger.error(f"{datetime.datetime.fromtimestamp(self.cur_time)}, Item {item_id} has timed out, "
                                 f"however it is still ignored in the dispatch result")
                    return True
        return False
コード例 #12
0
ファイル: checker.py プロジェクト: shishouyuan/xingtian
 def __do_pickup_and_delivery_items_match_the_node(route: list):
     for node in route:
         factory_id = node.id
         pickup_items = node.pickup_items
         for item in pickup_items:
             if item.pickup_factory_id != factory_id:
                 logger.error(f"Pickup factory of item {item.id} is {item.pickup_factory_id}, "
                              f"however you allocate the vehicle to pickup this item in {factory_id}")
                 return False
         delivery_items = node.delivery_items
         for item in delivery_items:
             if item.delivery_factory_id != factory_id:
                 logger.error(f"Delivery factory of item {item.id} is {item.delivery_factory_id}, "
                              f"however you allocate the vehicle to delivery this item in {factory_id}")
                 return False
     return True
コード例 #13
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))
コード例 #14
0
    def deliver_control_command_to_vehicles(self, dispatch_result):
        vehicle_id_to_destination = dispatch_result.vehicle_id_to_destination
        vehicle_id_to_planned_route = dispatch_result.vehicle_id_to_planned_route

        for vehicle_id, vehicle in self.id_to_vehicle.items():
            if vehicle_id not in vehicle_id_to_destination:
                logger.error(f"algorithm does not output the destination of vehicle {vehicle_id}")
                continue
            if vehicle_id not in vehicle_id_to_planned_route:
                logger.error(f"algorithm does not output the planned route of vehicle {vehicle_id}")
                continue
            vehicle.destination = vehicle_id_to_destination.get(vehicle_id)
            if vehicle.destination is not None:
                vehicle.destination.update_service_time()
            vehicle.planned_route = vehicle_id_to_planned_route.get(vehicle_id)
            for node in vehicle.planned_route:
                if node is not None:
                    node.update_service_time()
コード例 #15
0
ファイル: checker.py プロジェクト: huawei-noah/xingtian
    def __contain_duplicate_items(route, carrying_items):
        item_id_list = []
        while not carrying_items.is_empty():
            item = carrying_items.pop()
            if item.id not in item_id_list:
                item_id_list.append(item.id)
            else:
                logger.error(f"Item {item.id}: duplicate item id")
                return True

        for node in route:
            pickup_items = node.pickup_items
            for item in pickup_items:
                if item.id not in item_id_list:
                    item_id_list.append(item.id)
                else:
                    logger.error(f"Item {item.id}: duplicate item id")
                    return True
        return False
コード例 #16
0
ファイル: json_tools.py プロジェクト: huawei-noah/xingtian
def get_algorithm_calling_command():
    files = os.listdir(Configs.root_folder_path)
    for file in files:
        # 调度算法的入口文件必须以main_algorithm开头
        if file.startswith(Configs.ALGORITHM_ENTRY_FILE_NAME):
            end_name = file.split('.')[-1]
            algorithm_language = Configs.ALGORITHM_LANGUAGE_MAP.get(end_name)
            if algorithm_language == 'python':
                return 'python {}'.format(file)
            elif algorithm_language == 'java':
                return 'java {}'.format(file.split('.')[0])
            # c和c++调用方式一样,但系统不同调用方式有异
            elif algorithm_language == 'c':
                system = platform.system()
                if system == 'Windows':
                    return file
                elif system == 'Linux':
                    os.system(f'chmod 777 {file}')
                    return './{}'.format(file)
    logger.error('Can not find main_algorithm file.')
    sys.exit(-1)
コード例 #17
0
    def update_status_of_vehicles(self, vehicle_id_to_cur_position_info,
                                  vehicle_id_to_destination,
                                  vehicle_id_to_carry_items):
        for vehicle_id, vehicle in self.id_to_vehicle.items():
            if vehicle_id in vehicle_id_to_cur_position_info:
                cur_position_info = vehicle_id_to_cur_position_info.get(
                    vehicle_id)
                vehicle.set_cur_position_info(
                    cur_position_info.get("cur_factory_id"),
                    cur_position_info.get("update_time"),
                    cur_position_info.get("arrive_time_at_current_factory"),
                    cur_position_info.get("leave_time_at_current_factory"))
            else:
                logger.error(
                    f"Vehicle {vehicle_id} does not have updated position information"
                )

            if vehicle_id in vehicle_id_to_destination:
                vehicle.destination = vehicle_id_to_destination.get(vehicle_id)
            else:
                logger.error(
                    f"Vehicle {vehicle_id} does not have the destination information"
                )

            if vehicle_id in vehicle_id_to_carry_items:
                vehicle.carrying_items = vehicle_id_to_carry_items.get(
                    vehicle_id)
            else:
                logger.error(
                    f"Vehicle {vehicle_id} does not have the information of carrying items"
                )

            vehicle.planned_route = []
コード例 #18
0
ファイル: checker.py プロジェクト: huawei-noah/xingtian
    def __meet_capacity_constraint(route: list, carrying_items, capacity):
        left_capacity = capacity

        # Stack
        while not carrying_items.is_empty():
            item = carrying_items.pop()
            left_capacity -= item.demand
            if left_capacity < 0:
                logger.error(f"left capacity {left_capacity} < 0")
                return False

        for node in route:
            delivery_items = node.delivery_items
            pickup_items = node.pickup_items
            for item in delivery_items:
                left_capacity += item.demand
                if left_capacity > capacity:
                    logger.error(
                        f"left capacity {left_capacity} > capacity {capacity}")
                    return False

            for item in pickup_items:
                left_capacity -= item.demand
                if left_capacity < 0:
                    logger.error(f"left capacity {left_capacity} < 0")
                    return False
        return True
コード例 #19
0
    def check_dispatch_result(dispatch_result, id_to_vehicle: dict, id_to_order: dict):
        vehicle_id_to_destination = dispatch_result.vehicle_id_to_destination
        vehicle_id_to_planned_route = dispatch_result.vehicle_id_to_planned_route

        # 检查是否所有的车辆都有返回值
        if len(vehicle_id_to_destination) != len(id_to_vehicle):
            logger.error(f"Num of returned destination {len(vehicle_id_to_destination)} "
                         f"is not equal to vehicle number {len(id_to_vehicle)}")
            return False

        if len(vehicle_id_to_planned_route) != len(id_to_vehicle):
            logger.error(f"Num of returned planned route {len(vehicle_id_to_planned_route)} "
                         f"is not equal to vehicle number {len(id_to_vehicle)}")
            return False

        # 逐个检查各车辆路径
        for vehicle_id, vehicle in id_to_vehicle.items():
            if vehicle_id not in vehicle_id_to_destination:
                logger.error(f"Destination information of Vehicle {vehicle_id} is not in the returned result")
                return False

            # check destination
            destination_in_result = vehicle_id_to_destination.get(vehicle_id)
            origin_destination = vehicle.destination
            if origin_destination is not None:
                if destination_in_result is None:
                    logger.error(f"Vehicle {vehicle_id}, returned destination is None, "
                                 f"however the origin destination is not None.")
                    return False
                else:
                    if origin_destination.id != destination_in_result.id:
                        logger.error(f"Vehicle {vehicle_id}, returned destination id is {destination_in_result.id}, "
                                     f"however the origin destination id is {origin_destination.id}.")
                        return False

                    if origin_destination.arrive_time != destination_in_result.arrive_time:
                        logger.error(f"Vehicle {vehicle_id}, arrive time of returned destination is "
                                     f"{destination_in_result.arrive_time}, "
                                     f"however the arrive time of origin destination is "
                                     f"{origin_destination.arrive_time}.")
                        return False

            # check routes
            if vehicle_id not in vehicle_id_to_planned_route:
                logger.error(f"Planned route of Vehicle {vehicle_id} is not in the returned result")
                return False

            route = []
            if destination_in_result is not None:
                route.append(destination_in_result)
            route.extend(vehicle_id_to_planned_route.get(vehicle_id))

            if len(route) > 0:
                # check capacity
                if not Checker.__meet_capacity_constraint(route, copy.deepcopy(vehicle.carrying_items),
                                                          vehicle.board_capacity):
                    logger.error(f"Vehicle {vehicle_id} violates the capacity constraint")
                    return False

                # check LIFO
                if not Checker.__meet_loading_and_unloading_constraint(route, copy.deepcopy(vehicle.carrying_items)):
                    logger.error(f"Vehicle {vehicle_id} violates the LIFO constraint")
                    return False

                # # check duplicated node id
                # if Checker.contain_duplicate_nodes(complete_route):
                #     return False

                # check duplicated item id
                if Checker.__contain_duplicate_items(route, copy.deepcopy(vehicle.carrying_items)):
                    return False

        # check order splitting
        if not Checker.__meet_order_splitting_constraint(dispatch_result, id_to_vehicle, id_to_order):
            return False

        return True
コード例 #20
0
    def work(self, vehicle):
        cur_factory_id = vehicle.cur_factory_id
        # 当前在工厂: 1. 还处于装卸过程(占用货口资源); 2. 停车状态(不占用货口资源)
        if len(cur_factory_id) > 0:
            # 1.还处于装卸过程(占用货口资源);
            if vehicle.leave_time_at_current_factory > self.env.now:
                resource = self.factory_id_to_dock_resource.get(cur_factory_id)
                with resource.request() as req:
                    yield req
                    yield self.env.timeout(vehicle.leave_time_at_current_factory - self.env.now)

            # 2. 停车状态(不占用货口资源)
            else:
                vehicle.leave_time_at_current_factory = self.env.now

        if vehicle.destination is None:
            if len(cur_factory_id) == 0:
                logger.error(f"Vehicle {vehicle.id}: both the current factory and the destination are None!!!")
            return

        if len(cur_factory_id) > 0:
            next_factory_id = vehicle.destination.id
            transport_time = self.route_map.calculate_transport_time_between_factories(cur_factory_id, next_factory_id)
            yield self.env.timeout(transport_time)
        else:
            # driving towards destination
            arr_time = vehicle.destination.arrive_time
            if arr_time >= self.env.now:
                yield self.env.timeout(arr_time - self.env.now)
            else:
                logger.error(f"Vehicle {vehicle.id} is driving toward the destination, "
                             f"however current time {datetime.datetime.fromtimestamp(self.env.now)} is greater than "
                             f"the arrival time {datetime.datetime.fromtimestamp(arr_time)} of destination!!!")

        vehicle.destination.arrive_time = self.env.now
        service_time = vehicle.destination.service_time
        cur_factory_id = vehicle.destination.id
        resource = self.factory_id_to_dock_resource.get(cur_factory_id)
        with resource.request() as req:
            yield req
            yield self.env.timeout(service_time + Configs.DOCK_APPROACHING_TIME)
        vehicle.destination.leave_time = self.env.now

        # driving towards the left nodes
        for node in vehicle.planned_route:
            next_factory_id = node.id

            # 计算运输时间
            transport_time = self.route_map.calculate_transport_time_between_factories(cur_factory_id, next_factory_id)
            yield self.env.timeout(transport_time)

            # 计算服务时间
            arr_time = self.env.now
            service_time = node.service_time
            resource = self.factory_id_to_dock_resource.get(next_factory_id)
            with resource.request() as req:
                yield req
                yield self.env.timeout(service_time + Configs.DOCK_APPROACHING_TIME)
            leave_time = self.env.now

            node.arrive_time = arr_time
            node.leave_time = leave_time
            cur_factory_id = next_factory_id
コード例 #21
0
ファイル: main.py プロジェクト: Shawn-nau/xingtian
        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])
    print(score_list)
    print(avg_score)
    print("Happy Ending")
コード例 #22
0
ファイル: checker.py プロジェクト: huawei-noah/xingtian
    def check_dispatch_result(dispatch_result, id_to_vehicle: dict,
                              id_to_order: dict):
        vehicle_id_to_destination = dispatch_result.vehicle_id_to_destination
        vehicle_id_to_planned_route = dispatch_result.vehicle_id_to_planned_route

        # 检查是否所有的车辆都有返回值
        if len(vehicle_id_to_destination) != len(id_to_vehicle):
            logger.error(
                f"Num of returned destination {len(vehicle_id_to_destination)} "
                f"is not equal to vehicle number {len(id_to_vehicle)}")
            return False

        if len(vehicle_id_to_planned_route) != len(id_to_vehicle):
            logger.error(
                f"Num of returned planned route {len(vehicle_id_to_planned_route)} "
                f"is not equal to vehicle number {len(id_to_vehicle)}")
            return False

        # 逐个检查各车辆路径
        for vehicle_id, vehicle in id_to_vehicle.items():
            if vehicle_id not in vehicle_id_to_destination:
                logger.error(
                    f"Destination information of Vehicle {vehicle_id} is not in the returned result"
                )
                return False

            # check destination
            destination_in_result = vehicle_id_to_destination.get(vehicle_id)
            if not Checker.__is_returned_destination_valid(
                    destination_in_result, vehicle):
                logger.error(
                    f"Returned destination of Vehicle {vehicle_id} is not valid"
                )
                return False

            # check routes
            if vehicle_id not in vehicle_id_to_planned_route:
                logger.error(
                    f"Planned route of Vehicle {vehicle_id} is not in the returned result"
                )
                return False

            route = []
            if destination_in_result is not None:
                route.append(destination_in_result)
            route.extend(vehicle_id_to_planned_route.get(vehicle_id))

            if len(route) > 0:
                # check capacity
                if not Checker.__meet_capacity_constraint(
                        route, copy.deepcopy(vehicle.carrying_items),
                        vehicle.board_capacity):
                    logger.error(
                        f"Vehicle {vehicle_id} violates the capacity constraint"
                    )
                    return False

                # check LIFO
                if not Checker.__meet_loading_and_unloading_constraint(
                        route, copy.deepcopy(vehicle.carrying_items)):
                    logger.error(
                        f"Vehicle {vehicle_id} violates the LIFO constraint")
                    return False

                # check adjacent-duplicated nodes
                Checker.__contain_duplicated_nodes(vehicle_id, route)

                # check duplicated item id
                if Checker.__contain_duplicate_items(
                        route, copy.deepcopy(vehicle.carrying_items)):
                    return False

                if not Checker.__do_pickup_and_delivery_items_match_the_node(
                        route):
                    return False

        # check order splitting
        if not Checker.__meet_order_splitting_constraint(
                dispatch_result, id_to_vehicle, id_to_order):
            return False

        return True
コード例 #23
0
def dispatch_orders_to_vehicles(id_to_unallocated_order_item: dict,
                                id_to_vehicle: dict, id_to_factory: dict):
    """
    :param id_to_unallocated_order_item: item_id ——> OrderItem object(state: "GENERATED")
    :param id_to_vehicle: vehicle_id ——> Vehicle object
    :param id_to_factory: factory_id ——> factory object
    """
    vehicle_id_to_destination = {}
    vehicle_id_to_planned_route = {}

    # dealing with the carrying items of vehicles (处理车辆身上已经装载的货物)
    for vehicle_id, vehicle in id_to_vehicle.items():
        unloading_sequence_of_items = vehicle.get_unloading_sequence()
        vehicle_id_to_planned_route[vehicle_id] = []
        if len(unloading_sequence_of_items) > 0:
            delivery_item_list = []
            factory_id = unloading_sequence_of_items[0].delivery_factory_id
            for item in unloading_sequence_of_items:
                if item.delivery_factory_id == factory_id:
                    delivery_item_list.append(item)
                else:
                    factory = id_to_factory.get(factory_id)
                    node = Node(factory_id, factory.lng, factory.lat, [],
                                copy.copy(delivery_item_list))
                    vehicle_id_to_planned_route[vehicle_id].append(node)
                    delivery_item_list = [item]
                    factory_id = item.delivery_factory_id
            if len(delivery_item_list) > 0:
                factory = id_to_factory.get(factory_id)
                node = Node(factory_id, factory.lng, factory.lat, [],
                            copy.copy(delivery_item_list))
                vehicle_id_to_planned_route[vehicle_id].append(node)

    # for the empty vehicle, it has been allocated to the order, but have not yet arrived at the pickup factory
    pre_matching_item_ids = []
    for vehicle_id, vehicle in id_to_vehicle.items():
        if vehicle.carrying_items.is_empty(
        ) and vehicle.destination is not None:
            pickup_items = vehicle.destination.pickup_items
            pickup_node, delivery_node = __create_pickup_and_delivery_nodes_of_items(
                pickup_items, id_to_factory)
            vehicle_id_to_planned_route[vehicle_id].append(pickup_node)
            vehicle_id_to_planned_route[vehicle_id].append(delivery_node)
            pre_matching_item_ids.extend([item.id for item in pickup_items])

    # dispatch unallocated orders to vehicles
    capacity = __get_capacity_of_vehicle(id_to_vehicle)

    order_id_to_items = {}
    for item_id, item in id_to_unallocated_order_item.items():
        if item_id in pre_matching_item_ids:
            continue
        order_id = item.order_id
        if order_id not in order_id_to_items:
            order_id_to_items[order_id] = []
        order_id_to_items[order_id].append(item)

    vehicle_index = 0
    vehicles = [vehicle for vehicle in id_to_vehicle.values()]
    for order_id, items in order_id_to_items.items():
        demand = __calculate_demand(items)
        if demand > capacity:
            cur_demand = 0
            tmp_items = []
            for item in items:
                if cur_demand + item.demand > capacity:
                    pickup_node, delivery_node = __create_pickup_and_delivery_nodes_of_items(
                        tmp_items, id_to_factory)
                    if pickup_node is None or delivery_node is None:
                        continue
                    vehicle = vehicles[vehicle_index]
                    vehicle_id_to_planned_route[vehicle.id].append(pickup_node)
                    vehicle_id_to_planned_route[vehicle.id].append(
                        delivery_node)

                    vehicle_index = (vehicle_index + 1) % len(vehicles)
                    tmp_items = []
                    cur_demand = 0

                tmp_items.append(item)
                cur_demand += item.demand

            if len(tmp_items) > 0:
                pickup_node, delivery_node = __create_pickup_and_delivery_nodes_of_items(
                    tmp_items, id_to_factory)
                if pickup_node is None or delivery_node is None:
                    continue
                vehicle = vehicles[vehicle_index]
                vehicle_id_to_planned_route[vehicle.id].append(pickup_node)
                vehicle_id_to_planned_route[vehicle.id].append(delivery_node)
        else:
            pickup_node, delivery_node = __create_pickup_and_delivery_nodes_of_items(
                items, id_to_factory)
            if pickup_node is None or delivery_node is None:
                continue
            vehicle = vehicles[vehicle_index]
            vehicle_id_to_planned_route[vehicle.id].append(pickup_node)
            vehicle_id_to_planned_route[vehicle.id].append(delivery_node)

        vehicle_index = (vehicle_index + 1) % len(vehicles)

    # create the output of the algorithm
    for vehicle_id, vehicle in id_to_vehicle.items():
        origin_planned_route = vehicle_id_to_planned_route.get(vehicle_id)

        destination = None
        planned_route = []
        # determine the destination
        if vehicle.destination is not None:
            if len(origin_planned_route) == 0:
                logger.error(f"Planned route of vehicle {vehicle_id} is wrong")
            else:
                destination = origin_planned_route[0]
                destination.arrive_time = vehicle.destination.arrive_time
                planned_route = [
                    origin_planned_route[i]
                    for i in range(1, len(origin_planned_route))
                ]
        elif len(origin_planned_route) > 0:
            destination = origin_planned_route[0]
            planned_route = [
                origin_planned_route[i]
                for i in range(1, len(origin_planned_route))
            ]

        vehicle_id_to_destination[vehicle_id] = destination
        vehicle_id_to_planned_route[vehicle_id] = planned_route

    return vehicle_id_to_destination, vehicle_id_to_planned_route
コード例 #24
0
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE

import traceback

from src.utils.logging_engine import logger
from algorithm.algorithm_demo import scheduling

if __name__ == '__main__':
    try:
        scheduling()
        print("SUCCESS")
    except Exception as e:
        logger.error("Failed to run algorithm")
        logger.error(f"Error: {e}, {traceback.format_exc()}")
        print("FAIL")