Exemple #1
0
    def test_dispatch_twice(self, mock_uniformgenerator):
        """
        no target, dispatch (3, 1) first, then (8, -1)
        decelerate then accelerate
        not accelerate immediately
        """
        max_floors = 8
        # mansion_config
        world = MansionConfig(dt=0.50,
                              number_of_floors=max_floors,
                              floor_height=4.0)

        # test_elevator
        test_elevator = Elevator(start_position=0.0,
                                 mansion_config=world,
                                 name="test_elevator")
        test_elevator._direction = 1
        test_elevator._current_velocity = 2.0
        test_elevator._current_position = 9.0
        test_elevator._target_floors = list()
        test_elevator._loaded_person = [
            list() for i in range(test_elevator._number_of_floors)
        ]
        test_elevator._load_weight = 0

        # mansion
        tmp_uniform_generator = UniformPersonGenerator()
        ret_person = []
        person_generators.uniform_generator.UniformPersonGenerator.generate_person = mock.Mock(
            return_value=(ret_person))
        test_mansion = MansionManager(elevator_number=1,
                                      person_generator=tmp_uniform_generator,
                                      mansion_config=world,
                                      name="test_mansion")
        test_mansion._elevators = [test_elevator]
        # first, dispatch to 8 floor
        dispatch = []
        dispatch.append(ElevatorAction(4, 1))
        test_mansion.run_mansion(dispatch)
        test_mansion.run_mansion(dispatch)
        test_mansion.run_mansion(dispatch)
        dispatch = []
        dispatch.append(ElevatorAction(8, -1))
        test_mansion.run_mansion(dispatch)  # accelerate at once
        test_mansion.run_mansion(dispatch)
        state = test_mansion.state
        self.assertAlmostEqual(state.ElevatorStates[0].Velocity, 2.0)
Exemple #2
0
    def test_dispatch_invalid(self, mock_uniformgenerator):
        """
        ignore the invalid dispatch (cannot stop at the dispatch)
        and decelerate when needed (test velocity_planner)
        """
        max_floors = 8
        # mansion_config
        world = MansionConfig(dt=0.50,
                              number_of_floors=max_floors,
                              floor_height=4.0)

        # test_elevator
        test_elevator = Elevator(start_position=0.0,
                                 mansion_config=world,
                                 name="test_eleavtor")
        test_elevator._direction = 1
        test_elevator._current_velocity = 2.0
        test_elevator._current_position = 8.0  # currently at 3 floor
        test_elevator._target_floors = [5, 8]  # target 5 floor
        test_elevator._loaded_person = [
            list() for i in range(test_elevator._number_of_floors)
        ]
        test_elevator._loaded_person[4].append(
            PersonType(6, 40, 1, 5, world.raw_time))
        test_elevator._loaded_person[7].append(
            PersonType(7, 40, 1, 8, world.raw_time))
        test_elevator._load_weight = 80

        # test_mansion
        tmp_uniform_generator = UniformPersonGenerator()

        ret_person = []
        person_generators.uniform_generator.UniformPersonGenerator.generate_person = mock.Mock(
            return_value=(ret_person))

        test_mansion = MansionManager(elevator_number=1,
                                      person_generator=tmp_uniform_generator,
                                      mansion_config=world,
                                      name="test_mansion")
        test_mansion._elevators = [test_elevator]
        dispatch = []
        dispatch.append(ElevatorAction(3, 1))

        test_mansion.run_mansion(dispatch)
        state = test_mansion.state
        self.assertAlmostEqual(state.ElevatorStates[0].Velocity, 2.0)

        test_mansion.run_mansion(dispatch)
        state = test_mansion.state
        self.assertAlmostEqual(state.ElevatorStates[0].Velocity,
                               2.0)  # ignore the invalid dispatch

        for i in range(5):
            test_mansion.run_mansion(dispatch)
        test_mansion.run_mansion(dispatch)
        test_mansion.run_mansion(dispatch)
        test_mansion.run_mansion(dispatch)
        state = test_mansion.state
        self.assertAlmostEqual(state.ElevatorStates[0].Velocity, 0.0)
