def test_basic_training_batch(self):
        '''
        Test if training on trivial parameter set does not fail 
        if PPO uses TaxiEnvBatch
        '''
        generator_params = self.get_generator_params()
        gen = Generator("testGymSolver", generator_params)
        graph_info = gen.generate()
        world_graph, idle_driver_locations, real_orders, \
            onoff_driver_locations, random_average, dist = gen.load_complete_set()

        # use OrigSolver as wrapper for params
        solver_params = self.get_solver_params(graph_info)
        solver_params['batch_env'] = 1

        solver = GymSolver(**solver_params)
        solver.train()

        solver_params["include_income_to_observation"] = 1
        solver = GymSolver(**solver_params)

        def fake_save_callback(result):
            pass

        solver.run(fake_save_callback)
    def load_dataset(self):
        '''
        load complete dataset

        note that orders are merged into a single day, and then sampled out of there
        '''
        dataset_params = self.params['dataset']
        gen = Generator(self.params['tag'], dataset_params)
        assert dataset_params[
            'dataset_type'] == 'hexagon', "Only hexagon dataset supported"
        world, idle_driver_locations, real_orders, \
            onoff_driver_locations, random_average, dist = gen.load_complete_set(dataset_id=self.params['dataset']['dataset_id'])

        self.l_max = 9  # default 9 (1.5h orders) can be served max. should not matter if orders are "real" and not generated

        self.n_side = 6  # number of neighbors to travel
        self.M = dataset_params['n']
        self.N = dataset_params['n']
        self.mapped_matrix_int = np.reshape(
            np.arange(0, len(world)),
            (self.N, self.M))  # should be positive for some reason
        self.order_num_dist = None  # should be used only for synthetic orders, we always generate orders ourselves
        self.order_time_dist = None
        self.order_price_dist = None
        self.idle_driver_dist_time = None  # [time, mean, std] -- we generate total number of drivers not randomly, but load them from generator
        self.idle_driver_location_mat = idle_driver_locations
        self.onoff_driver_location_mat = onoff_driver_locations

        # collect all orders in one day and sample them
        self.order_real = np.array(real_orders)
        for i in np.arange(len(self.order_real)):
            self.order_real[i][
                2] = self.order_real[i][2] % 144  # merge all together

        self.order_sample_p = 1. / self.days
Beispiel #3
0
    def load_env_params(self):
        '''
        load complete dataset

        note that orders are merged into a single day, and then sampled out of there
        '''
        dataset_params = self.params['dataset']
        gen = Generator(self.params['tag'], dataset_params)
        world, idle_driver_locations, real_orders, onoff_driver_locations, random_average, dist = gen.load_complete_set(dataset_id=self.params['dataset']['dataset_id'])
        params = {
            "world": world,
            "orders": real_orders,
            "order_sampling_rate": 1./self.days*self.params['dataset']['order_sampling_multiplier'],
            "drivers_per_node": idle_driver_locations[0,:],
            "n_intervals": self.params['dataset']['time_periods'],
            "wc": self.params['wc'],
            "count_neighbors": self.params['count_neighbors'] == 1,
            "weight_poorest": self.params['weight_poorest'] == 1,
            "normalize_rewards": self.params['normalize_rewards'] == 1,
            "minimum_reward": self.params['minimum_reward'] == 1,
            "include_income_to_observation": self.params['include_income_to_observation'] == 1,
            "poorest_first": self.params.get("poorest_first", 0) == 1,
            "idle_reward": self.params["idle_reward"], 
            "include_action_mask": self.params["action_mask"],
            "seed": self.params["seed"],
            "hold_observation": self.params["hold_observation"],
            "penalty_for_invalid_action": self.params["penalty_for_invalid_action"],
            "discrete": self.params["discrete"],
            "bounded_income": self.params["robust"] == 1,
            "fully_collaborative": self.params["batch_env"] == 1,
            "randomize_drivers": self.params["randomize_drivers"],
            "debug": self.params["debug"]
        }

        return params
