def simulate_parallel(config="../data/config/parallel.json", inData=None, params=None, search_space=None, **kwargs): if inData is None: # othwerwise we use what is passed from MaaSSim.data_structures import structures inData = structures.copy() # fresh data if params is None: params = get_config(config, root_path = kwargs.get('root_path')) # load from .json file if len(inData.G) == 0: # only if no graph in input inData = load_G(inData, params, stats=True) # download graph for the 'params.city' and calc the skim matrices if len(inData.passengers) == 0: # only if no passengers in input inData = generate_demand(inData, params, avg_speed=True) if len(inData.vehicles) == 0: # only if no vehicles in input inData.vehicles = generate_vehicles(inData, params.nV) if len(inData.platforms) == 0: # only if no platforms in input inData.platforms = initialize_df(inData.platforms) inData.platforms.loc[0] = empty_series(inData.platforms) inData.platforms.fare = [1] inData.vehicles.platform = 0 inData.passengers.platforms = inData.passengers.apply(lambda x: [0], axis=1) inData = prep_shared_rides(inData, params.shareability) # obligatory to prepare schedules brute(func=single_pararun, ranges=slice_space(search_space, replications=params.parallel.get("nReplications",1)), args=(inData, params, search_space), full_output=True, finish=None, workers=params.parallel.get('nThread',1))
def test_platform_competition(self): # make sure when you compete with the prcie, lowering the fare and increasing the fee from MaaSSim.data_structures import structures as local_inData from MaaSSim.decisions import f_platform_choice from MaaSSim.simulators import simulate as platform_simulator_1 from MaaSSim.utils import get_config, generate_vehicles, generate_demand, initialize_df, load_G CONFIG_PATH = os.path.join(os.path.dirname(__file__), 'config_platform_choices.json') params = get_config(CONFIG_PATH, root_path=os.path.dirname(__file__)) # load from .json file params.nP = 200 # reuqests (and passengers) params.simTime = 4 params.nD = 1 fare = 1.5 fleet = 10 params.nV = 20 + fleet inData = local_inData.copy() inData = load_G(inData, params, stats=True) # download graph for the 'params.city' and calc the skim matrices inData = generate_demand(inData, params, avg_speed=True) inData.vehicles = generate_vehicles(inData, params.nV) inData.platforms = initialize_df(inData.platforms) inData.platforms.loc[0] = [1, 'Platform1', 30] inData.platforms.loc[1] = [fare, 'Platform2', 30] inData = generate_demand(inData, params, avg_speed=True) inData.vehicles = generate_vehicles(inData, params.nV) inData.vehicles.platform = [0] * 20 + [1] * fleet inData.passengers.platforms = inData.passengers.apply(lambda x: [0, 1], axis=1) sim = platform_simulator_1(params=params, inData=inData, f_platform_choice=f_platform_choice) ret = sim.res[0].veh_exp.copy() ret['platform'] = inData.vehicles.platform first = ret[ret.platform == 1].ARRIVES_AT_DROPOFF.sum() fare = 0.5 fleet = 50 params.nV = 20 + fleet inData = generate_demand(inData, params, avg_speed=True) inData.vehicles = generate_vehicles(inData, params.nV) inData.platforms = initialize_df(inData.platforms) inData.platforms.loc[0] = [1, 'Platform1', 30] inData.platforms.loc[1] = [fare, 'Platform2', 30] inData = generate_demand(inData, params, avg_speed=True) inData.vehicles = generate_vehicles(inData, params.nV) inData.vehicles.platform = [0] * 20 + [1] * fleet inData.passengers.platforms = inData.passengers.apply(lambda x: [0, 1], axis=1) from MaaSSim.simulators import simulate as platform_simulator_2 sim2 = platform_simulator_2(params=params, inData=inData, f_platform_choice=f_platform_choice) ret = sim2.res[0].veh_exp ret['platform'] = inData.vehicles.platform second = ret[ret.platform == 1].ARRIVES_AT_DROPOFF.sum() self.assertGreater(second, first) del sim del sim2 del params del inData
def test_staticIO(self): """ test if simulation can be restarted from static .csv file and yield the same results """ from MaaSSim.utils import prep_supply_and_demand, get_config, load_G from MaaSSim.simulators import simulate as this_simulator from MaaSSim.data_structures import structures as inData from MaaSSim.utils import read_requests_csv, read_vehicle_positions from pandas.testing import assert_frame_equal CONFIG_PATH = os.path.join(os.path.dirname(__file__), 'config_results_test.json') params = get_config( CONFIG_PATH, root_path=os.path.dirname(__file__)) # load from .json file inData = load_G(inData, params) # load network graph inData = prep_supply_and_demand(inData, params) # generate supply and demand inData.requests.to_csv('requests.csv') inData.vehicles.to_csv('vehicles.csv') sim1 = this_simulator(params=params, inData=inData) # simulate inData = read_requests_csv(inData, path='requests.csv') inData = read_vehicle_positions(inData, path='vehicles.csv') sim2 = this_simulator(params=params, inData=inData) # simulate assert_frame_equal(sim2.runs[0].trips, sim2.runs[0].trips) assert_frame_equal(sim2.runs[0].rides, sim2.runs[0].rides) # self.assertTrue(sim2.runs[0].rides.equals(sim1.runs[0].rides)) del sim2 del sim1
def test_early_ending_shift_and_losing_patience(self): """ test if platform batches the results properly at matching """ from MaaSSim.traveller import travellerEvent from MaaSSim.driver import driverEvent from MaaSSim.data_structures import structures as this_inData_early from MaaSSim.simulators import simulate as simulator_early from MaaSSim.utils import prep_supply_and_demand, get_config, load_G CONFIG_PATH = os.path.join(os.path.dirname(__file__), 'config_results_test.json') params = get_config(CONFIG_PATH, root_path=os.path.dirname(__file__)) # load from .json file params.nP = 2 params.nV = 1 params.times.patience = 30 this_inData_early = load_G(this_inData_early, params) # load network graph this_inData_early = prep_supply_and_demand(this_inData_early, params) # generate supply and demand this_inData_early.vehicles.shift_end = [100] # vehicle ends early sim = simulator_early(params=params, inData=this_inData_early, event_based=False) self.assertIn(travellerEvent.LOSES_PATIENCE.name, sim.runs[0].trips.event.values) # one traveller lost patience r = sim.runs[0].rides self.assertLess(r[r.event == driverEvent.ENDS_SHIFT.name].t.squeeze(), sim.t1) # did he really end earlier del sim del params
def test_batch_platform(self): """ test if platform batches the results properly at matching """ from MaaSSim.utils import initialize_df, get_config, load_G, prep_supply_and_demand from MaaSSim.data_structures import structures as inData from MaaSSim.simulators import simulate as this_simulator CONFIG_PATH = os.path.join(os.path.dirname(__file__), 'config_results_test.json') params = get_config( CONFIG_PATH, root_path=os.path.dirname(__file__)) # load from .json file inData = load_G(inData, params) # load network graph inData = prep_supply_and_demand(inData, params) # generate supply and demand inData.platforms = initialize_df(inData.platforms) inData.platforms.loc[0] = [1, 'Uber', 600] # batch requests every 600 seconds sim = this_simulator(params=params, inData=inData, event_based=False) Qs = sim.runs[0].queues Qs.groupby('platform')[['vehQ', 'reqQ']].plot(drawstyle='steps-post') r = sim.runs[0].trips times = r[r.event == 'RECEIVES_OFFER'].t.sort_values( ascending=True).diff().dropna().unique() self.assertIn(600, times) # are requests batched ony at batch_time del sim del params del inData
def test_maassim_with_exmas(self): from MaaSSim.data_structures import structures as inData from MaaSSim.utils import get_config, load_G, prep_supply_and_demand, generate_demand, generate_vehicles, \ initialize_df # simulator from MaaSSim.simulators import simulate from MaaSSim.driver import driverEvent from MaaSSim.utils import get_config CONFIG_PATH = os.path.join(os.path.dirname(__file__), 'config_platform_choices.json') params = get_config( CONFIG_PATH, root_path=os.path.dirname(__file__)) # load from .json file params.times.pickup_patience = 3600 # 1 hour of simulation params.simTime = 4 # 1 hour of simulation params.nP = 500 # reuqests (and passengers) params.nV = 100 # vehicles params.shareability.avg_speed = params.speeds.ride params.shareability.shared_discount = 0.3 params.shareability.delay_value = 1 params.shareability.WtS = 1.3 params.shareability.price = 1.5 # eur/km params.shareability.VoT = 0.0035 # eur/s params.shareability.matching_obj = 'u_pax' # minimize VHT for vehicles params.shareability.pax_delay = 0 params.shareability.horizon = 600 params.shareability.max_degree = 4 params.shareability.nP = params.nP params.shareability.share = 1 params.shareability.without_matching = True inData = load_G(inData, params) # load network graph inData = generate_demand(inData, params, avg_speed=False) inData.vehicles = generate_vehicles(inData, params.nV) inData.vehicles.platform = inData.vehicles.apply(lambda x: 0, axis=1) inData.passengers.platforms = inData.passengers.apply(lambda x: [0], axis=1) inData.requests['platform'] = inData.requests.apply( lambda row: inData.passengers.loc[row.name].platforms[0], axis=1) inData.platforms = initialize_df(inData.platforms) inData.platforms.loc[0] = [1, 'Uber', 30] params.shareability.share = 1 params.shareability.without_matching = True inData = ExMAS.main(inData, params.shareability, plot=False) # create shareability graph (ExMAS) sim = simulate(params=params, inData=inData) # simulate self.assertGreater(sim.inData.sblts.schedule.kind.max(), 10) # are there shared rides in the solution self.assertGreater( sim.runs[0].rides.paxes.apply(lambda x: len(x)).max(), 1) # did someone travel together
def simulate(config="../data/config/default.json", inData=None, params=None, **kwargs): """ main runner and wrapper loads or uses json config to prepare the data for simulation, run it and process the results :param config: .json file path :param inData: optional input data :param params: loaded json file :param kwargs: optional arguments :return: simulation object with results """ if inData is None: # otherwise we use what is passed from MaaSSim.data_structures import structures inData = structures.copy() # fresh data if params is None: params = get_config( config, root_path=kwargs.get('root_path')) # load from .json file if kwargs.get('make_main_path', False): from MaaSSim.utils import make_config_paths params = make_config_paths(params, main=kwargs.get('make_main_path', False), rel=True) if params.paths.get('requests', False): inData = read_requests_csv(inData, path=params.paths.requests) if params.paths.get('vehicles', False): inData = read_vehicle_positions(inData, path=params.paths.vehicles) if len(inData.G) == 0: # only if no graph in input inData = load_G( inData, params, stats=True ) # download graph for the 'params.city' and calc the skim matrices if len(inData.passengers) == 0: # only if no passengers in input inData = generate_demand(inData, params, avg_speed=True) if len(inData.vehicles) == 0: # only if no vehicles in input inData.vehicles = generate_vehicles(inData, params.nV) if len(inData.platforms) == 0: # only if no platforms in input inData.platforms = initialize_df(inData.platforms) inData.platforms.loc[0] = empty_series(inData.platforms) inData.platforms.fare = [1] inData = prep_shared_rides(inData, params.shareability) # prepare schedules sim = Simulator(inData, params=params, **kwargs) # initialize for day in range(params.get('nD', 1)): # run iterations sim.make_and_run(run_id=day) # prepare and SIM sim.output() # calc results if sim.functions.f_stop_crit(sim=sim): break return sim
def platforms(): # play the market competition scenarios. You compete with platform of 20 vehs in fleet and charging 1/km. # You explore how to compete varying fleet from 5 to 40 vehicles and price ranges from .6 to 1.4 # experiments are run sequentially and collect to ine csv # (error prone and using single thread, only for small experiments) print(os.getcwd()) def experiment(inData, params, fare=0.8, fleet=20): params.nV = 20 + fleet # vehicles inData = generate_demand(inData, params, avg_speed=True) inData.vehicles = generate_vehicles(inData, params.nV) inData.platforms = initialize_df(inData.platforms) inData.platforms.loc[0] = [1, 'Platform1', 30] inData.platforms.loc[1] = [fare, 'Platform2', 30] inData = generate_demand(inData, params, avg_speed=True) inData.vehicles = generate_vehicles(inData, params.nV) inData.vehicles.platform = [0] * 20 + [1] * fleet # inData.vehicles.platform = inData.vehicles.apply(lambda x: 1 if random.random()<0.5 else 0, axis = 1) # randomly 30% vehicles for first platform, 70% for 2nd inData.passengers.platforms = inData.passengers.apply(lambda x: [0, 1], axis=1) sim = simulate(params=params, inData=inData, print=False, f_platform_choice=f_platform_choice, logger_level=logging.CRITICAL) ret = sim.res[0].veh_exp ret['platform'] = inData.vehicles.platform return ret[ret.platform == 1].ARRIVES_AT_DROPOFF.sum() from MaaSSim.data_structures import structures as inData params = get_config('../../data/config/platforms.json') # load configuration params.paths.G = '../../data/graphs/delft.graphml' params.paths.skim = '../../data/graphs/delft.csv' inData = load_G(inData, params) # load network graph params.nP = 200 # reuqests (and passengers) params.simTime = 4 params.nD = 1 ret = [] for repl in range(10): for fleet in [5, 10, 15, 20, 25, 30, 40]: for fare in [0.6, 0.8, 1, 1.2, 1.4]: revenue = experiment(inData, params, fare=fare, fleet=fleet) print(fleet, fare, revenue, repl) ret.append({'fleet': fleet, 'fare': fare, 'revenue': revenue, 'repl': repl}) pd.DataFrame(ret).to_csv('pricing.csv')
def test_prep(self): """ tests if simulation is prepared properly (reuests, passengers, vehicles are generated) """ from MaaSSim.utils import prep_supply_and_demand, get_config, load_G from MaaSSim.data_structures import structures as inData CONFIG_PATH = os.path.join(os.path.dirname(__file__), 'config_results_test.json') params = get_config( CONFIG_PATH, root_path=os.path.dirname(__file__)) # load from .json file inData = load_G(inData, params) # load network graph inData = prep_supply_and_demand(inData, params) # generate supply and demand self.assertEqual(inData.requests.shape[0], params.nP) self.assertEqual(inData.passengers.shape[0], params.nP) self.assertEqual(inData.vehicles.shape[0], params.nV)
def test_multiple_days(self): # have two runs in the same instance and see if they are different from MaaSSim.data_structures import structures as my_inData from MaaSSim.decisions import f_platform_choice from MaaSSim.simulators import simulate as multiple_days_simulator from MaaSSim.utils import get_config, generate_vehicles, generate_demand, initialize_df, load_G from MaaSSim.simulators import simulate as simulator_for_multiple_days CONFIG_PATH = os.path.join(os.path.dirname(__file__), 'config_results_test.json') params = get_config( CONFIG_PATH, root_path=os.path.dirname(__file__)) # load from .json file params.times.patience = 3600 # 1 hour of simulation params.simTime = 1 # 1 hour of simulation params.nP = 30 # reuqests (and passengers) params.nV = 30 # vehicles params.nD = 3 inData = my_inData.copy() inData = load_G( inData, params, stats=True ) # download graph for the 'params.city' and calc the skim matrices inData = generate_demand(inData, params, avg_speed=True) inData.vehicles = generate_vehicles(inData, params.nV) sim = multiple_days_simulator(params=params, inData=inData, print=False, f_platform_choice=f_platform_choice) self.assertEqual(len(sim.runs), 3) del sim del params
def supply_demand(): # explore various supply and demand setting with parallel simulations replicatrd 10 times, # each stored to separate .zip file (to be further merged with collect_results from utils) from MaaSSim.data_structures import structures as inData params = get_config('../../data/config/delft.json') # load configuration params.paths.dumps = '../docs/experiments/sd' params.times.patience = 1200 params.simTime = 4 params.parallel.nThread = 4 params.parallel.nReplications = 10 params.paths.G = '../../data/graphs/delft.graphml' params.paths.skim = '../../data/graphs/delft.csv' inData = load_G(inData, params) # load network graph space = DotMap() space.nP = list(range(50,1001,50)) space.nV = list(range(20,201,20)) print(dict(space)) simulate_parallel(params = params, search_space = space)
def test_networkIO(self): from numpy import inf from MaaSSim.utils import load_G, download_G, save_G, get_config from MaaSSim.data_structures import structures as inData CONFIG_PATH = os.path.join(os.path.dirname(__file__), 'config_utils_test.json') params = get_config(CONFIG_PATH, root_path=os.path.dirname(__file__)) # load from .json file params.city = 'Wieliczka, Poland' params.paths.G = os.path.join(os.path.dirname(__file__), params.city.split(",")[0] + ".graphml") # graphml of a current .city params.paths.skim = os.path.join(os.path.dirname(__file__), params.city.split(",")[ 0] + ".csv") # csv with a skim between the nodes of the .city inData = download_G(inData, params) # download the graph and compute the skim save_G(inData, params) # save it to params.paths.G inData = load_G(inData, params, stats=True) # download graph for the 'params.city' and calc the skim matrices self.assertGreater(inData.nodes.shape[0], 10) # do we have nodes self.assertGreater(inData.skim.shape[0], 10) # do we have skim self.assertLess(inData.skim.mean().mean(), inf) # and values inside self.assertGreater(inData.skim.mean().mean(), 0) # positive distances