Exemple #3
0
    def test_cancel_dispatch(self, mock_uniformgenerator):
        """
        no target, dispatch first, accelerate, then cancel dispatch, decelerate
        """
        max_floors = 8
        # mansion_config
        world = MansionConfig(dt=0.50,
                              number_of_floors=max_floors,
                              floor_height=4.0)

        # test_elevator
        test_elevator = Elevator(start_position=0.0,
                                 mansion_config=world,
                                 name="test_elevator")
        test_elevator._direction = 0
        test_elevator._current_velocity = 0.0
        test_elevator._current_position = 8.0
        test_elevator._target_floors = list()
        test_elevator._loaded_person = [
            list() for i in range(test_elevator._number_of_floors)
        ]
        test_elevator._load_weight = 0

        # mansion
        tmp_uniform_generator = UniformPersonGenerator()
        ret_person = []
        person_generators.uniform_generator.UniformPersonGenerator.generate_person = mock.Mock(
            return_value=(ret_person))
        test_mansion = MansionManager(elevator_number=1,
                                      person_generator=tmp_uniform_generator,
                                      mansion_config=world,
                                      name="test_mansion")
        test_mansion._elevators = [test_elevator]
        dispatch = []
        dispatch.append(ElevatorAction(6, 1))
        test_mansion.run_mansion(dispatch)
        test_mansion.run_mansion(dispatch)  # t = 1.0
        dispatch = []
        dispatch.append(ElevatorAction(0, -1))
        for i in range(10):
            test_mansion.run_mansion(dispatch)

        state = test_mansion.state
        self.assertAlmostEqual(state.ElevatorStates[0].DoorState, 0.0)
        self.assertAlmostEqual(state.ElevatorStates[0].Velocity, 0.0)
Exemple #4
0
    def test_no_dispatch(self, mock_uniformgenerator):
        """
        arrive at the target, no dispatch, hold still
        """
        max_floors = 8
        # mansion_config
        world = MansionConfig(dt=0.50,
                              number_of_floors=max_floors,
                              floor_height=4.0)

        # test_elevator
        test_elevator = Elevator(start_position=0.0,
                                 mansion_config=world,
                                 name="test_eleavtor")
        test_elevator._direction = 1
        test_elevator._current_velocity = 0
        test_elevator._current_position = 8.0  # currently at 3 floor
        test_elevator._target_floors = [3]  # target 3 floor
        test_elevator._loaded_person = [
            list() for i in range(test_elevator._number_of_floors)
        ]
        test_elevator._loaded_person[2].append(
            PersonType(0, 40, 1, 3, world.raw_time))
        test_elevator._load_weight = 40

        # test_mansion
        tmp_uniform_generator = UniformPersonGenerator()

        ret_person = []
        person_generators.uniform_generator.UniformPersonGenerator.generate_person = mock.Mock(
            return_value=(ret_person))

        test_mansion = MansionManager(elevator_number=1,
                                      person_generator=tmp_uniform_generator,
                                      mansion_config=world,
                                      name="test_mansion")
        test_mansion._elevators = [test_elevator]
        dispatch = []
        dispatch.append(ElevatorAction(-1, 0))

        test_mansion.run_mansion(dispatch)
        test_mansion.run_mansion(dispatch)  # open the door

        for i in range(4):
            test_mansion.run_mansion(dispatch)  # unload person 0

        test_mansion.run_mansion(dispatch)
        test_mansion.run_mansion(dispatch)  # close the door

        test_mansion.run_mansion(dispatch)
        test_mansion.run_mansion(dispatch)
        state = test_mansion.state
        self.assertAlmostEqual(state.ElevatorStates[0].DoorState, 0.0)
        self.assertAlmostEqual(state.ElevatorStates[0].Velocity, 0.0)
        self.assertAlmostEqual(state.ElevatorStates[0].Floor, 3.0)
        self.assertAlmostEqual(state.ElevatorStates[0].Direction, 0)
Exemple #5
0
 def step(self, action):
     assert type(action) is list, "Type of action should be list"
     assert len(action) == self._mansion.attribute.ElevatorNumber*2, \
         "Action is supposed to be a list with length ElevatorNumber * 2"
     action_tuple = []
     for i in range(self._mansion.attribute.ElevatorNumber):
         action_tuple.append(ElevatorAction(action[i*2], action[i*2+1]))
     time_consume, energy_consume, given_up_persons = self._mansion.run_mansion(action_tuple)
     reward = - (time_consume + 5e-4 * energy_consume +
                 300 * given_up_persons) * 1.0e-4
     info = {'time_consume':time_consume, 'energy_consume':energy_consume, 'given_up_persons': given_up_persons}
     return (self._mansion.state, reward, False, info)