Beispiel #4
0
    def test_no_solver(self):
        generator_params = {
            "dataset_type": "hexagon",
            "n": 10,
            "time_periods": 144,
            "days": 1,
            "orders_density": 0.1,
            "number_of_cars": 2,
            "order_distr": "uniform",
            "seed": 0
        }

        gen = Generator("testOrigSolvers", generator_params)
        graph_info = gen.generate()
        world_graph, idle_driver_locations, real_orders, onoff_driver_locations, random_average, dist = gen.load_complete_set(
        )

        solver_params = {
            "dataset": graph_info,
            "alpha": 0.1,
            "wc": 0,
            "tag": "testOrigSolvers",
            "gamma": 0.9,
            "train_test_split": 0.5
        }

        solver = OrigNoSolver(**solver_params)

        def fake_save_callback(result):
            pass

        solver.run(fake_save_callback)
 def test_init_solvers(self):
     # create simple environment
     gen = Generator("test")
     graph_info = gen.generate()
     params = {
         "dataset": graph_info,
         "wc": 0,
         "iterations": 2,
         "tag": "test",
         "count_neighbors": 1,
         "weight_poorest": 0,
         "normalize_rewards": 1,
         "minimum_reward": 0,
         "poorest_first": 1,
         "include_income_to_observation": 0,
         "testing_epochs": 2,
         "draw": 0,
         "shrinking_fraction": 0.9,
         "subsolver": "Diff",
         "debug": 1,
         "seed": 123,
         'penalty_for_invalid_action': 1000,
         "discrete": 0
     }
     solv = SplitSolver(**params)
     solv.init_subsolvers()
    def test_include_observation(self):
        generator_params = {
            "dataset_type": "hexagon",
            "n": 10,
            "time_periods": 2,
            "days": 2,
            "orders_density": 2,
            "number_of_cars": 20,
            "order_distr": "star",
            "order_sampling_multiplier": 1,
            "seed": 0
        }

        gen = Generator("testTaxiEnvBatch", generator_params)
        graph_info = gen.generate()
        world_graph, idle_driver_locations, real_orders, \
            onoff_driver_locations, random_average, dist = gen.load_complete_set()

        # use OrigSolver as wrapper for params
        orig_solver_params = {
            "dataset": graph_info,
            "alpha": 0.1,
            "wc": 0,
            "iterations": 1,  # 1 epoch
            "tag": "testTaxiEnvBatch",
            "gamma": 0.9,
            "order_sampling_multiplier": 1,
            "seed": 0
        }
        ca2c_params = self.get_ca2c_params(graph_info)
        solv = cA2CSolver(**ca2c_params)

        # driver + order dist + income + time + idle_driver
        assert solv.env.get_observation_space_shape() == (
            4 * len(world_graph) + generator_params["time_periods"], )
        observation = solv.env.reset()
        init_info = solv.env.get_reset_info()
        assert observation.shape == solv.env.get_observation_space_shape()
        curr_state, info, income_mat = solv.observation_to_old_fashioned_info(
            observation, init_info)
        assert (income_mat == np.zeros((len(world_graph), ))).all()

        def fake_save_callback(result):
            pass

        solv.run(fake_save_callback)
    def generate_datasets(self, force=False):
        if force:
            self.db.dataset.delete_many({'tag': self.tag})

        if self.db.dataset.find_one({'tag': self.tag}) != None:
            logging.info("Dataset for {} has been found".format(self.tag))
            return 0

        total_datasets = list(self.pm.get_data_param_sets())
        if len(total_datasets) == 0:
            raise Exception("No datasets generated, bad parameter values")

        generated = 0
        for p in total_datasets:
            gen = Generator(self.tag, p)
            dataset_info = gen.generate()
            self.db.dataset.insert_one(dataset_info)
            generated += 1

        return generated
    def load_dataset(self):
        '''
        load complete dataset
        note that orders are merged into a single day, and then sampled out of there
        '''
        dataset_params = self.params['dataset']
        gen = Generator(self.params['tag'], dataset_params)
        self.world, self.idle_driver_locations, self.real_orders, \
            self.onoff_driver_locations, random_average, dist = gen.load_complete_set(dataset_id=self.params['dataset']['dataset_id'])

        # check for views as an attribute of the network
        views = {}
        for n in self.world.nodes(data=True):
            if 'view' not in n[1]:
                break
            if n[1]['view'] != -1:
                if n[1]['view'] not in views:
                    views[n[1]['view']] = []
                views[n[1]['view']].append(n[0])
        self.views = views
    def test_discrete(self):
        generator_params = self.get_generator_params()
        gen = Generator("testGymSolver", generator_params)
        graph_info = gen.generate()
        world_graph, idle_driver_locations, real_orders, \
            onoff_driver_locations, random_average, dist = gen.load_complete_set()

        # use OrigSolver as wrapper for params
        solver_params = self.get_solver_params(graph_info)
        solver_params['discrete'] = 1

        solver = GymSolver(**solver_params)
        solver.train()

        solver_params["include_income_to_observation"] = 1
        solver = GymSolver(**solver_params)

        def fake_save_callback(result):
            pass

        solver.run(fake_save_callback)
    def test_view_solver(self):
        # a linear graph with orders and drivers beinng dispatched in over all network
        # only half of the graph is within a view

        generator_params = {
            "dataset_type": "linear",
            "n": 10,
            "time_periods": 2,
            "days": 1,
            "orders_density": 2,
            "number_of_cars": 200,
            "order_distr": "star",
            "order_sampling_multiplier": 1,
            "view_div":
            0.1,  # view is 10% of nodes (1 node), ordered by node id. 1 node makes max_deg different inside the view
            "seed": 0
        }

        gen = Generator("testTaxiEnvBatch", generator_params)
        graph_info = gen.generate()
        world_graph, idle_driver_locations, real_orders, _, _, _ = gen.load_complete_set(
        )

        # assert drivers ar distributed somehow uniformly
        assert idle_driver_locations.shape == (2, 10)
        assert (idle_driver_locations[0] > 0).all()
        # orders are located only on the edges
        orders_sum = np.zeros((10, ))
        for r in real_orders:
            orders_sum[r[0]] += 1
        assert orders_sum[0] > 0 and orders_sum[-1] > 0
        assert np.sum(orders_sum[1:-2]) == 0

        ca2c_params = self.get_ca2c_params(graph_info)
        solv = cA2CSolver(**ca2c_params)

        def fake_save_callback(result):
            pass

        solv.run(fake_save_callback)