Exemple #6
0
    def test_set_direction_0(self, mock_uniformgenerator):
        """
        When the elevator is stopped and empty, always set direction as 0 first, 
        then set as dispatch_target_direction
        """
        max_floors = 8
        # mansion_config
        world = MansionConfig(dt=0.50,
                              number_of_floors=max_floors,
                              floor_height=4.0)

        # test_elevator
        test_elevator = Elevator(start_position=0.0,
                                 mansion_config=world,
                                 name="test_elevator")
        test_elevator._direction = 1
        test_elevator._current_velocity = 0.0
        test_elevator._current_position = 8.0  # 3rd floor
        test_elevator._target_floors = list()
        test_elevator._loaded_person = [
            list() for i in range(test_elevator._number_of_floors)
        ]
        test_elevator._load_weight = 0

        # mansion
        tmp_uniform_generator = UniformPersonGenerator()
        ret_person = []
        ret_person.append(PersonType(0, 50, 3, 1, world.raw_time))
        person_generators.uniform_generator.UniformPersonGenerator.generate_person = mock.Mock(
            return_value=(ret_person))
        test_mansion = MansionManager(elevator_number=1,
                                      person_generator=tmp_uniform_generator,
                                      mansion_config=world,
                                      name="test_mansion")
        test_mansion._elevators = [test_elevator]
        dispatch = []
        dispatch.append(ElevatorAction(3, -1))
        test_mansion.run_mansion(dispatch)
        test_mansion.run_mansion(dispatch)  # t = 1.0
        # print(test_mansion.state, "\nworld time is", world.raw_time)
        state = test_mansion.state
        self.assertAlmostEqual(state.ElevatorStates[0].Direction, -1)
Exemple #7
0
def run_action_abnormal_test(action_target_floor, action_target_direction,
                             set_seed):
    flag = True
    try:
        env = LiftSim()
        if (set_seed):
            env.seed(set_seed)
        state = env.reset()

        action = [
            ElevatorAction(action_target_floor, action_target_direction)
            for i in range(4)
        ]
        next_state, reward, _, _ = env.step(elevatoraction_to_list(action))
    except AssertionError:
        flag = False
        print('abnormal action: ', action_target_floor, type(action_target_floor) \
                                , action_target_direction, type(action_target_direction))
        print('run_action_abnormal_test pass')
    if (flag):
        print('abnormal action: ', action_target_floor, type(action_target_floor) \
                                , action_target_direction, type(action_target_direction))
        print('run_action_abnormal_test fail')
        assert False
Exemple #8
0
    def test_door_load_unload(self, mock_uniformgenerator):
        """
        stop at the target, load and unload corresponding passengers, open and close the door properly
        """
        max_floors = 8
        world = MansionConfig(dt=0.50,
                              number_of_floors=max_floors,
                              floor_height=4.0)

        test_elevator = Elevator(start_position=0.0,
                                 mansion_config=world,
                                 name="test_elevator")
        test_elevator._direction = 1
        test_elevator._current_position = 8.0
        test_elevator._target_floors = [3, 5]
        test_elevator._loaded_person = [
            list() for i in range(test_elevator._number_of_floors)
        ]
        test_elevator._loaded_person[2].append(
            PersonType(6, 40, 1, 3, world.raw_time))
        test_elevator._loaded_person[4].append(
            PersonType(7, 35, 1, 5, world.raw_time))
        test_elevator._load_weight = 80

        tmp_uniform_generator = UniformPersonGenerator()

        ret_person = []
        ret_person.append(PersonType(0, 50, 3, 5, world.raw_time))
        ret_person.append(PersonType(1, 30, 3, 1, world.raw_time))
        ret_person.append(PersonType(2, 60, 6, 4, world.raw_time))
        ret_person.append(PersonType(4, 55, 3, 4, world.raw_time))
        ret_person.append(PersonType(5, 65, 3, 6, world.raw_time))
        person_generators.uniform_generator.UniformPersonGenerator.generate_person = mock.Mock(
            return_value=(ret_person))

        test_mansion = MansionManager(elevator_number=1,
                                      person_generator=tmp_uniform_generator,
                                      mansion_config=world,
                                      name="test_mansion")
        test_mansion._elevators = [test_elevator]
        dispatch = []
        dispatch.append(ElevatorAction(3, 1))

        test_mansion.run_mansion(dispatch)
        # print(test_mansion.state, "\nworld time is", world.raw_time)
        state = test_mansion.state
        self.assertAlmostEqual(state.ElevatorStates[0].DoorState, 0.5)

        # mock generate_person again
        ret_person = []
        person_generators.uniform_generator.UniformPersonGenerator.generate_person = mock.Mock(
            return_value=(ret_person))

        test_mansion.run_mansion(dispatch)  # Door fully open, t = 1.0
        state = test_mansion.state
        self.assertAlmostEqual(state.ElevatorStates[0].DoorState, 1.0)

        for i in range(4):
            test_mansion.run_mansion(dispatch)
            # print(test_mansion.state, "\nworld time is", world.raw_time)
        state = test_mansion.state  # passenger 6 is unloaded, t = 3.0
        self.assertAlmostEqual(state.ElevatorStates[0].LoadWeight, 40)

        dispatch = []
        dispatch.append(ElevatorAction(0, 0))

        for i in range(4):
            test_mansion.run_mansion(dispatch)
            # print(test_mansion.state, "\nworld time is", world.raw_time)
        state = test_mansion.state  # passenger 0 and 4 are loaded, t = 5.0
        self.assertAlmostEqual(state.ElevatorStates[0].LoadWeight, 145)

        for i in range(4):
            test_mansion.run_mansion(dispatch)
        state = test_mansion.state  # passenger 5 is loaded, t = 7.0
        self.assertAlmostEqual(state.ElevatorStates[0].LoadWeight, 210)

        for i in range(4):
            test_mansion.run_mansion(dispatch)
            print(test_mansion.state, "\nworld time is", world.raw_time)
        state = test_mansion.state  # the door is closed, going up, t = 9.0
        self.assertAlmostEqual(state.ElevatorStates[0].Velocity, 1.0)
Exemple #9
0
    def test_dispatch_when_closing(self, mock_uniformgenerator):
        """
        dispatch the current floor when the door is closing
        """
        max_floors = 8
        # mansion_config
        world = MansionConfig(dt=0.50,
                              number_of_floors=max_floors,
                              floor_height=4.0)

        # test_elevator
        test_elevator = Elevator(start_position=0.0,
                                 mansion_config=world,
                                 name="test_elevator")

        test_elevator._direction = 1
        test_elevator._current_position = 8.0
        test_elevator._target_floors = [4, 5]
        test_elevator._loaded_person = [
            list() for i in range(test_elevator._number_of_floors)
        ]
        test_elevator._loaded_person[3].append(
            PersonType(6, 40, 1, 4, world.raw_time))
        test_elevator._loaded_person[4].append(
            PersonType(7, 40, 1, 5, world.raw_time))
        test_elevator._load_weight = 80

        # test_mansion
        tmp_uniform_generator = UniformPersonGenerator()

        ret_person = []
        ret_person.append(PersonType(0, 50, 3, 5, world.raw_time))
        ret_person.append(PersonType(1, 50, 3, 1, world.raw_time))
        ret_person.append(PersonType(2, 60, 6, 4, world.raw_time))
        person_generators.uniform_generator.UniformPersonGenerator.generate_person = mock.Mock(
            return_value=(ret_person))

        test_mansion = MansionManager(elevator_number=1,
                                      person_generator=tmp_uniform_generator,
                                      mansion_config=world,
                                      name="test_mansion")
        test_mansion._elevators = [test_elevator]
        dispatch = []
        dispatch.append(ElevatorAction(3, 1))

        # run_mansion
        test_mansion.run_mansion(dispatch)

        ret_person = []
        person_generators.uniform_generator.UniformPersonGenerator.generate_person = mock.Mock(
            return_value=(ret_person))

        test_mansion.run_mansion(dispatch)  # the door is open, t = 1.0
        # print(test_mansion.state, "\nworld time is", world.raw_time)

        dispatch = []
        dispatch.append(ElevatorAction(-1, 0))
        for i in range(4):
            test_mansion.run_mansion(dispatch)  # load person 0, t = 3.0

        # the door is closing, the door state = 0.5, t = 3.5
        test_mansion.run_mansion(dispatch)

        # come two more passengers
        ret_person = []
        ret_person.append(PersonType(4, 55, 3, 4, world.raw_time))
        ret_person.append(PersonType(5, 65, 3, 6, world.raw_time))
        person_generators.uniform_generator.UniformPersonGenerator.generate_person = mock.Mock(
            return_value=(ret_person))

        dispatch = []
        dispatch.append(ElevatorAction(3, 1))

        # the door is open, door_state = 1.0, time = 4.0
        test_mansion.run_mansion(dispatch)
        state = test_mansion.state
        self.assertAlmostEqual(state.ElevatorStates[0].DoorState, 1.0)

        ret_person = []
        person_generators.uniform_generator.UniformPersonGenerator.generate_person = mock.Mock(
            return_value=(ret_person))

        dispatch = []
        dispatch.append(ElevatorAction(-1, 0))
        for i in range(4):
            test_mansion.run_mansion(dispatch)  # load the two passengers
        state = test_mansion.state
        self.assertAlmostEqual(state.ElevatorStates[0].LoadWeight, 250)
Exemple #10
0
    def test_stop_at_dispatch(self, mock_uniformgenerator):
        """
        stop at the dispatch floor, open and close the door, then keep going to the target floor
        """
        max_floors = 8
        # mansion_config
        world = MansionConfig(dt=0.50,
                              number_of_floors=max_floors,
                              floor_height=4.0)

        # test_elevator
        test_elevator = Elevator(start_position=0.0,
                                 mansion_config=world,
                                 name="test_elevator")
        test_elevator._direction = 1
        test_elevator._current_velocity = 2.0
        test_elevator._current_position = 4.0  # currently at 2 floor
        test_elevator._target_floors = [5]
        test_elevator._loaded_person = [
            list() for i in range(test_elevator._number_of_floors)
        ]
        test_elevator._loaded_person[5].append(
            PersonType(0, 50, 1, 6, world.raw_time))
        test_elevator._load_weight = 50

        # test_mansion
        tmp_uniform_generator = UniformPersonGenerator()

        ret_person = []
        person_generators.uniform_generator.UniformPersonGenerator.generate_person = mock.Mock(
            return_value=(ret_person))

        test_mansion = MansionManager(elevator_number=1,
                                      person_generator=tmp_uniform_generator,
                                      mansion_config=world,
                                      name="test_mansion")
        test_mansion._elevators = [test_elevator]

        # test
        dispatch = []
        dispatch.append(ElevatorAction(3, 1))

        for i in range(7):
            test_mansion.run_mansion(dispatch)  # stop at the dispatched floor
        # print(test_mansion.state, "\nworld time is", world.raw_time)
        # dispatch = []
        # dispatch.append(ElevatorAction(-1, 0))
        for i in range(2):
            # the door is fully open, t = 4.5
            test_mansion.run_mansion(dispatch)
        state = test_mansion.state
        self.assertAlmostEqual(state.ElevatorStates[0].DoorState, 1.0)

        dispatch = []
        dispatch.append(ElevatorAction(0, 0))

        for i in range(6):
            # finish time open lag and close the door
            test_mansion.run_mansion(dispatch)
        state = test_mansion.state
        self.assertAlmostEqual(state.ElevatorStates[0].DoorState, 0.0)

        for i in range(4):
            test_mansion.run_mansion(dispatch)  # then keep going up
        state = test_mansion.state
        self.assertAlmostEqual(state.ElevatorStates[0].Velocity, 2.0)
Exemple #11
0
    def test_overload(self, mock_uniformgenerator):
        """
        overload, two people enter together, check who can enter the elevator one by one
        after overload, if the dispatcher still dispatches the elevator to the current floor, ignore the dispatch
        """
        max_floors = 8
        world = MansionConfig(dt=0.50,
                              number_of_floors=max_floors,
                              floor_height=4.0)

        test_elevator = Elevator(start_position=0.0,
                                 mansion_config=world,
                                 name="test_elevator")
        test_elevator._direction = 1
        test_elevator._current_position = 8.0
        test_elevator._target_floors = [5]
        test_elevator._loaded_person = [
            list() for i in range(test_elevator._number_of_floors)
        ]
        test_elevator._loaded_person[5].append(
            PersonType(6, 750, 1, 6, world.raw_time))
        test_elevator._loaded_person[7].append(
            PersonType(7, 750, 1, 8, world.raw_time))
        test_elevator._load_weight = 1500

        tmp_uniform_generator = UniformPersonGenerator()

        ret_person = []
        ret_person.append(PersonType(0, 150, 3, 5, world.raw_time))
        ret_person.append(PersonType(1, 50, 3, 1, world.raw_time))
        ret_person.append(PersonType(2, 60, 5, 6, world.raw_time))
        ret_person.append(PersonType(4, 65, 3, 8, world.raw_time))
        ret_person.append(PersonType(5, 65, 3, 6, world.raw_time))
        person_generators.uniform_generator.UniformPersonGenerator.generate_person = mock.Mock(
            return_value=(ret_person))

        test_mansion = MansionManager(elevator_number=1,
                                      person_generator=tmp_uniform_generator,
                                      mansion_config=world,
                                      name="test_mansion")
        test_mansion._elevators = [test_elevator]
        dispatch = []
        dispatch.append(ElevatorAction(3, 1))

        test_mansion.run_mansion(dispatch)

        # mock generate_person again
        ret_person = []
        person_generators.uniform_generator.UniformPersonGenerator.generate_person = mock.Mock(
            return_value=(ret_person))

        test_mansion.run_mansion(dispatch)  # Door fully open, t = 1.0

        dispatch = []
        dispatch.append(ElevatorAction(-1, 0))

        for i in range(4):
            test_mansion.run_mansion(dispatch)  # upload person 4, t = 3.0

        dispatch = []
        dispatch.append(ElevatorAction(3, 1))

        test_mansion.run_mansion(dispatch)
        state = test_mansion.state
        self.assertAlmostEqual(state.ElevatorStates[0].LoadWeight, 1565)

        test_mansion.run_mansion(dispatch)
        test_mansion.run_mansion(dispatch)  # t = 4.5
        state = test_mansion.state
        self.assertGreater(state.ElevatorStates[0].Velocity, 0.0)
Exemple #12
0
    def policy(self, state):
        ret_actions = [
            ElevatorAction(
                0, 1) for i in range(self.elevator_num)]

        idle_ele_queue = queue.Queue()
        upward_floor_address_dict = dict()
        downward_floor_address_dict = dict()

        for i in range(len(state.ElevatorStates)):
            idle_ele_queue.put(i)

        for floor in state.RequiringUpwardFloors:
            # Addressing Elevator, Priority
            upward_floor_address_dict[floor] = (-1, -HUGE)

        for floor in state.RequiringDownwardFloors:
            downward_floor_address_dict[floor] = (-1, -HUGE)

        while not idle_ele_queue.empty():
            sel_ele = idle_ele_queue.get()
            if(state.ElevatorStates[sel_ele].Direction > 0):
                assigned = False
                sel_priority = -HUGE
                sel_floor = -1
                for upward_floor in state.RequiringUpwardFloors:
                    if(upward_floor < state.ElevatorStates[sel_ele].Floor - EPSILON):
                        continue
                    priority = state.ElevatorStates[sel_ele].Floor - \
                        upward_floor
                    if(upward_floor in state.ElevatorStates[sel_ele].ReservedTargetFloors):
                        priority = min(0.0, priority + 5.0)
                    if (state.ElevatorStates[sel_ele].Velocity < EPSILON):
                        priority -= 5.0
                    if(priority > upward_floor_address_dict[upward_floor][1] and priority > sel_priority):
                        sel_priority = priority
                        sel_floor = upward_floor

                if(sel_floor > 0):
                    ret_actions[sel_ele] = ElevatorAction(sel_floor, 1)
                    if(upward_floor_address_dict[sel_floor][0] >= 0):
                        ret_actions[upward_floor_address_dict[sel_floor]
                                    [0]] = ElevatorAction(0, 1)
                        idle_ele_queue.put(
                            upward_floor_address_dict[sel_floor][0])
                    upward_floor_address_dict[sel_floor] = (
                        sel_ele, sel_priority)
                    assigned = True

                # In case no floor is assigned to the current elevator, we
                # search all requiring downward floor, find the largest floor
                # and assign it to the elevator
                if(not assigned):
                    if(len(state.RequiringDownwardFloors) > 0):
                        max_unassigned_down_floor = -1
                        for downward_floor in state.RequiringDownwardFloors:
                            if(downward_floor_address_dict[downward_floor][0] < 0 and max_unassigned_down_floor < downward_floor):
                                max_unassigned_down_floor = downward_floor
                        if(max_unassigned_down_floor >= 0):
                            ret_actions[sel_ele] = ElevatorAction(
                                max_unassigned_down_floor, -1)
                            priority = - \
                                state.ElevatorStates[sel_ele].Floor - EPSILON + max_unassigned_down_floor
                            downward_floor_address_dict[max_unassigned_down_floor] = (
                                sel_ele, priority)

            if(state.ElevatorStates[sel_ele].Direction < 0):
                assigned = False
                sel_priority = -HUGE
                sel_floor = -1
                for downward_floor in state.RequiringDownwardFloors:
                    if(downward_floor > state.ElevatorStates[sel_ele].Floor + EPSILON):
                        continue
                    priority = - \
                        state.ElevatorStates[sel_ele].Floor + downward_floor
                    if(downward_floor in state.ElevatorStates[sel_ele].ReservedTargetFloors):
                        priority = min(0.0, priority + 5.0)
                    if (state.ElevatorStates[sel_ele].Velocity < EPSILON):
                        priority -= 5.0
                    if(priority > downward_floor_address_dict[downward_floor][1] and priority > sel_priority):
                        sel_priority = priority
                        sel_floor = downward_floor

                if(sel_floor > 0):
                    ret_actions[sel_ele] = ElevatorAction(sel_floor, 1)
                    if(downward_floor_address_dict[sel_floor][0] >= 0):
                        ret_actions[downward_floor_address_dict[sel_floor][0]] = ElevatorAction(
                            0, 1)
                        idle_ele_queue.put(
                            downward_floor_address_dict[sel_floor][0])
                    downward_floor_address_dict[sel_floor] = (
                        sel_ele, sel_priority)
                    assigned = True

                # In case no floor is assigned to the current elevator, we
                # search all requiring-upward floor, find the lowest floor and
                # assign it to the elevator
                if(not assigned):
                    if(len(state.RequiringUpwardFloors) > 0):
                        min_unassigned_up_floor = HUGE
                        for upward_floor in state.RequiringUpwardFloors:
                            if(upward_floor_address_dict[upward_floor][0] < 0 and min_unassigned_up_floor > upward_floor):
                                min_unassigned_up_floor = upward_floor
                        if(min_unassigned_up_floor >= 0 and min_unassigned_up_floor < HUGE - 1):
                            ret_actions[sel_ele] = ElevatorAction(
                                min_unassigned_up_floor, 1)
                            priority = state.ElevatorStates[sel_ele].Floor + \
                                EPSILON - min_unassigned_up_floor
                            upward_floor_address_dict[min_unassigned_up_floor] = (
                                sel_ele, priority)

            if(state.ElevatorStates[sel_ele].Direction == 0):
                # in case direction == 0,  select the closest requirements
                sel_floor = -1
                sel_priority = -HUGE
                sel_direction = 0

                for upward_floor in state.RequiringUpwardFloors:
                    priority = -abs(upward_floor -
                                    state.ElevatorStates[sel_ele].Floor)
                    if(priority > upward_floor_address_dict[upward_floor][1] and priority > sel_priority):
                        sel_priority = priority
                        sel_direction = 1
                        sel_floor = upward_floor

                for downward_floor in state.RequiringDownwardFloors:
                    priority = -abs(downward_floor -
                                    state.ElevatorStates[sel_ele].Floor)
                    if(priority > downward_floor_address_dict[downward_floor][1] and priority > sel_priority):
                        sel_priority = priority
                        sel_direction = - 1
                        sel_floor = downward_floor

                if(sel_floor > 0):
                    ret_actions[sel_ele] = ElevatorAction(
                        sel_floor, sel_direction)
                    if(sel_direction > 0):
                        if(upward_floor_address_dict[sel_floor][0] >= 0):
                            idle_ele_queue.put(
                                upward_floor_address_dict[sel_floor][0])
                        upward_floor_address_dict[sel_floor] = (
                            sel_ele, sel_priority)
                    else:
                        if(downward_floor_address_dict[sel_floor][0] >= 0):
                            idle_ele_queue.put(
                                downward_floor_address_dict[sel_floor][0])
                        downward_floor_address_dict[sel_floor] = (
                            sel_ele, sel_priority)

        # print min_unaddressed_up_lift, max_unaddressed_down_lift,
        # state.RequiringUpwardFloors, state.RequiringDownwardFloors
        # action_list = []
        # for a in ret_actions:
        #     action_list.append(a.TargetFloor)
        #     action_list.append(a.DirectionIndicator)
        return ret_actions