diff --git a/.gitignore b/.gitignore index 2ec0303e..975e57cb 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,8 @@ *.pyc data +/data/data.zip +PLOTS nbactions*.xml nb-configuration.xml diff --git a/actions_requests.uml b/actions_requests.uml new file mode 100644 index 00000000..d45f5d0c --- /dev/null +++ b/actions_requests.uml @@ -0,0 +1,39 @@ + + + JAVA + cz.cvut.fel.aic.simod.visual.ridesharing.peoplefreightheuristic.SimpleTest + + cz.cvut.fel.aic.simod.ridesharing.model.PlanActionPickup + cz.cvut.fel.aic.simod.ridesharing.model.PlanComputationRequestFreight + cz.cvut.fel.aic.simod.ridesharing.model.DefaultPlanComputationRequest + cz.cvut.fel.aic.simod.ridesharing.model.PlanComputationRequestPeople + cz.cvut.fel.aic.simod.ridesharing.model.PlanActionDropoff + cz.cvut.fel.aic.simod.visual.ridesharing.peoplefreightheuristic.SimpleTest + + + + + + + + + + + + + + + + + + + cz.cvut.fel.aic.simod.ridesharing.model.PlanActionDropoff + + + Fields + Properties + + All + private + + diff --git a/local_config_files/10k_requests.cfg b/local_config_files/10k_requests.cfg new file mode 100644 index 00000000..41465fa8 --- /dev/null +++ b/local_config_files/10k_requests.cfg @@ -0,0 +1,46 @@ +simod_data_dir: 'data/' + +experiment_name: 'PFheuristic_10k' + +packages_on: true +trips_filename: 'trips_10k' +packages_filename: 'packages_10k' +packages_max_delay: 0 +packages_capacity: 100 + +vehicles_per_station: 10 + +trips_multiplier: 1.0 +start_time: 0 + +travel_time_provider: 'dm' + + +rebalancing: +{ + on: false +} + +ridesharing: +{ + on: true + + method: 'people-freight-heuristic' + + max_prolongation_in_seconds: 600 +} + +agentpolis: +{ + # srid for New York + srid: 32618 + + # 11,5 hours + simulation_duration: + { + days: 0 + hours: 11 + minutes: 30 + seconds: 0 + } +} diff --git a/local_config_files/20k_10h_base.cfg b/local_config_files/20k_10h_base.cfg new file mode 100644 index 00000000..ec3fe6f9 --- /dev/null +++ b/local_config_files/20k_10h_base.cfg @@ -0,0 +1,46 @@ +simod_data_dir: 'data/' + +experiment_name: 'MULTI_INSERTION_version/20k_10h' + +packages_on: true +trips_filename: 'trips_doubled_20k' +packages_filename: 'packages_doubled_20k' +packages_max_delay: 0 +packages_capacity: 100 + +vehicles_per_station: 12 + +trips_multiplier: 1.0 +start_time: 0 + +travel_time_provider: 'dm' + + +rebalancing: +{ + on: false +} + +ridesharing: +{ + on: true + + method: 'pf-base' + + max_prolongation_in_seconds: 600 +} + +agentpolis: +{ + # srid for New York + srid: 32618 + + # 21 hours + simulation_duration: + { + days: 0 + hours: 12 + minutes: 0 + seconds: 0 + } +} diff --git a/local_config_files/20k_10h_insertion.cfg b/local_config_files/20k_10h_insertion.cfg new file mode 100644 index 00000000..ec3fe6f9 --- /dev/null +++ b/local_config_files/20k_10h_insertion.cfg @@ -0,0 +1,46 @@ +simod_data_dir: 'data/' + +experiment_name: 'MULTI_INSERTION_version/20k_10h' + +packages_on: true +trips_filename: 'trips_doubled_20k' +packages_filename: 'packages_doubled_20k' +packages_max_delay: 0 +packages_capacity: 100 + +vehicles_per_station: 12 + +trips_multiplier: 1.0 +start_time: 0 + +travel_time_provider: 'dm' + + +rebalancing: +{ + on: false +} + +ridesharing: +{ + on: true + + method: 'pf-base' + + max_prolongation_in_seconds: 600 +} + +agentpolis: +{ + # srid for New York + srid: 32618 + + # 21 hours + simulation_duration: + { + days: 0 + hours: 12 + minutes: 0 + seconds: 0 + } +} diff --git a/local_config_files/20k_1h_base.cfg b/local_config_files/20k_1h_base.cfg new file mode 100644 index 00000000..3ce87e9a --- /dev/null +++ b/local_config_files/20k_1h_base.cfg @@ -0,0 +1,46 @@ +simod_data_dir: 'data/' + +experiment_name: 'BASE_version/20k_2h' + +packages_on: true +trips_filename: 'trips_20k_2h' +packages_filename: 'packages_20k_2h' +packages_max_delay: 0 +packages_capacity: 100 + +vehicles_per_station: 50 + +trips_multiplier: 1.0 +start_time: 0 + +travel_time_provider: 'dm' + + +rebalancing: +{ + on: false +} + +ridesharing: +{ + on: true + + method: 'pf-base' + + max_prolongation_in_seconds: 600 +} + +agentpolis: +{ + # srid for New York + srid: 32618 + + # 21 hours + simulation_duration: + { + days: 0 + hours: 4 + minutes: 0 + seconds: 0 + } +} diff --git a/local_config_files/20k_1h_insertion.cfg b/local_config_files/20k_1h_insertion.cfg new file mode 100644 index 00000000..440f3ba9 --- /dev/null +++ b/local_config_files/20k_1h_insertion.cfg @@ -0,0 +1,46 @@ +simod_data_dir: 'data/' + +experiment_name: 'MULTI_INSERTION_version/20k_2h' + +packages_on: true +trips_filename: 'trips_20k_2h' +packages_filename: 'packages_20k_2h' +packages_max_delay: 0 +packages_capacity: 100 + +vehicles_per_station: 50 + +trips_multiplier: 1.0 +start_time: 0 + +travel_time_provider: 'dm' + + +rebalancing: +{ + on: false +} + +ridesharing: +{ + on: true + + method: 'pf-multi-insertion' + + max_prolongation_in_seconds: 600 +} + +agentpolis: +{ + # srid for New York + srid: 32618 + + # 21 hours + simulation_duration: + { + days: 0 + hours: 4 + minutes: 0 + seconds: 0 + } +} diff --git a/local_config_files/20k_2h_base.cfg b/local_config_files/20k_2h_base.cfg new file mode 100644 index 00000000..1dc76ab0 --- /dev/null +++ b/local_config_files/20k_2h_base.cfg @@ -0,0 +1,46 @@ +simod_data_dir: 'data/' + +experiment_name: 'BASE_version/20k_10h' + +packages_on: true +trips_filename: 'trips_20k_10h' +packages_filename: 'packages_20k_10h' +packages_max_delay: 0 +packages_capacity: 100 + +vehicles_per_station: 12 + +trips_multiplier: 1.0 +start_time: 0 + +travel_time_provider: 'dm' + + +rebalancing: +{ + on: false +} + +ridesharing: +{ + on: true + + method: 'pf-base' + + max_prolongation_in_seconds: 600 +} + +agentpolis: +{ + # srid for New York + srid: 32618 + + # 21 hours + simulation_duration: + { + days: 0 + hours: 12 + minutes: 0 + seconds: 0 + } +} diff --git a/local_config_files/20k_2h_insertion.cfg b/local_config_files/20k_2h_insertion.cfg new file mode 100644 index 00000000..ed8e4170 --- /dev/null +++ b/local_config_files/20k_2h_insertion.cfg @@ -0,0 +1,46 @@ +simod_data_dir: 'data/' + +experiment_name: 'MULTI_INSERTION_version/20k_10h' + +packages_on: true +trips_filename: 'trips_20k_10h' +packages_filename: 'packages_20k_10h' +packages_max_delay: 0 +packages_capacity: 100 + +vehicles_per_station: 12 + +trips_multiplier: 1.0 +start_time: 0 + +travel_time_provider: 'dm' + + +rebalancing: +{ + on: false +} + +ridesharing: +{ + on: true + + method: 'pf-multi-insertion' + + max_prolongation_in_seconds: 600 +} + +agentpolis: +{ + # srid for New York + srid: 32618 + + # 21 hours + simulation_duration: + { + days: 0 + hours: 12 + minutes: 0 + seconds: 0 + } +} diff --git a/local_config_files/20k_base.cfg b/local_config_files/20k_base.cfg new file mode 100644 index 00000000..35e6abf5 --- /dev/null +++ b/local_config_files/20k_base.cfg @@ -0,0 +1,46 @@ +simod_data_dir: 'data/' + +experiment_name: 'BASE_version/20k' + +packages_on: true +trips_filename: 'trips_20k' +packages_filename: 'packages_20k' +packages_max_delay: 0 +packages_capacity: 100 + +vehicles_per_station: 10 + +trips_multiplier: 1.0 +start_time: 0 + +travel_time_provider: 'dm' + + +rebalancing: +{ + on: false +} + +ridesharing: +{ + on: true + + method: 'pf-base' + + max_prolongation_in_seconds: 600 +} + +agentpolis: +{ + # srid for New York + srid: 32618 + + # 21 hours + simulation_duration: + { + days: 0 + hours: 21 + minutes: 0 + seconds: 0 + } +} diff --git a/local_config_files/20k_insertion.cfg b/local_config_files/20k_insertion.cfg new file mode 100644 index 00000000..35e6abf5 --- /dev/null +++ b/local_config_files/20k_insertion.cfg @@ -0,0 +1,46 @@ +simod_data_dir: 'data/' + +experiment_name: 'BASE_version/20k' + +packages_on: true +trips_filename: 'trips_20k' +packages_filename: 'packages_20k' +packages_max_delay: 0 +packages_capacity: 100 + +vehicles_per_station: 10 + +trips_multiplier: 1.0 +start_time: 0 + +travel_time_provider: 'dm' + + +rebalancing: +{ + on: false +} + +ridesharing: +{ + on: true + + method: 'pf-base' + + max_prolongation_in_seconds: 600 +} + +agentpolis: +{ + # srid for New York + srid: 32618 + + # 21 hours + simulation_duration: + { + days: 0 + hours: 21 + minutes: 0 + seconds: 0 + } +} diff --git a/local_config_files/24k_24h_manhattan_base.cfg b/local_config_files/24k_24h_manhattan_base.cfg new file mode 100644 index 00000000..f3f5ddb0 --- /dev/null +++ b/local_config_files/24k_24h_manhattan_base.cfg @@ -0,0 +1,48 @@ +simod_data_dir: 'data/' + +experiment_name: 'BASE_version/24k_24h_manhattan' + +packages_on: true +# data from 2014-01-20 - half +trips_filename: 'people_manhattan_24k_24h' +# data from 2014-01-20 - other half +packages_filename: 'packages_manhattan_24k_24h' +packages_max_delay: 0 +packages_capacity: 100 + +vehicles_per_station: 15 + +trips_multiplier: 1.0 +start_time: 0 + +travel_time_provider: 'dm' + + +rebalancing: +{ + on: false +} + +ridesharing: +{ + on: true + + method: 'pf-base' + + max_prolongation_in_seconds: 600 +} + +agentpolis: +{ + # srid for New York + srid: 32618 + + # 25 hours + simulation_duration: + { + days: 0 + hours: 25 + minutes: 0 + seconds: 0 + } +} diff --git a/local_config_files/24k_24h_manhattan_insertion.cfg b/local_config_files/24k_24h_manhattan_insertion.cfg new file mode 100644 index 00000000..c34da30a --- /dev/null +++ b/local_config_files/24k_24h_manhattan_insertion.cfg @@ -0,0 +1,48 @@ +simod_data_dir: 'data/' + +experiment_name: 'INSERTION_version/24k_24h_manhattan' + +packages_on: true +# data from 2014-01-20 - half +trips_filename: 'people_manhattan_24k_24h' +# data from 2014-01-20 - other half +packages_filename: 'packages_manhattan_24k_24h' +packages_max_delay: 0 +packages_capacity: 100 + +vehicles_per_station: 15 + +trips_multiplier: 1.0 +start_time: 0 + +travel_time_provider: 'dm' + + +rebalancing: +{ + on: false +} + +ridesharing: +{ + on: true + + method: 'pf-multi-insertion' + + max_prolongation_in_seconds: 600 +} + +agentpolis: +{ + # srid for New York + srid: 32618 + + # 25 hours + simulation_duration: + { + days: 0 + hours: 25 + minutes: 0 + seconds: 0 + } +} diff --git a/local_config_files/24k_24h_manhattan_multipass.cfg b/local_config_files/24k_24h_manhattan_multipass.cfg new file mode 100644 index 00000000..5aa0f028 --- /dev/null +++ b/local_config_files/24k_24h_manhattan_multipass.cfg @@ -0,0 +1,48 @@ +simod_data_dir: 'data/' + +experiment_name: 'MULTIPASS_version/24k_24h_manhattan' + +packages_on: true +# data from 2014-01-20 - half +trips_filename: 'people_manhattan_24k_24h' +# data from 2014-01-20 - other half +packages_filename: 'packages_manhattan_24k_24h' +packages_max_delay: 0 +packages_capacity: 100 + +vehicles_per_station: 15 + +trips_multiplier: 1.0 +start_time: 0 + +travel_time_provider: 'dm' + + +rebalancing: +{ + on: false +} + +ridesharing: +{ + on: true + + method: 'pf-multipass' + + max_prolongation_in_seconds: 600 +} + +agentpolis: +{ + # srid for New York + srid: 32618 + + # 25 hours + simulation_duration: + { + days: 0 + hours: 25 + minutes: 0 + seconds: 0 + } +} diff --git a/local_config_files/25k_1h_manhattan_base.cfg b/local_config_files/25k_1h_manhattan_base.cfg new file mode 100644 index 00000000..b8f40c6b --- /dev/null +++ b/local_config_files/25k_1h_manhattan_base.cfg @@ -0,0 +1,48 @@ +simod_data_dir: 'data/' + +experiment_name: 'BASE_version/25k_1h_manhattan' + +packages_on: true +# data from monday 2014-01-12 from 0h to 1h - half +trips_filename: 'people_manhattan_25k_1h' +# data from monday 2014-01-12 from 0h to 1h - other half +packages_filename: 'packages_manhattan_25k_1h' +packages_max_delay: 0 +packages_capacity: 100 + +vehicles_per_station: 125 + +trips_multiplier: 1.0 +start_time: 0 + +travel_time_provider: 'dm' + + +rebalancing: +{ + on: false +} + +ridesharing: +{ + on: true + + method: 'pf-base' + + max_prolongation_in_seconds: 600 +} + +agentpolis: +{ + # srid for New York + srid: 32618 + + # 21 hours + simulation_duration: + { + days: 0 + hours: 4 + minutes: 0 + seconds: 0 + } +} diff --git a/local_config_files/25k_1h_manhattan_insertion.cfg b/local_config_files/25k_1h_manhattan_insertion.cfg new file mode 100644 index 00000000..b1e25a69 --- /dev/null +++ b/local_config_files/25k_1h_manhattan_insertion.cfg @@ -0,0 +1,48 @@ +simod_data_dir: 'data/' + +experiment_name: 'INSERTION_version/25k_1h_manhattan' + +packages_on: true +# data from 2014-01-01 from 0h to 1h - half +trips_filename: 'people_manhattan_25k_1h' +# data from 2014-01-01 from 0h to 1h - other half +packages_filename: 'packages_manhattan_25k_1h' +packages_max_delay: 0 +packages_capacity: 100 + +vehicles_per_station: 125 + +trips_multiplier: 1.0 +start_time: 0 + +travel_time_provider: 'dm' + + +rebalancing: +{ + on: false +} + +ridesharing: +{ + on: true + + method: 'pf-multi-insertion' + + max_prolongation_in_seconds: 600 +} + +agentpolis: +{ + # srid for New York + srid: 32618 + + # 21 hours + simulation_duration: + { + days: 0 + hours: 4 + minutes: 0 + seconds: 0 + } +} diff --git a/local_config_files/25k_1h_manhattan_multipass.cfg b/local_config_files/25k_1h_manhattan_multipass.cfg new file mode 100644 index 00000000..b1a3cb73 --- /dev/null +++ b/local_config_files/25k_1h_manhattan_multipass.cfg @@ -0,0 +1,48 @@ +simod_data_dir: 'data/' + +experiment_name: 'MULTIPASS_version/25k_1h_manhattan' + +packages_on: true +# data from monday 2014-01-12 from 0h to 1h - half +trips_filename: 'people_manhattan_25k_1h' +# data from monday 2014-01-12 from 0h to 1h - other half +packages_filename: 'packages_manhattan_25k_1h' +packages_max_delay: 0 +packages_capacity: 100 + +vehicles_per_station: 125 + +trips_multiplier: 1.0 +start_time: 0 + +travel_time_provider: 'dm' + + +rebalancing: +{ + on: false +} + +ridesharing: +{ + on: true + + method: 'pf-multipass' + + max_prolongation_in_seconds: 600 +} + +agentpolis: +{ + # srid for New York + srid: 32618 + + # 21 hours + simulation_duration: + { + days: 0 + hours: 4 + minutes: 0 + seconds: 0 + } +} diff --git a/local_config_files/2k_requests.cfg b/local_config_files/2k_requests.cfg new file mode 100644 index 00000000..76204ab8 --- /dev/null +++ b/local_config_files/2k_requests.cfg @@ -0,0 +1,46 @@ +simod_data_dir: 'data/' + +experiment_name: 'PFheuristic_2k' + +packages_on: true +trips_filename: 'trips_2k' +packages_filename: 'packages_2k' +packages_max_delay: 0 +packages_capacity: 100 + +vehicles_per_station: 10 + +trips_multiplier: 1.0 +start_time: 0 + +travel_time_provider: 'dm' + + +rebalancing: +{ + on: false +} + +ridesharing: +{ + on: true + + method: 'people-freight-heuristic' + + max_prolongation_in_seconds: 600 +} + +agentpolis: +{ + # srid for New York + srid: 32618 + + # 3 hours + simulation_duration: + { + days: 0 + hours: 3 + minutes: 0 + seconds: 0 + } +} diff --git a/local_config_files/50k_1h_manhattan_base.cfg b/local_config_files/50k_1h_manhattan_base.cfg new file mode 100644 index 00000000..4e7fdba0 --- /dev/null +++ b/local_config_files/50k_1h_manhattan_base.cfg @@ -0,0 +1,48 @@ +simod_data_dir: 'data/' + +experiment_name: 'BASE_version/50k_1h_manhattan' + +packages_on: true +# data from 2014-01-01 from 0h to 1h +trips_filename: 'people_manhattan_50k_1h' +# data from 2014-01-01 from 1h to 2h +packages_filename: 'packages_manhattan_50k_1h' +packages_max_delay: 0 +packages_capacity: 100 + +vehicles_per_station: 225 + +trips_multiplier: 1.0 +start_time: 46800000 + +travel_time_provider: 'dm' + + +rebalancing: +{ + on: false +} + +ridesharing: +{ + on: true + + method: 'pf-base' + + max_prolongation_in_seconds: 600 +} + +agentpolis: +{ + # srid for New York + srid: 32618 + + # 4 hours + simulation_duration: + { + days: 0 + hours: 4 + minutes: 0 + seconds: 0 + } +} diff --git a/local_config_files/50k_1h_manhattan_insertion.cfg b/local_config_files/50k_1h_manhattan_insertion.cfg new file mode 100644 index 00000000..4c48fce1 --- /dev/null +++ b/local_config_files/50k_1h_manhattan_insertion.cfg @@ -0,0 +1,48 @@ +simod_data_dir: 'data/' + +experiment_name: 'INSERTION_version/50k_1h_manhattan' + +packages_on: true +# data from 2014-01-01 from 0h to 1h +trips_filename: 'people_manhattan_50k_1h' +# data from 2014-01-01 from 1h to 2h +packages_filename: 'packages_manhattan_50k_1h' +packages_max_delay: 0 +packages_capacity: 100 + +vehicles_per_station: 225 + +trips_multiplier: 1.0 +start_time: 46800000 + +travel_time_provider: 'dm' + + +rebalancing: +{ + on: false +} + +ridesharing: +{ + on: true + + method: 'pf-multi-insertion' + + max_prolongation_in_seconds: 600 +} + +agentpolis: +{ + # srid for New York + srid: 32618 + + # 4 hours + simulation_duration: + { + days: 0 + hours: 4 + minutes: 0 + seconds: 0 + } +} diff --git a/local_config_files/50k_1h_manhattan_multipass.cfg b/local_config_files/50k_1h_manhattan_multipass.cfg new file mode 100644 index 00000000..233dc1a4 --- /dev/null +++ b/local_config_files/50k_1h_manhattan_multipass.cfg @@ -0,0 +1,48 @@ +simod_data_dir: 'data/' + +experiment_name: 'MULTIPASS_version/50k_1h_manhattan' + +packages_on: true +# data from 2014-01-01 from 0h to 1h +trips_filename: 'people_manhattan_50k_1h' +# data from 2014-01-01 from 1h to 2h +packages_filename: 'packages_manhattan_50k_1h' +packages_max_delay: 0 +packages_capacity: 100 + +vehicles_per_station: 225 + +trips_multiplier: 1.0 +start_time: 46800000 + +travel_time_provider: 'dm' + + +rebalancing: +{ + on: false +} + +ridesharing: +{ + on: true + + method: 'pf-multipass' + + max_prolongation_in_seconds: 600 +} + +agentpolis: +{ + # srid for New York + srid: 32618 + + # 4 hours + simulation_duration: + { + days: 0 + hours: 4 + minutes: 0 + seconds: 0 + } +} diff --git a/local_config_files/5k_requests.cfg b/local_config_files/5k_requests.cfg new file mode 100644 index 00000000..e730e39d --- /dev/null +++ b/local_config_files/5k_requests.cfg @@ -0,0 +1,46 @@ +simod_data_dir: 'data/' + +experiment_name: 'PFheuristic_5k' + +packages_on: true +trips_filename: 'trips_5k' +packages_filename: 'packages_5k' +packages_max_delay: 0 +packages_capacity: 100 + +vehicles_per_station: 10 + +trips_multiplier: 1.0 +start_time: 0 + +travel_time_provider: 'dm' + + +rebalancing: +{ + on: false +} + +ridesharing: +{ + on: true + + method: 'people-freight-heuristic' + + max_prolongation_in_seconds: 600 +} + +agentpolis: +{ + # srid for New York + srid: 32618 + + # 6 hours + simulation_duration: + { + days: 0 + hours: 6 + minutes: 0 + seconds: 0 + } +} diff --git a/local_config_files/static_20k.cfg b/local_config_files/static_20k.cfg new file mode 100644 index 00000000..45d6963f --- /dev/null +++ b/local_config_files/static_20k.cfg @@ -0,0 +1,46 @@ +simod_data_dir: 'data/' + +experiment_name: 'PFheuristic_static_20k' + +packages_on: true +trips_filename: 'trips_static_20k' +packages_filename: 'packages_static_20k' +packages_max_delay: 36000 +packages_capacity: 100 + +vehicles_per_station: 10 + +trips_multiplier: 1.0 +start_time: 0 + +travel_time_provider: 'dm' + + +rebalancing: +{ + on: false +} + +ridesharing: +{ + on: true + + method: 'people-freight-heuristic' + + max_prolongation_in_seconds: 600 +} + +agentpolis: +{ + # srid for New York + srid: 32618 + + # 21 hours + simulation_duration: + { + days: 0 + hours: 21 + minutes: 0 + seconds: 0 + } +} diff --git a/local_config_files/static_20k_10h_base.cfg b/local_config_files/static_20k_10h_base.cfg new file mode 100644 index 00000000..f85b518c --- /dev/null +++ b/local_config_files/static_20k_10h_base.cfg @@ -0,0 +1,46 @@ +simod_data_dir: 'data/' + +experiment_name: 'MULTI_INSERTION_version/20k_10h_static' + +packages_on: true +trips_filename: 'trips_static_20k_10h' +packages_filename: 'packages_static_20k_10h' +packages_max_delay: 36000 +packages_capacity: 100 + +vehicles_per_station: 12 + +trips_multiplier: 1.0 +start_time: 0 + +travel_time_provider: 'dm' + + +rebalancing: +{ + on: false +} + +ridesharing: +{ + on: true + + method: 'pf-multi-insertion' + + max_prolongation_in_seconds: 600 +} + +agentpolis: +{ + # srid for New York + srid: 32618 + + # 21 hours + simulation_duration: + { + days: 0 + hours: 12 + minutes: 0 + seconds: 0 + } +} diff --git a/local_config_files/static_20k_10h_insertion.cfg b/local_config_files/static_20k_10h_insertion.cfg new file mode 100644 index 00000000..ee27291c --- /dev/null +++ b/local_config_files/static_20k_10h_insertion.cfg @@ -0,0 +1,46 @@ +simod_data_dir: 'data/' + +experiment_name: 'PASS_STOPS_version/20k_10h_static' + +packages_on: true +trips_filename: 'trips_doubled_static_20k' +packages_filename: 'packages_doubled_static_20k' +packages_max_delay: 36000 +packages_capacity: 100 + +vehicles_per_station: 10 + +trips_multiplier: 1.0 +start_time: 0 + +travel_time_provider: 'dm' + + +rebalancing: +{ + on: false +} + +ridesharing: +{ + on: true + + method: 'people-freight-heuristic' + + max_prolongation_in_seconds: 600 +} + +agentpolis: +{ + # srid for New York + srid: 32618 + + # 21 hours + simulation_duration: + { + days: 0 + hours: 12 + minutes: 0 + seconds: 0 + } +} diff --git a/python/simod/config/comparison.py b/python/simod/config/comparison.py index 4b8dfb37..0dd7d756 100644 --- a/python/simod/config/comparison.py +++ b/python/simod/config/comparison.py @@ -22,4 +22,16 @@ def __init__(self, properties: dict = None): self.experiment_9_dir = properties.get("experiment_9_dir") self.experiment_10_name = properties.get("experiment_10_name") self.experiment_10_dir = properties.get("experiment_10_dir") + self.experiment_11_name = properties.get("experiment_11_name") + self.experiment_11_dir = properties.get("experiment_11_dir") + self.experiment_12_name = properties.get("experiment_12_name") + self.experiment_12_dir = properties.get("experiment_12_dir") + self.experiment_13_name = properties.get("experiment_13_name") + self.experiment_13_dir = properties.get("experiment_13_dir") + self.experiment_14_name = properties.get("experiment_14_name") + self.experiment_14_dir = properties.get("experiment_14_dir") + self.experiment_15_name = properties.get("experiment_15_name") + self.experiment_15_dir = properties.get("experiment_15_dir") + self.experiment_16_name = properties.get("experiment_16_name") + self.experiment_16_dir = properties.get("experiment_16_dir") pass diff --git a/python/simod/config/statistics.py b/python/simod/config/statistics.py index c65dd304..2e764e44 100644 --- a/python/simod/config/statistics.py +++ b/python/simod/config/statistics.py @@ -6,8 +6,19 @@ def __init__(self, properties: dict = None): self.result_file_path = properties.get("result_file_path") self.all_edges_load_history_file_name = properties.get("all_edges_load_history_file_name") self.all_edges_load_history_file_path = properties.get("all_edges_load_history_file_path") + self.occupancies_file_name = properties.get("occupancies_file_name") self.occupancies_file_path = properties.get("occupancies_file_path") + self.packages_occupancies_file_name = properties.get("packages_occupancies_file_name") + self.packages_occupancies_file_path = properties.get("packages_occupancies_file_path") + self.combined_occupancies_file_path = properties.get("combined_occupancies_file_path") + self.combined_occupancies_file_name = properties.get("combined_occupancies_file_name") + + self.no_people_occupancies_file_name = properties.get("no_people_occupancies_file_name") + self.no_people_occupancies_file_path = properties.get("no_people_occupancies_file_path") + self.people_onboard_occupancies_file_name = properties.get("people_onboard_occupancies_file_name") + self.people_onboard_occupancies_file_path = properties.get("people_onboard_occupancies_file_path") + self.service_file_name = properties.get("service_file_name") self.transit_file_name = properties.get("transit_file_name") self.ridesharing_stats_file_name = properties.get("ridesharing_stats_file_name") diff --git a/python/simod/resources/blaham17_statistics.cfg b/python/simod/resources/blaham17_statistics.cfg new file mode 100644 index 00000000..62e7d08a --- /dev/null +++ b/python/simod/resources/blaham17_statistics.cfg @@ -0,0 +1,79 @@ +simod_data_dir: 'data/' +map_dir: '/home/martin/Documents/01_Bakalarka/01_simod/data/maps/' + +experiments_dir: '/home/martin/Documents/01_Bakalarka/01_simod/data/experiments/' + +experiment_dir: $experiments_dir + 'BASE_version/20k' + +statistics: +{ + result_file_name: 'result.json' + #result_file_path: $experiment_dir + $statistics.result_file_name + occupancies_file_name: 'vehicle_occupancy.csv' + #occupancies_file_path: $experiment_dir + $statistics.occupancies_file_name + packages_occupancies_file_name: 'packages_occupancy.csv' + #packages_occupancies_file_path: $experiment_dir + $statistics.packages_occupancies_file_name + combined_occupancies_file_name: 'combined_occupancy.csv' + #combined_occupancies_file_path: $experiment_dir + $statistics.combined_occupancies_file_name + + service_file_name: 'service.csv' + transit_file_name: 'transit.csv' + ridesharing_stats_file_name: 'ridesharing.csv' + #trip_distances_file_path: $experiment_dir + 'demand_trip_lengths.csv' +} + +comparison: +{ + experiment_8_name: 'BASE_version/25k_1h_manhattan' + experiment_8_dir: $experiments_dir + $comparison.experiment_8_name + '/' + + experiment_9_name: 'MULTIPASS_version/25k_1h_manhattan' + experiment_9_dir: $experiments_dir + $comparison.experiment_9_name + '/' + + experiment_10_name: 'INSERTION_version/25k_1h_manhattan' + experiment_10_dir: $experiments_dir + $comparison.experiment_10_name + '/' + + experiment_11_name: 'BASE_version/50k_1h_manhattan' + experiment_11_dir: $experiments_dir + $comparison.experiment_11_name + '/' + + experiment_12_name: 'MULTIPASS_version/50k_1h_manhattan' + experiment_12_dir: $experiments_dir + $comparison.experiment_12_name + '/' + + experiment_13_name: 'INSERTION_version/50k_1h_manhattan' + experiment_13_dir: $experiments_dir + $comparison.experiment_13_name + '/' + + experiment_14_name: 'BASE_version/24k_24h_manhattan' + experiment_14_dir: $experiments_dir + $comparison.experiment_14_name + '/' + + experiment_15_name: 'MULTIPASS_version/24k_24h_manhattan' + experiment_15_dir: $experiments_dir + $comparison.experiment_15_name + '/' + + experiment_16_name: 'INSERTION_version/24k_24h_manhattan' + experiment_16_dir: $experiments_dir + $comparison.experiment_16_name + '/' + + # experiment_1_name: 'BASE_version/20k' + # experiment_1_dir: $experiments_dir + $comparison.experiment_1_name + '/' + # + # experiment_2_name: 'INSERTION_version/20k' + # experiment_2_dir: $experiments_dir + $comparison.experiment_2_name + '/' + # + # experiment_3_name: 'BASE_version/20k_10h' + # experiment_3_dir: $experiments_dir + $comparison.experiment_3_name + '/' + # + # experiment_4_name: 'INSERTION_version/20k_10h' + # experiment_4_dir: $experiments_dir + $comparison.experiment_4_name + '/' + # + # experiment_5_name: 'BASE_version/20k_2h' + # experiment_5_dir: $experiments_dir + $comparison.experiment_5_name + '/' + # + # experiment_6_name: 'INSERTION_version/20k_2h' + # experiment_6_dir: $experiments_dir + $comparison.experiment_6_name + '/' + # + # experiment_7_name: 'BASE_version/20k_1h' + # experiment_7_dir: $experiments_dir + $comparison.experiment_7_name + '/' + # + + +} + + diff --git a/python/simod/resources/config.cfg b/python/simod/resources/config.cfg index 98fa811e..229990cf 100644 --- a/python/simod/resources/config.cfg +++ b/python/simod/resources/config.cfg @@ -37,6 +37,14 @@ statistics: all_edges_load_history_file_path: $experiment_dir + $statistics.all_edges_load_history_file_name occupancies_file_name: 'vehicle_occupancy.csv' occupancies_file_path: $experiment_dir + $statistics.occupancies_file_name + packages_occupancies_file_name: 'packages_occupancy.csv' + packages_occupancies_file_path: $experiment_dir + $statistics.packages_occupancies_file_name + + no_people_occupancies_file_name: 'no_people_occupancies_file_name.csv' + no_people_occupancies_file_path: $experiment_dir + $statistics.no_people_occupancies_file_name + people_onboard_occupancies_file_name: 'people_onboard_occupancies_file_name.csv' + people_onboard_occupancies_file_path: $experiment_dir + $statistics.people_onboard_occupancies_file_name + service_file_name: 'service.csv' transit_file_name: 'transit.csv' ridesharing_stats_file_name: 'ridesharing.csv' @@ -88,34 +96,33 @@ images: comparison: { - #experiment_1_name: 'insertion-heuristic-capacity1-weight0' - experiment_1_name: 'ih-nr' + experiment_1_name: 'PFheuristic_20k' experiment_1_dir: $experiments_dir + $comparison.experiment_1_name + '/' + #experiment_2_name: 'insertion-heuristic-weight0' - experiment_2_name: 'ih' - experiment_2_dir: $experiments_dir + $comparison.experiment_2_name + '/' +# experiment_2_name: 'ih' #experiment_3_name: 'vga-weight0' - experiment_3_name: 'vga_gap_0002' - experiment_3_dir: $experiments_dir + $comparison.experiment_3_name + '/' +# experiment_3_name: 'vga_gap_0002' +# experiment_3_dir: $experiments_dir + $comparison.experiment_3_name + '/' #experiment_4_name: 'vga-limited-weight0-lim30ms' - experiment_4_name: 'vga-lim_gap_005_gg_60ms' - experiment_4_dir: $experiments_dir + $comparison.experiment_4_name + '/' +# experiment_4_name: 'vga-lim_gap_005_gg_60ms' +# experiment_4_dir: $experiments_dir + $comparison.experiment_4_name + '/' #experiment_5_name: 'insertion-heuristic-capacity1-second-window-weight0' - experiment_5_name: 'sw-ih-nr' - experiment_5_dir: $experiments_dir + $comparison.experiment_5_name + '/' +# experiment_5_name: 'sw-ih-nr' +# experiment_5_dir: $experiments_dir + $comparison.experiment_5_name + '/' #experiment_6_name: 'insertion-heuristic-second-window-weight0' - experiment_6_name: 'sw-ih' - experiment_6_dir: $experiments_dir + $comparison.experiment_6_name + '/' +# experiment_6_name: 'sw-ih' +# experiment_6_dir: $experiments_dir + $comparison.experiment_6_name + '/' #experiment_7_name: 'vga-second-window-weight0' - experiment_7_name: 'sw-vga-gap_0002' - experiment_7_dir: $experiments_dir + $comparison.experiment_7_name + '/' +# experiment_7_name: 'sw-vga-gap_0002' +# experiment_7_dir: $experiments_dir + $comparison.experiment_7_name + '/' #experiment_8_name: 'vga-lim30ms-sw-weight0' - experiment_8_name: 'sw-vga-lim_gap_005_gg_60ms' - experiment_8_dir: $experiments_dir + $comparison.experiment_8_name + '/' - experiment_9_name: 'vga-pnas' - experiment_9_dir: $experiments_dir + $comparison.experiment_9_name + '/' - experiment_10_name: 'sw-vga-pnas' - experiment_10_dir: $experiments_dir + $comparison.experiment_10_name + '/' +# experiment_8_name: 'sw-vga-lim_gap_005_gg_60ms' +# experiment_8_dir: $experiments_dir + $comparison.experiment_8_name + '/' +# experiment_9_name: 'vga-pnas' +# experiment_9_dir: $experiments_dir + $comparison.experiment_9_name + '/' +# experiment_10_name: 'sw-vga-pnas' +# experiment_10_dir: $experiments_dir + $comparison.experiment_10_name + '/' } ridesharing: diff --git a/python/simod/statistics/comparisons/common.py b/python/simod/statistics/comparisons/common.py index efc0749d..55f4d870 100644 --- a/python/simod/statistics/comparisons/common.py +++ b/python/simod/statistics/comparisons/common.py @@ -21,12 +21,14 @@ class Experiment(Enum): - PRESENT_STATE = (0, "grey", "ooo", "Present State", 'o') - NO_RIDESHARING = (1, "red", "+++", "No Ridesharing", '+') - IH = (2, "green", "///", "Insertion Heuristic", '/') - VGA = (3, "blue", "\\\\\\", "VGA (optimal)", 'v') - VGA_LIMITED = (4, "orange", "***", "VGA (limited)", '*') - VGA_PNAS = (4, "darkcyan", "---", "VGA (PNAS)", 's') + # PRESENT_STATE = (0, "grey", "ooo", "Present State", 'o') + PFH = (2, "green", "///", "PeopleFreight Heuristic", '/') + # PRESENT_STATE = (0, "grey", "ooo", "Present State", 'o') + # NO_RIDESHARING = (1, "red", "+++", "No Ridesharing", '+') + # IH = (2, "green", "///", "Insertion Heuristic", '/') + # VGA = (3, "blue", "\\\\\\", "VGA (optimal)", 'v') + # VGA_LIMITED = (4, "orange", "***", "VGA (limited)", '*') + # VGA_PNAS = (4, "darkcyan", "---", "VGA (PNAS)", 's') def __init__(self, index, color, pattern, label, marker): self.color = color diff --git a/python/simod/statistics/comparisons/create_road_graph.py b/python/simod/statistics/comparisons/create_road_graph.py new file mode 100644 index 00000000..b0c004b6 --- /dev/null +++ b/python/simod/statistics/comparisons/create_road_graph.py @@ -0,0 +1,95 @@ + +import geopandas as gpd +import contextily as ctx +# import matplotlib.pyplot as plt +# import pandas as pd +# import seaborn as sns +# import shapely +# # from mpl_toolkits.basemap import Basemap +# import rasterio.crs +from ctypes.util import find_library + + +def add_basemap(ax, zoom, url='http://tile.stamen.com/terrain/tileZ/tileX/tileY.png'): + xmin, xmax, ymin, ymax = ax.axis() + basemap, extent = ctx.bounds2img(xmin, ymin, xmax, ymax, zoom=zoom, source=url) + ax.imshow(basemap, extent=extent, interpolation='bilinear') + # restore original x/y limits + ax.axis((xmin, xmax, ymin, ymax)) + + + +# find_library('geos_c') + +# loading the edges +data = gpd.read_file('/home/martin/Documents/01_Bakalarka/01_simod/data/maps/edges.geojson') +data_edges = data.geometry +data_edges.columns = ["start_pt", "end_pt"] +# print(data_edges[["start_pt"]]) + +save_dir = '/home/martin/Documents/01_Bakalarka/02_PLOTS_RESULTS/' + +print(data_edges) + +""" +# data = pd.read_csv('/home/martin/Documents/01_Bakalarka/03_DATA/manhattan_trips_13_to_14_50k.txt', sep=" ", header=None) +# data.columns = ["time", "y", "x", "y2", "x2", "count", "weight"] +# data_part1 = data[['y', 'x']] +# data_part2 = data[['y2', 'x2']] +# +# new_data = pd.concat([data_part1, data_part2.rename(columns={'y2': 'y', 'x2': 'x'})], ignore_index=True) +# new_data = new_data.reset_index() +# +""" + + + +# gdf = gpd.GeoDataFrame(data_edges, geometry=gpd.points_from_xy(data_edges.geometry, new_data.x), crs='EPSG:4326') +# +# +# gdf.geometry.map(lambda polygon: shapely.ops.transform(lambda x, y: (y, x), polygon)) +# +# gdf = gdf.set_crs(epsg='4326', allow_override=True) +# gdf = gdf['geometry'] +# +# df_wm = gdf.to_crs(epsg=3857) +# # ax = gdf.plot(figsize=(10, 10), alpha=0.7, c='grey') +# +# # ax = gdf.plot(figsize=(10, 10), alpha=0, c='grey') +# # ctx.add_basemap(ax, crs='EPSG:3857', source=ctx.providers.Stamen.TonerLite) +# +# +# # ------------------------------------------------------------------------------------------------------------ +# # ------------------------------------------------------------------------------------------------------------ +# +# ax = gdf.plot(figsize=(10, 10), alpha=0.1, c='grey') +# +# ctx.add_basemap(ax, zoom=18) +# ctx.add_basemap(ax, crs=df_wm.crs.to_string(), zoom=10) +# # m.shadedrelief() +# +# minx, miny, maxx, maxy = data_edges.total_bounds +# +# print(minx, maxx, miny, maxy) +# +# ax = gdf.plot(figsize=(10, 10), alpha=0.5, edgecolor='b') +# +# add_basemap(ax, zoom=10) +# ctx.add_basemap(ax, crs=gdf.crs, zoom=10) +# +# ctx.add_basemap(ax, zoom=12, source=ctx.providers.OpenStreetMap.Mapnik) +# ctx.add_basemap(ax, crs=gdf.crs, source=ctx.providers.OpenStreetMap.Mapnik) +# ctx.add_basemap(ax, source=ctx.providers.Stamen.TonerLite) +# ctx.add_basemap(ax, source=ctx.providers.Stamen.TonerLite, crs=gdf.crs.to_string()) +# +# # ax.get_xaxis().set_ticks([]) +# # ax.get_yaxis().set_ticks([]) +# ax.set_ylabel('') +# ax.set_xlabel('') +# +# plt.savefig(save_dir + 'road_graph', bbox_inches='tight', transparent=True) +# plt.savefig(save_dir + 'demand_locations', bbox_inches='tight', transparent=True) +# # plt.savefig(save_dir + 'demand_heatmap', bbox_inches='tight', transparent=True) +# +# plt.show() +# diff --git a/python/simod/statistics/comparisons/delay_comparison.py b/python/simod/statistics/comparisons/delay_comparison.py index 3f9111b2..ac3a1234 100644 --- a/python/simod/statistics/comparisons/delay_comparison.py +++ b/python/simod/statistics/comparisons/delay_comparison.py @@ -29,7 +29,7 @@ FONT_SIZE = 18 -matplotlib.rcParams['text.usetex'] = True +matplotlib.rcParams['text.usetex'] = False matplotlib.rcParams.update({'font.size': FONT_SIZE}) @@ -100,7 +100,7 @@ def configure_subplot(axis): plt.legend(loc='upper right') -plt.savefig(config.images.delay_histogram_comparison, bbox_inches='tight', transparent=True) +# plt.savefig(config.images.delay_histogram_comparison, bbox_inches='tight', transparent=True) # combined plots @@ -141,7 +141,7 @@ def configure_subplot(axis): plt.legend(loc='upper right', labelspacing=0.01) -plt.savefig(config.images.delay_histogram_comparison_combined, bbox_inches='tight', transparent=True, pad_inches=0.0, dpi=fig.dpi) +# plt.savefig(config.images.delay_histogram_comparison_combined, bbox_inches='tight', transparent=True, pad_inches=0.0, dpi=fig.dpi) plt.show() diff --git a/python/simod/statistics/comparisons/demands_histogram.py b/python/simod/statistics/comparisons/demands_histogram.py new file mode 100644 index 00000000..8d2e1fc5 --- /dev/null +++ b/python/simod/statistics/comparisons/demands_histogram.py @@ -0,0 +1,125 @@ + +import numpy as np +import pandas as pd +import matplotlib.pyplot as plt +import matplotlib.dates as dates +from matplotlib.ticker import FuncFormatter +from matplotlib.ticker import MaxNLocator, FixedLocator + +bins = 12 +labels = [(str(n) + ":00") for n in range(25)] +# labels = ["0:" + (str(5*n)) for n in range(bins + 1)] +xs = range(bins + 1) + +def format_time(miliseconds: int, position) -> str: + # return str(datetime.timedelta(minutes=minutes)) + return str(int(round(miliseconds / 1000 / 60 / 60))) + ":" + str(int(round(miliseconds / 1000 / 60))) + +def format_fn(tick_val, tick_pos): + if int(tick_val) in xs: + return labels[int(tick_val)] + else: + return '' + +def format_hours(tick_value, tick_index): + return str(tick_value) + ":00" + +def format_hours_to_minutes(tick_value, tick_index): + minutes = np.round(60 * (tick_value - 13)).astype(int) + if minutes < 10: + str_minutes = "0:0" + str(minutes) + elif minutes == 60: + str_minutes = "1:00" + else: + str_minutes = "0:" + str(minutes) + return str_minutes + +# bins = np.arange(0, 1000*60*60*24, 1000*60*60) + +# demands_24k = pd.read_csv('/home/martin/Documents/01_Bakalarka/03_DATA/manhattan_taxi_data_01_12_24k.txt', sep=" ", header=None) +# demands_24k.columns = ["time", "y", "x", "y2", "x2", "count", "newline"] +# demands_24_times = demands_24k["time"] / (1000*60*60) +# +# fig, axes = plt.subplots(1, 1, figsize=(10, 5)) +# plt.xticks(np.arange(0, 25, 2)) +# # plt.xticks(rotation=-45) +# axes.xaxis.set_major_formatter(format_hours) +# _n, _bins, patches = axes.hist(demands_24_times, bins) + + +# demands_25k = pd.read_csv('/home/martin/Documents/01_Bakalarka/03_DATA/manhattan_trips_0_to_1.txt', sep=" ", header=None) +# demands_25k.columns = ["time", "y", "x", "y2", "x2", "count", "newline"] +# demands_25_times = demands_25k["time"] / (1000*60*60) +# +# fig, axes = plt.subplots(1, 1, figsize=(10, 5)) +# plt.xticks(np.arange(0, 1.01, (1/12))) +# axes.xaxis.set_major_formatter(format_hours_to_minutes) +# _n, _bins, patches = axes.hist(demands_25_times, bins) + + +demands_50k = pd.read_csv('/home/martin/Documents/01_Bakalarka/03_DATA/manhattan_trips_13_to_14_50k.txt', sep=" ", header=None) +demands_50k.columns = ["time", "y", "x", "y2", "x2", "count", "newline"] +demands_50_times = demands_50k["time"] / (1000*60*60) + +fig, axes = plt.subplots(1, 1, figsize=(10, 5)) +plt.xticks(np.arange(13, 14.01, (1/12))) +axes.xaxis.set_major_formatter(format_hours_to_minutes) +_n, _bins, patches = axes.hist(demands_50_times, bins) + + + + + +plt.show() + + + + +# demands_24k = pd.read_csv('/home/martin/Documents/01_Bakalarka/03_DATA/manhattan_taxi_data_01_12_24k.txt', sep=" ", header=None) +# demands_24k.columns = ["time", "y", "x", "y2", "x2", "count", "newline"] +# demands_24_times = demands_24k["time"] / (1000*60*60) +# +# fig, axes = plt.subplots(1, 1, figsize=(10, 5)) +# axes.xaxis.set_major_formatter(format_fn) +# axes.xaxis.set_major_locator(MaxNLocator(integer=True)) +# _n, _bins, patches = axes.hist(demands_24_times, bins) + + + + + + + + +# fig, ax = plt.subplots() +# xs = range(26) +# ys = range(26) +# labels = list('abcdefghijklmnopqrstuvwxyz') +# +# def format_fn(tick_val, tick_pos): +# if int(tick_val) in xs: +# return labels[int(tick_val)] +# else: +# return '' +# +# # A FuncFormatter is created automatically. +# ax.xaxis.set_major_formatter(format_fn) +# ax.xaxis.set_major_locator(MaxNLocator(integer=True)) +# ax.plot(xs, ys) +# +# +# plt.show() + +# x_times = pd.timedelta_range(start='00:00:00', end='23:00:00', freq='1H') +# x_times_floats = x_times.apply(lambda x: x.hours) +# print(x_times.values.astype(float)) +# print(x_times_floats) +# plt.hist(demands_24_times, bins) +# plt.show() + +# axes.xaxis.set_ticks(np.arange(0, 60*60*24, 60*60)) +# axes.xaxis.set_major_formatter(FuncFormatter(format_time)) + +# axes.set_ylabel("number of demands") +# axes.set_xlabel("passengers per vehicle") +# plt.legend(loc='upper right') \ No newline at end of file diff --git a/python/simod/statistics/comparisons/heatmap_script.py b/python/simod/statistics/comparisons/heatmap_script.py new file mode 100644 index 00000000..b8b346b3 --- /dev/null +++ b/python/simod/statistics/comparisons/heatmap_script.py @@ -0,0 +1,99 @@ + +import geopandas as gpd +import contextily as ctx +import matplotlib.pyplot as plt +import pandas as pd +import seaborn as sns +import shapely +# from mpl_toolkits.basemap import Basemap +import rasterio.crs + + + +def add_basemap(ax, zoom, url='http://tile.stamen.com/terrain/tileZ/tileX/tileY.png'): + xmin, xmax, ymin, ymax = ax.axis() + basemap, extent = ctx.bounds2img(xmin, ymin, xmax, ymax, zoom=zoom, source=url) + ax.imshow(basemap, extent=extent, interpolation='bilinear') + # restore original x/y limits + ax.axis((xmin, xmax, ymin, ymax)) + + +save_dir = '/home/martin/Documents/01_Bakalarka/02_PLOTS_RESULTS/heatmap/' + +# data = pd.read_csv('/home/martin/Documents/01_Bakalarka/03_DATA/manhattan_TEST_data.txt', sep=" ", header=None) +# filename = "TEST_heatmap" + +data = pd.read_csv('/home/martin/Documents/01_Bakalarka/03_DATA/manhattan_taxi_data_01_12_24k.txt', sep=" ", header=None) +filename = "scatterplot_24k_better" +# data = pd.read_csv('/home/martin/Documents/01_Bakalarka/03_DATA/manhattan_trips_0_to_1.txt', sep=" ", header=None) +# filename = "heatmap_25k_better" +# data = pd.read_csv('/home/martin/Documents/01_Bakalarka/03_DATA/manhattan_trips_13_to_14_50k.txt', sep=" ", header=None) +# filename = "heatmap_50k_better" + + +data.columns = ["time", "y", "x", "y2", "x2", "count", "newline"] +data_part1 = data[['y', 'x']] +data_part2 = data[['y2', 'x2']] +# +new_data = pd.concat([data_part1, data_part2.rename(columns={'y2': 'y', 'x2': 'x'})], ignore_index=True) +new_data = new_data.reset_index() +# +gdf = gpd.GeoDataFrame(new_data, geometry=gpd.points_from_xy(new_data.y, new_data.x), crs='EPSG:4326') + + +gdf.geometry.map(lambda polygon: shapely.ops.transform(lambda x, y: (y, x), polygon)) + +gdf = gdf.set_crs(epsg='4326', allow_override=True) +gdf = gdf['geometry'] + +df_wm = gdf.to_crs(epsg=3857) +# ax = gdf.plot(figsize=(10, 10), alpha=0.7, c='grey') + +ax = gdf.plot(figsize=(5, 10), alpha=0, c='grey') +# ctx.add_basemap(ax, crs='EPSG:3857', source=ctx.providers.Stamen.TonerLite) + +sns.kdeplot(data=new_data, + x='y', + y='x', + fill=True, + cmap='coolwarm', + alpha=0.6, + gridsize=1000, + levels=20, + ax=ax, + legend=False) +# sns.scatterplot(data=new_data, +# x='x', +# y='y', +# ax=ax) + +# ax = gdf.plot(figsize=(10, 10), alpha=0.1, c='grey') + +# ctx.add_basemap(ax, zoom=18) +# ctx.add_basemap(ax, crs=df_wm.crs.to_string(), zoom=10) +# m.shadedrelief() + +# minx, miny, maxx, maxy = data.total_bounds + +# print(minx, maxx, miny, maxy) + +# ax = gdf.plot(figsize=(10, 10), alpha=0.5, edgecolor='b') + +# add_basemap(ax, zoom=10) +# ctx.add_basemap(ax, crs=gdf.crs, zoom=10) + +# ctx.add_basemap(ax, zoom=12, source=ctx.providers.OpenStreetMap.Mapnik) +# ctx.add_basemap(ax, crs=gdf.crs, source=ctx.providers.OpenStreetMap.Mapnik) +# ctx.add_basemap(ax, source=ctx.providers.Stamen.TonerLite) +# ctx.add_basemap(ax, source=ctx.providers.Stamen.TonerLite, crs=gdf.crs.to_string()) + +# ax.get_xaxis().set_ticks([]) +# ax.get_yaxis().set_ticks([]) +ax.set_ylabel('') +ax.set_xlabel('') + +# plt.xticks(np.arange(0, 25, 2)) +plt.xticks(rotation=-30) +# plt.savefig(save_dir + filename, bbox_inches='tight', transparent=True) + +plt.show() \ No newline at end of file diff --git a/python/simod/statistics/comparisons/map_from_edges.py b/python/simod/statistics/comparisons/map_from_edges.py new file mode 100644 index 00000000..175a4ba4 --- /dev/null +++ b/python/simod/statistics/comparisons/map_from_edges.py @@ -0,0 +1,30 @@ +import geopandas as gpd +import contextily as ctx +import matplotlib.pyplot as plt +import numpy as np + +data = gpd.read_file('/home/martin/Documents/01_Bakalarka/01_simod/data/maps/edges.geojson') +nodes = gpd.read_file('/home/martin/Documents/01_Bakalarka/01_simod/data/maps/nodes.geojson') +save_dir = '/home/martin/Documents/01_Bakalarka/02_PLOTS_RESULTS/' + +gdf = data['geometry'] + +nodes_X = nodes['geometry'].x +nodes_Y = nodes['geometry'].y +min_X = np.min(nodes_X) +max_X = np.max(nodes_X) +min_Y = np.min(nodes_Y) +max_Y = np.max(nodes_Y) +print(min_X, max_X, min_Y, max_Y) + +gdf = gdf.to_crs(epsg=3857) + +ax = gdf.plot(figsize=(10, 10), alpha=0.5, edgecolor='b') +ctx.add_basemap(ax, zoom=12, source=ctx.providers.OpenStreetMap.Mapnik) +# ctx.add_basemap(ax, zoom=12, url='http://b.tile.openstreetmap.org/tileZ/tileX/tileY.png') + +ax.set_ylabel('') +ax.set_xlabel('') + +# plt.savefig(save_dir + 'road_graph', bbox_inches='tight', transparent=True) +plt.show() diff --git a/python/simod/statistics/comparisons/occupancy_histogram_PFheuristic.py b/python/simod/statistics/comparisons/occupancy_histogram_PFheuristic.py new file mode 100644 index 00000000..d49c18b7 --- /dev/null +++ b/python/simod/statistics/comparisons/occupancy_histogram_PFheuristic.py @@ -0,0 +1,770 @@ +# +# Copyright (c) 2021 Czech Technical University in Prague. +# +# This file is part of the SiMoD project. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . +# +from simod.init import config + +import numpy as np +import matplotlib +import matplotlib.pyplot as plt +from matplotlib.ticker import PercentFormatter +import pandas as pd +import roadmaptools.inout +import simod.statistics.model.occupancy as occupancy +import simod.statistics.comparisons.common as common + +from matplotlib.ticker import FuncFormatter + +FONT_SIZE = 16 + +matplotlib.rcParams['text.usetex'] = False +matplotlib.rcParams.update({'font.size': FONT_SIZE}) + + +def format_time(minutes: int, position) -> str: + # return str(datetime.timedelta(minutes=minutes)) + return str(int(round(minutes / 60))) + + +def configure_subplot(axis): + axis.yaxis.set_ticks(np.arange(0, 1020001, 30000)) + axis.yaxis.set_major_formatter(FuncFormatter(format_time)) + axis.xaxis.set_ticks(np.arange(0, 10, 1)) + +# data_1_num_people = occupancy.load(config.comparison.experiment_1_dir) +# data_1_no_people = occupancy.load_no_people(config.comparison.experiment_1_dir) +# data_1_with_people = occupancy.load_people_onboard(config.comparison.experiment_1_dir) + +# data_3_people = occupancy.load(config.comparison.experiment_3_dir) +# data_3_packages = occupancy.load_packages(config.comparison.experiment_3_dir) +# +# data_4_people = occupancy.load(config.comparison.experiment_4_dir) +# data_4_packages = occupancy.load_packages(config.comparison.experiment_4_dir) +# +# data_5_people = occupancy.load(config.comparison.experiment_5_dir) +# data_5_packages = occupancy.load_packages(config.comparison.experiment_5_dir) +# +# data_6_people = occupancy.load(config.comparison.experiment_6_dir) +# data_6_packages = occupancy.load_packages(config.comparison.experiment_6_dir) +# +# data_9_people = occupancy.load(config.comparison.experiment_9_dir) +# data_9_packages = occupancy.load_packages(config.comparison.experiment_9_dir) +# +# data_10_people = occupancy.load(config.comparison.experiment_10_dir) +# data_10_packages = occupancy.load_packages(config.comparison.experiment_10_dir) +# data_10_combined = occupancy.load_combined_occupancy(config.comparison.experiment_10_dir) + +# 25k 1h +data_8_people = occupancy.load(config.comparison.experiment_8_dir) +data_8_packages = occupancy.load_packages(config.comparison.experiment_8_dir) +data_8_combined = occupancy.load_combined_occupancy(config.comparison.experiment_8_dir) + +data_9_people = occupancy.load(config.comparison.experiment_9_dir) +data_9_packages = occupancy.load_packages(config.comparison.experiment_9_dir) +data_9_combined = occupancy.load_combined_occupancy(config.comparison.experiment_9_dir) + +data_10_people = occupancy.load(config.comparison.experiment_10_dir) +data_10_packages = occupancy.load_packages(config.comparison.experiment_10_dir) +data_10_combined = occupancy.load_combined_occupancy(config.comparison.experiment_10_dir) + +# 50k 1h +data_11_people = occupancy.load(config.comparison.experiment_11_dir) +data_11_packages = occupancy.load_packages(config.comparison.experiment_11_dir) +data_11_combined = occupancy.load_combined_occupancy(config.comparison.experiment_11_dir) + +data_12_people = occupancy.load(config.comparison.experiment_12_dir) +data_12_packages = occupancy.load_packages(config.comparison.experiment_12_dir) +data_12_combined = occupancy.load_combined_occupancy(config.comparison.experiment_12_dir) + +data_13_people = occupancy.load(config.comparison.experiment_13_dir) +data_13_packages = occupancy.load_packages(config.comparison.experiment_13_dir) +data_13_combined = occupancy.load_combined_occupancy(config.comparison.experiment_13_dir) + +# 24k 24h +data_14_people = occupancy.load(config.comparison.experiment_14_dir) +data_14_packages = occupancy.load_packages(config.comparison.experiment_14_dir) +data_14_combined = occupancy.load_combined_occupancy(config.comparison.experiment_14_dir) + +data_15_people = occupancy.load(config.comparison.experiment_15_dir) +data_15_packages = occupancy.load_packages(config.comparison.experiment_15_dir) +data_15_combined = occupancy.load_combined_occupancy(config.comparison.experiment_15_dir) + +data_16_people = occupancy.load(config.comparison.experiment_16_dir) +data_16_packages = occupancy.load_packages(config.comparison.experiment_16_dir) +data_16_combined = occupancy.load_combined_occupancy(config.comparison.experiment_16_dir) + + +# occupancies_1_num_people = occupancy.get_occupancies(data_1_num_people) +# occupancies_1_no_people = occupancy.get_occupancies(data_1_no_people) +# occupancies_1_with_people = occupancy.get_occupancies(data_1_with_people) + + +# occupancies_3_people = occupancy.get_occupancies(data_3_people) +# occupancies_3_packages = occupancy.get_occupancies(data_3_packages) +# +# occupancies_4_people = occupancy.get_occupancies(data_4_people) +# occupancies_4_packages = occupancy.get_occupancies(data_4_packages) +# +# occupancies_5_people = occupancy.get_occupancies(data_5_people) +# occupancies_5_packages = occupancy.get_occupancies(data_5_packages) +# +# occupancies_6_people = occupancy.get_occupancies(data_6_people) +# occupancies_6_packages = occupancy.get_occupancies(data_6_packages) +# +# +# occupancies_9_people = occupancy.get_occupancies(data_9_people) +# occupancies_9_packages = occupancy.get_occupancies(data_9_packages) + +occupancies_8_people = occupancy.get_occupancies(data_8_people) +occupancies_8_packages = occupancy.get_occupancies(data_8_packages) +occupancies_8_combined = occupancy.get_combined_occupancies(data_8_combined) + +occupancies_9_people = occupancy.get_occupancies(data_9_people) +occupancies_9_packages = occupancy.get_occupancies(data_9_packages) +occupancies_9_combined = occupancy.get_combined_occupancies(data_9_combined) + +occupancies_10_people = occupancy.get_occupancies(data_10_people) +occupancies_10_packages = occupancy.get_occupancies(data_10_packages) +occupancies_10_combined = occupancy.get_combined_occupancies(data_10_combined) + +occupancies_11_people = occupancy.get_occupancies(data_11_people) +occupancies_11_packages = occupancy.get_occupancies(data_11_packages) +occupancies_11_combined = occupancy.get_combined_occupancies(data_11_combined) + +occupancies_12_people = occupancy.get_occupancies(data_12_people) +occupancies_12_packages = occupancy.get_occupancies(data_12_packages) +occupancies_12_combined = occupancy.get_combined_occupancies(data_12_combined) + +occupancies_13_people = occupancy.get_occupancies(data_13_people) +occupancies_13_packages = occupancy.get_occupancies(data_13_packages) +occupancies_13_combined = occupancy.get_combined_occupancies(data_13_combined) + +occupancies_14_people = occupancy.get_occupancies(data_14_people) +occupancies_14_packages = occupancy.get_occupancies(data_14_packages) +occupancies_14_combined = occupancy.get_combined_occupancies(data_14_combined) + +occupancies_15_people = occupancy.get_occupancies(data_15_people) +occupancies_15_packages = occupancy.get_occupancies(data_15_packages) +occupancies_15_combined = occupancy.get_combined_occupancies(data_15_combined) + +occupancies_16_people = occupancy.get_occupancies(data_16_people) +occupancies_16_packages = occupancy.get_occupancies(data_16_packages) +occupancies_16_combined = occupancy.get_combined_occupancies(data_16_combined) + + + +bins = np.arange(-0.5, 10.5, 1) + +hatches = ['\\\\', '//', '++', '**'] + +""" ---------------------- FIG ------------------------- """ +# fig, axes = plt.subplots(1, 1, subplot_kw={"adjustable": 'box'}, figsize=(10, 5)) +# _n, _bins, patches = axes.hist([occupancies_1_num_people], bins, rwidth=0.9) +# # axes.yaxis.set_ticks(np.arange(0, 1200001, 120000)) +# axes.yaxis.set_major_formatter(FuncFormatter(format_time)) +# axes.set_ylabel("vehicle hours") +# axes.set_xlabel("passengers per vehicle") +# # plt.legend(loc='upper right') + +""" ---------------------- FIG ---------------------- """ +# fig, axes = plt.subplots(1, 1, subplot_kw={"adjustable": 'box'}, figsize=(10, 5)) +# _n, _bins, patches = axes.hist([occupancies_1_with_person], bins, label=['1 person onboard'], rwidth=0.9) +# # axes.yaxis.set_ticks(np.arange(0, 1200001, 120000)) +# axes.yaxis.set_major_formatter(FuncFormatter(format_time)) +# axes.set_ylabel("vehicle hours") +# axes.set_xlabel("packages per vehicle") +# plt.legend(loc='upper right') + + + +# for patch_set, hatch in zip(patches, hatches): +# plt.setp(patch_set, hatch=hatch) + +""" +fig, axes = plt.subplots(1, 1, subplot_kw={"adjustable": 'box'}, figsize=(10, 3)) +_n, _bins, patches = axes.hist([occupancies_in_window_1], bins, + label=common.labels) +# , occupancies_in_window_3, +# occupancies_in_window_4, occupancies_in_window_4, occupancies_in_window_10 +axes.yaxis.set_ticks(np.arange(0, 840001, 120000)) +axes.yaxis.set_major_formatter(FuncFormatter(format_time)) +axes.set_ylabel("vehicle hours") + +for patch_set, hatch in zip(patches, hatches): + plt.setp(patch_set, hatch=hatch) +""" + + +# plt.savefig(config.images.occupancy_histogram_comparison, bbox_inches='tight', transparent=True) + + +""" --------------------------------- FIG 1 ------------------------------- """ +# fig, axes = plt.subplots(1, 2, figsize=(10, 5), sharex=True, sharey=True) +# +# # decrease space between subplots +# fig.subplots_adjust(wspace=0.05) +# +# axis1 = axes[0] +# axis2 = axes[1] +# # axis1.yaxis.set_ticks(np.arange(0, 1200001, 120000)) +# +# axis1.set_title("Base version 10h") +# axis1.set_xlabel("Passengers per vehicle") +# +# # axis2.set_title("Packages occupancy") +# axis2.set_xlabel("Packages per vehicle") +# +# configure_subplot(axis1) +# +# _n, _bins, patches = axis1.hist([occupancies_3_people], bins, rwidth=0.9) +# _n, _bins, patches = axis2.hist([occupancies_3_packages], bins, rwidth=0.9) +# +# axis1.set_ylabel("vehicle hours") +""" -----------------------------------------------------------------------------""" + + +""" ------------------------------------ FIG 2 --------------------------------- """ +# fig, axes = plt.subplots(1, 2, figsize=(10, 5), sharex=True, sharey=True) +# +# # decrease space between subplots +# fig.subplots_adjust(wspace=0.05) +# +# axis1 = axes[0] +# axis2 = axes[1] +# +# axis1.set_title("Insertion version 10h") +# axis1.set_xlabel("Passengers per vehicle") +# +# # axis2.set_title("Packages occupancy") +# axis2.set_xlabel("Packages per vehicle") +# configure_subplot(axis1) +# +# _n, _bins, patches = axis1.hist([occupancies_4_people], bins, rwidth=0.9) +# _n, _bins, patches = axis2.hist([occupancies_4_packages], bins, rwidth=0.9) +# +# axis1.set_ylabel("vehicle hours") +""" -----------------------------------------------------------------------------""" + + +""" --------------------------------- FIG 3 ------------------------------- """ +# fig, axes = plt.subplots(1, 2, figsize=(10, 5), sharex=True, sharey=True) +# +# # decrease space between subplots +# fig.subplots_adjust(wspace=0.05) +# +# axis1 = axes[0] +# axis2 = axes[1] +# +# axis1.set_title("Base version 2h") +# axis1.set_xlabel("Passengers per vehicle") +# +# # axis2.set_title("Packages occupancy") +# axis2.set_xlabel("Packages per vehicle") +# configure_subplot(axis1) +# +# _n, _bins, patches = axis1.hist([occupancies_5_people], bins, rwidth=0.9) +# _n, _bins, patches = axis2.hist([occupancies_5_packages], bins, rwidth=0.9) +# +# axis1.set_ylabel("vehicle hours") +""" -----------------------------------------------------------------------------""" + + +""" ------------------------------------ FIG 4 --------------------------------- """ +# fig, axes = plt.subplots(1, 2, figsize=(10, 5), sharex=True, sharey=True) +# +# # decrease space between subplots +# fig.subplots_adjust(wspace=0.05) +# +# axis1 = axes[0] +# axis2 = axes[1] +# +# axis1.set_title("Insertion version 2h") +# axis1.set_xlabel("Passengers per vehicle") +# +# # axis2.set_title("Packages occupancy") +# axis2.set_xlabel("Packages per vehicle") +# configure_subplot(axis1) +# +# _n, _bins, patches = axis1.hist([occupancies_6_people], bins, rwidth=0.9) +# _n, _bins, patches = axis2.hist([occupancies_6_packages], bins, rwidth=0.9) +# +# axis1.set_ylabel("vehicle hours") +""" -----------------------------------------------------------------------------""" + + +""" --------------------------------- FIG 5 ------------------------------- """ +# fig, axes = plt.subplots(1, 2, figsize=(10, 5), sharex=True, sharey=True) +# +# # decrease space between subplots +# fig.subplots_adjust(wspace=0.05) +# +# axis1 = axes[0] +# axis2 = axes[1] +# +# axis1.set_title("Base version Manhattan 1h") +# axis1.set_xlabel("Passengers per vehicle") +# +# # axis2.set_title("Packages occupancy") +# axis2.set_xlabel("Packages per vehicle") +# configure_subplot(axis1) +# +# _n, _bins, patches = axis1.hist([occupancies_9_people], bins, rwidth=0.9) +# _n, _bins, patches = axis2.hist([occupancies_9_packages], bins, rwidth=0.9) +# +# axis1.set_ylabel("vehicle hours") +""" -----------------------------------------------------------------------------""" + + +""" --------------------------------- FIG 6 ------------------------------- """ +# fig, axes = plt.subplots(1, 2, figsize=(10, 5), sharex=True, sharey=True) +# +# # decrease space between subplots +# fig.subplots_adjust(wspace=0.05) +# +# axis1 = axes[0] +# axis2 = axes[1] +# +# axis1.set_title("Insertion version Manhattan 1h") +# axis1.set_xlabel("Passengers per vehicle") +# +# # axis2.set_title("Packages occupancy") +# axis2.set_xlabel("Packages per vehicle") +# configure_subplot(axis1) +# +# _n, _bins, patches = axis1.hist([occupancies_10_people], bins, rwidth=0.9) +# _n, _bins, patches = axis2.hist([occupancies_10_packages], bins, rwidth=0.9) +# +# axis1.set_ylabel("vehicle hours") +""" -----------------------------------------------------------------------------""" + + +""" --------------------------------- FIG 13 ------------------------------- """ +# fig, axes = plt.subplots(1, 2, figsize=(10, 5), sharex=True, sharey=True) +# +# # decrease space between subplots +# fig.subplots_adjust(wspace=0.05) +# +# axis1 = axes[0] +# axis2 = axes[1] +# +# axis1.set_title("Base version Manhattan 1h 50k") +# axis1.set_xlabel("Passengers per vehicle") +# +# # axis2.set_title("Packages occupancy") +# axis2.set_xlabel("Packages per vehicle") +# configure_subplot(axis1) +# +# _n, _bins, patches = axis1.hist([occupancies_8_people], bins, rwidth=0.9) +# _n, _bins, patches = axis2.hist([occupancies_8_packages], bins, rwidth=0.9) +# +# axis1.set_ylabel("vehicle hours") +""" -----------------------------------------------------------------------------""" + +""" --------------------------------- FIG 14 ------------------------------- """ +# fig, axes = plt.subplots(1, 2, figsize=(10, 5), sharex=True, sharey=True) +# +# # decrease space between subplots +# fig.subplots_adjust(wspace=0.05) +# +# axis1 = axes[0] +# axis2 = axes[1] +# +# axis1.set_title("Insertion version Manhattan 1h 50k") +# axis1.set_xlabel("Passengers per vehicle") +# +# # axis2.set_title("Packages occupancy") +# axis2.set_xlabel("Packages per vehicle") +# configure_subplot(axis1) +# +# _n, _bins, patches = axis1.hist([occupancies_10_people], bins, rwidth=0.9) +# _n, _bins, patches = axis2.hist([occupancies_10_packages], bins, rwidth=0.9) +# +# axis1.set_ylabel("vehicle hours") +""" -----------------------------------------------------------------------------""" + + + + + +# for patch_set, hatch in zip(patches, common.hatches): +# plt.setp(patch_set, hatch=hatch) + +# plt.legend(loc='upper right') + +""" +# _n, _bins, patches = axis2.hist([occupancies_in_window_6, occupancies_in_window_7, +# occupancies_in_window_8, occupancies_in_window_9, occupancies_in_window_10, occupancies_in_window_11], bins, +# label=common.labels, color=common.colors) + +configure_subplot(axis2) + +for patch_set, hatch in zip(patches, common.hatches): + plt.setp(patch_set, hatch=hatch) + +plt.legend(loc='upper right', labelspacing=0.01) + +""" + +# plt.savefig(config.images.occupancy_histogram_comparison_combined, bbox_inches='tight', transparent=True, pad_inches=0.0, dpi=fig.dpi) +save_dir = '/home/martin/Documents/01_Bakalarka/02_PLOTS_RESULTS/occupancy_new/' + + + +""" --------------------- 3D Histogram experiment 14 = 24h 24k BASE -------------------- """ +x = data_14_combined["people_occupancy"] +y = data_14_combined["package_occupancy"] + +fig = plt.figure() +ax = fig.add_subplot(projection='3d') +ax.set_xlabel("Passengers per vehicle") +ax.set_ylabel("Packages per vehicle") +# ax.set_zlabel("Vehicle hours", labelpad=10.0) +# ax.zaxis.set_ticks(np.arange(0, 1020001, 60000)) +# ax.zaxis.set_major_formatter(FuncFormatter(format_time)) +ax.zaxis.set_ticks(np.arange(0, 1, 0.05)) +ax.zaxis.set_major_formatter(PercentFormatter(xmax=1.0, decimals=0)) + +hist, xedges, yedges = np.histogram2d(x, y, bins=4, normed=True, range=[[0, 4], [0, 4]]) +print("======== RIDESHARING RATES: ==============") +print("'R' = any ridesharing, 'RwD' = Ridesharing with Delivery") +print("24k Base:") +print("R: ", end="") +print(np.round(100*(np.sum(hist) - hist[0][0] - hist[0][1] - hist[1][0]), decimals=2), end="") +print(" ; RwD: ", end="") +print(np.round(100*(np.sum(hist) - np.sum(hist[0,:]) - np.sum(hist[:,0]) + hist[0][0]), decimals=2), end="\n") + +# Construct arrays for the anchor positions of the 16 bars. +xpos, ypos = np.meshgrid(xedges[:-1] - 0.5, yedges[:-1] - 0.5, indexing="ij") +xpos = xpos.ravel() +ypos = ypos.ravel() +zpos = np.zeros_like(xpos) + +# Construct arrays with the dimensions for the 16 bars. +dx = dy = 0.9 * np.ones_like(zpos) +dz = hist.ravel() + +ax.bar3d(xpos, ypos, zpos, dx, dy, dz, zsort='average') +ax.view_init(15, 45) +plt.savefig(save_dir + 'occ_24h_24k_Base', bbox_inches='tight', transparent=True) +""" -----------------------------------------------------------------------------""" + +""" --------------------------3D Histogram experiment 15 = 24h 24k MULTIPASS -------------------- """ +x = data_15_combined["people_occupancy"] +y = data_15_combined["package_occupancy"] + +fig = plt.figure() +ax = fig.add_subplot(projection='3d') +ax.set_xlabel("Passengers per vehicle") +ax.set_ylabel("Packages per vehicle") +# ax.set_zlabel("Vehicle hours", labelpad=10.0) +# ax.zaxis.set_ticks(np.arange(0, 1020001, 30000)) +# ax.zaxis.set_major_formatter(FuncFormatter(format_time)) +ax.zaxis.set_ticks(np.arange(0, 1, 0.05)) +ax.zaxis.set_major_formatter(PercentFormatter(xmax=1.0, decimals=0)) + +hist, xedges, yedges = np.histogram2d(x, y, bins=4, normed=True, range=[[0, 4], [0, 4]]) +print("24k Multipass:") +print("R: ", end="") +print(np.round(100*(np.sum(hist) - hist[0][0] - hist[0][1] - hist[1][0]), decimals=2), end="") +print(" ; RwD: ", end="") +print(np.round(100*(np.sum(hist) - np.sum(hist[0,:]) - np.sum(hist[:,0]) + hist[0][0]), decimals=2), end="\n") + +# Construct arrays for the anchor positions of the 16 bars. +xpos, ypos = np.meshgrid(xedges[:-1] - 0.5, yedges[:-1] - 0.5, indexing="ij") +xpos = xpos.ravel() +ypos = ypos.ravel() +zpos = np.zeros_like(xpos) + +# Construct arrays with the dimensions for the 16 bars. +dx = dy = 0.9 * np.ones_like(zpos) +dz = hist.ravel() + +ax.bar3d(xpos, ypos, zpos, dx, dy, dz, zsort='average') +ax.view_init(15, 45) +plt.savefig(save_dir + 'occ_24h_24k_Multipass', bbox_inches='tight', transparent=True) +""" -----------------------------------------------------------------------------""" + +""" --------------------------------- 3D Histogram experiment 16 24h 24k INSERTION ------------ """ +x = data_16_combined["people_occupancy"] +y = data_16_combined["package_occupancy"] + +fig = plt.figure() +ax = fig.add_subplot(projection='3d') +ax.set_xlabel("Passengers per vehicle") +ax.set_ylabel("Packages per vehicle") +# ax.set_zlabel("Vehicle hours", labelpad=10.0) +# ax.zaxis.set_ticks(np.arange(0, 1020001, 30000)) +# ax.zaxis.set_major_formatter(FuncFormatter(format_time)) +ax.zaxis.set_ticks(np.arange(0, 1, 0.05)) +ax.zaxis.set_major_formatter(PercentFormatter(xmax=1.0, decimals=0)) + +hist, xedges, yedges = np.histogram2d(x, y, bins=4, normed=True, range=[[0, 4], [0, 4]]) +print("24k Insertion:") +print("R: ", end="") +print(np.round(100*(np.sum(hist) - hist[0][0] - hist[0][1] - hist[1][0]), decimals=2), end="") +print(" ; RwD: ", end="") +print(np.round(100*(np.sum(hist) - np.sum(hist[0,:]) - np.sum(hist[:,0]) + hist[0][0]), decimals=2), end="\n\n") + +# Construct arrays for the anchor positions of the 16 bars. +xpos, ypos = np.meshgrid(xedges[:-1] - 0.5, yedges[:-1] - 0.5, indexing="ij") +xpos = xpos.ravel() +ypos = ypos.ravel() +zpos = np.zeros_like(xpos) + +# Construct arrays with the dimensions for the 16 bars. +dx = dy = 0.9 * np.ones_like(zpos) +dz = hist.ravel() + +ax.bar3d(xpos, ypos, zpos, dx, dy, dz, zsort='average') +ax.view_init(15, 45) +plt.savefig(save_dir + 'occ_24h_24k_Insertion', bbox_inches='tight', transparent=True) +""" -----------------------------------------------------------------------------""" + +""" --------------------- 3D Histogram experiment 8 = 1h 25k BASE -------------------- """ +x = data_8_combined["people_occupancy"] +y = data_8_combined["package_occupancy"] + +fig = plt.figure() +ax = fig.add_subplot(projection='3d') +ax.set_xlabel("Passengers per vehicle") +ax.set_ylabel("Packages per vehicle") +# ax.set_zlabel("Vehicle hours", labelpad=10.0) +# ax.zaxis.set_ticks(np.arange(0, 1020001, 30000)) +# ax.zaxis.set_major_formatter(FuncFormatter(format_time)) +ax.zaxis.set_ticks(np.arange(0, 1, 0.05)) +ax.zaxis.set_major_formatter(PercentFormatter(xmax=1.0, decimals=0)) + +hist, xedges, yedges = np.histogram2d(x, y, bins=4, normed=True, range=[[0, 4], [0, 4]]) +print("25k Base:") +print("R: ", end="") +print(np.round(100*(np.sum(hist) - hist[0][0] - hist[0][1] - hist[1][0]), decimals=2), end="") +print(" ; RwD: ", end="") +print(np.round(100*(np.sum(hist) - np.sum(hist[0,:]) - np.sum(hist[:,0]) + hist[0][0]), decimals=2), end="\n") + +# Construct arrays for the anchor positions of the 16 bars. +xpos, ypos = np.meshgrid(xedges[:-1] - 0.5, yedges[:-1] - 0.5, indexing="ij") +xpos = xpos.ravel() +ypos = ypos.ravel() +zpos = np.zeros_like(xpos) + +# Construct arrays with the dimensions for the 16 bars. +dx = dy = 0.9 * np.ones_like(zpos) +dz = hist.ravel() + +ax.bar3d(xpos, ypos, zpos, dx, dy, dz, zsort='average') +ax.view_init(15, 45) +plt.savefig(save_dir + 'occ_1h_25k_Base', bbox_inches='tight', transparent=True) +""" -----------------------------------------------------------------------------""" + +""" --------------------------3D Histogram experiment 9 = 1h 25k MULTIPASS -------------------- """ +x = data_9_combined["people_occupancy"] +y = data_9_combined["package_occupancy"] + +fig = plt.figure() +ax = fig.add_subplot(projection='3d') +ax.set_xlabel("Passengers per vehicle") +ax.set_ylabel("Packages per vehicle") +# ax.set_zlabel("Vehicle hours", labelpad=10.0) +# ax.zaxis.set_ticks(np.arange(0, 1020001, 30000)) +# ax.zaxis.set_major_formatter(FuncFormatter(format_time)) +ax.zaxis.set_ticks(np.arange(0, 1, 0.05)) +ax.zaxis.set_major_formatter(PercentFormatter(xmax=1.0, decimals=0)) + +hist, xedges, yedges = np.histogram2d(x, y, bins=4, normed=True, range=[[0, 4], [0, 4]]) +print("25k Multipass:") +print("R: ", end="") +print(np.round(100*(np.sum(hist) - hist[0][0] - hist[0][1] - hist[1][0]), decimals=2), end="") +print(" ; RwD: ", end="") +print(np.round(100*(np.sum(hist) - np.sum(hist[0,:]) - np.sum(hist[:,0]) + hist[0][0]), decimals=2), end="\n") + +# Construct arrays for the anchor positions of the 16 bars. +xpos, ypos = np.meshgrid(xedges[:-1] - 0.5, yedges[:-1] - 0.5, indexing="ij") +xpos = xpos.ravel() +ypos = ypos.ravel() +zpos = np.zeros_like(xpos) + +# Construct arrays with the dimensions for the 16 bars. +dx = dy = 0.9 * np.ones_like(zpos) +dz = hist.ravel() + +ax.bar3d(xpos, ypos, zpos, dx, dy, dz, zsort='average') +ax.view_init(15, 45) +plt.savefig(save_dir + 'occ_1h_25k_Multipass', bbox_inches='tight', transparent=True) +""" -----------------------------------------------------------------------------""" + +""" --------------------------------- 3D Histogram experiment 10 1h 25k INSERTION ------------ """ +x = data_10_combined["people_occupancy"] +y = data_10_combined["package_occupancy"] + +fig = plt.figure() +ax = fig.add_subplot(projection='3d') +ax.set_xlabel("Passengers per vehicle") +ax.set_ylabel("Packages per vehicle") +# ax.set_zlabel("Vehicle hours", labelpad=10.0) +# ax.zaxis.set_ticks(np.arange(0, 1020001, 30000)) +# ax.zaxis.set_major_formatter(FuncFormatter(format_time)) +ax.zaxis.set_ticks(np.arange(0, 1, 0.05)) +ax.zaxis.set_major_formatter(PercentFormatter(xmax=1.0, decimals=0)) + +hist, xedges, yedges = np.histogram2d(x, y, bins=4, normed=True, range=[[0, 4], [0, 4]]) +print("25k Insertion:") +print("R: ", end="") +print(np.round(100*(np.sum(hist) - hist[0][0] - hist[0][1] - hist[1][0]), decimals=2), end="") +print(" ; RwD: ", end="") +print(np.round(100*(np.sum(hist) - np.sum(hist[0,:]) - np.sum(hist[:,0]) + hist[0][0]), decimals=2), end="\n\n") + +# Construct arrays for the anchor positions of the 16 bars. +xpos, ypos = np.meshgrid(xedges[:-1] - 0.5, yedges[:-1] - 0.5, indexing="ij") +# print(xpos) +# print(ypos) +xpos = xpos.ravel() +ypos = ypos.ravel() +zpos = np.zeros_like(xpos) + +# Construct arrays with the dimensions for the 16 bars. +dx = dy = 0.9 * np.ones_like(zpos) +dz = hist.ravel() + +ax.bar3d(xpos, ypos, zpos, dx, dy, dz, zsort='average') +ax.view_init(15, 45) +plt.savefig(save_dir + 'occ_1h_25k_Insertion', bbox_inches='tight', transparent=True) +""" -----------------------------------------------------------------------------""" + +""" --------------------- 3D Histogram experiment 11 = 1h 50k BASE -------------------- """ +x = data_11_combined["people_occupancy"] +y = data_11_combined["package_occupancy"] + +fig = plt.figure() +ax = fig.add_subplot(projection='3d') +ax.set_xlabel("Passengers per vehicle") +ax.set_ylabel("Packages per vehicle") +# ax.set_zlabel("Vehicle hours", labelpad=10.0) +# ax.zaxis.set_ticks(np.arange(0, 1020001, 60000)) +# ax.zaxis.set_major_formatter(FuncFormatter(format_time)) +ax.zaxis.set_ticks(np.arange(0, 1, 0.05)) +ax.zaxis.set_major_formatter(PercentFormatter(xmax=1.0, decimals=0)) + +hist, xedges, yedges = np.histogram2d(x, y, bins=4, normed=True, range=[[0, 4], [0, 4]]) +print("50k Base:") +print("R: ", end="") +print(np.round(100*(np.sum(hist) - hist[0][0] - hist[0][1] - hist[1][0]), decimals=2), end="") +print(" ; RwD: ", end="") +print(np.round(100*(np.sum(hist) - np.sum(hist[0,:]) - np.sum(hist[:,0]) + hist[0][0]), decimals=2), end="\n") +# print(100*hist) +# print("sum: ", end="") +# print(100*np.sum(hist)) +# print("first row: ", end="") +# # print(100*np.sum(hist[0][:])) +# print(100*hist[0, :]) +# print("first column: ", end="") +# print(100*hist[:, 0]) +# print(100*hist[0][0]) +# print(100*hist[1][0]) +# print("empty taxi: ", end="") +# print(100*hist[0][0]) + + +# Construct arrays for the anchor positions of the 16 bars. +xpos, ypos = np.meshgrid(xedges[:-1] - 0.5, yedges[:-1] - 0.5, indexing="ij") +xpos = xpos.ravel() +ypos = ypos.ravel() +zpos = np.zeros_like(xpos) + +# Construct arrays with the dimensions for the 16 bars. +dx = dy = 0.9 * np.ones_like(zpos) +dz = hist.ravel() + +ax.bar3d(xpos, ypos, zpos, dx, dy, dz, zsort='average') +ax.view_init(15, 45) +plt.savefig(save_dir + 'occ_1h_50k_Base', bbox_inches='tight', transparent=True) +""" -----------------------------------------------------------------------------""" + +""" --------------------------3D Histogram experiment 12 = 1h 50k MULTIPASS -------------------- """ +x = data_12_combined["people_occupancy"] +y = data_12_combined["package_occupancy"] + +fig = plt.figure() +ax = fig.add_subplot(projection='3d') +ax.set_xlabel("Passengers per vehicle") +ax.set_ylabel("Packages per vehicle") +# ax.set_zlabel("Vehicle hours", labelpad=10.0) +# ax.zaxis.set_ticks(np.arange(0, 1020001, 30000)) +# ax.zaxis.set_major_formatter(FuncFormatter(format_time)) +ax.zaxis.set_ticks(np.arange(0, 1, 0.05)) +ax.zaxis.set_major_formatter(PercentFormatter(xmax=1.0, decimals=0)) + +hist, xedges, yedges = np.histogram2d(x, y, bins=4, normed=True, range=[[0, 4], [0, 4]]) +print("50k Multipass:") +print("R: ", end="") +print(np.round(100*(np.sum(hist) - hist[0][0] - hist[0][1] - hist[1][0]), decimals=2), end="") +print(" ; RwD: ", end="") +print(np.round(100*(np.sum(hist) - np.sum(hist[0][:]) - np.sum(hist[:][0]) + hist[0][0]), decimals=2), end="\n") + +# Construct arrays for the anchor positions of the 16 bars. +xpos, ypos = np.meshgrid(xedges[:-1] - 0.5, yedges[:-1] - 0.5, indexing="ij") +xpos = xpos.ravel() +ypos = ypos.ravel() +zpos = np.zeros_like(xpos) + +# Construct arrays with the dimensions for the 16 bars. +dx = dy = 0.9 * np.ones_like(zpos) +dz = hist.ravel() + +ax.bar3d(xpos, ypos, zpos, dx, dy, dz, zsort='average') +ax.view_init(15, 45) +plt.savefig(save_dir + 'occ_1h_50k_Multipass', bbox_inches='tight', transparent=True) +""" -----------------------------------------------------------------------------""" + +""" --------------------------------- 3D Histogram experiment 13 1h 50k INSERTION ------------ """ +x = data_13_combined["people_occupancy"] +y = data_13_combined["package_occupancy"] + +fig = plt.figure() +ax = fig.add_subplot(projection='3d') +ax.set_xlabel("Passengers per vehicle") +ax.set_ylabel("Packages per vehicle") +# ax.set_zlabel("Vehicle hours", labelpad=10.0) +# ax.zaxis.set_ticks(np.arange(0, 1020001, 30000)) +# ax.zaxis.set_major_formatter(FuncFormatter(format_time)) +ax.zaxis.set_ticks(np.arange(0, 1, 0.05)) +ax.zaxis.set_major_formatter(PercentFormatter(xmax=1.0, decimals=0)) + +hist, xedges, yedges = np.histogram2d(x, y, bins=4, normed=True, range=[[0, 4], [0, 4]]) +print("50k Insertion:") +print("R: ", end="") +print(np.round(100*(np.sum(hist) - hist[0][0] - hist[0][1] - hist[1][0]), decimals=2), end="") +print(" ; RwD: ", end="") +print(np.round(100*(np.sum(hist) - np.sum(hist[0][:]) - np.sum(hist[:][0]) + hist[0][0]), decimals=2), end="\n") + +# Construct arrays for the anchor positions of the 16 bars. +xpos, ypos = np.meshgrid(xedges[:-1] - 0.5, yedges[:-1] - 0.5, indexing="ij") +# print(xpos) +# print(ypos) +xpos = xpos.ravel() +ypos = ypos.ravel() +zpos = np.zeros_like(xpos) + +# Construct arrays with the dimensions for the 16 bars. +dx = dy = 0.9 * np.ones_like(zpos) +dz = hist.ravel() + +ax.bar3d(xpos, ypos, zpos, dx, dy, dz, zsort='average') +ax.view_init(15, 45) +plt.savefig(save_dir + 'occ_1h_50k_Insertion', bbox_inches='tight', transparent=True) +""" -----------------------------------------------------------------------------""" + +plt.show() \ No newline at end of file diff --git a/python/simod/statistics/comparisons/occupancy_histogram_comparison.py b/python/simod/statistics/comparisons/occupancy_histogram_comparison.py index 453a98d7..348e89e1 100644 --- a/python/simod/statistics/comparisons/occupancy_histogram_comparison.py +++ b/python/simod/statistics/comparisons/occupancy_histogram_comparison.py @@ -16,7 +16,7 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . # -from amodsim.init import config +from simod.init import config import numpy as np import pandas as pd @@ -24,8 +24,8 @@ import matplotlib.pyplot as plt import datetime import roadmaptools.inout -import amodsim.statistics.model.occupancy as occupancy -import amodsim.statistics.comparisons.common as common +import simod.statistics.model.occupancy as occupancy +import simod.statistics.comparisons.common as common from matplotlib.ticker import FuncFormatter @@ -140,7 +140,7 @@ def configure_subplot(axis): plt.legend(loc='upper right') - +"""sdifsk""" _n, _bins, patches = axis2.hist([occupancies_in_window_6, occupancies_in_window_7, occupancies_in_window_8, occupancies_in_window_9, occupancies_in_window_10, occupancies_in_window_11], bins, diff --git a/python/simod/statistics/comparisons/ridesharing_comparison_table_PF.py b/python/simod/statistics/comparisons/ridesharing_comparison_table_PF.py new file mode 100644 index 00000000..ee286536 --- /dev/null +++ b/python/simod/statistics/comparisons/ridesharing_comparison_table_PF.py @@ -0,0 +1,491 @@ +# +# Copyright (c) 2021 Czech Technical University in Prague. +# +# This file is part of the SiMoD project. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . +# +from simod.init import config + +import numpy as np +import pandas.errors +import roadmaptools.inout +import simod.statistics.model.traffic_load as traffic_load +import simod.statistics.model.transit as transit +import simod.statistics.model.edges as edges +import simod.statistics.model.ridesharing as ridesharing +import simod.statistics.model.service as service +import simod.statistics.model.occupancy as occupancy + +from typing import List, Dict, Iterable +from pandas import DataFrame +from roadmaptools.printer import print_table, print_info +from simod.statistics.traffic_density_histogram import TrafficDensityHistogram +from simod.statistics.model.vehicle_state import VehicleState + + + + + + + +def compute_stats_current_state(experiment_dir: str, result: Dict, histogram: TrafficDensityHistogram, load) -> List: + + # distance + transit_data = transit.load(experiment_dir) + km_total_window = int(round(transit.get_total_distance(transit_data, edge_data, True, + VehicleState.DRIVING_TO_TARGET_LOCATION) / 1000 / 100)) + + # average density + # average_density_list_total_future = histogram.get_average_density_list(load) + # average_density_in_time_window_non_empty_edges = np.average(average_density_list_total_future) + + # congested count + # congested_count_in_time_window = np.where(average_density_list_total_future > config.critical_density)[0].size + + dropped_demand_count = 0 + + # half congested edges + # half_congested_count_in_time_window \ + # = np.where(average_density_list_total_future > (config.critical_density / 2))[0].size + + used_cars_count = result["demandsCount"] + + return [km_total_window, 0, 0, dropped_demand_count , 0, used_cars_count, None, None] + + +def compute_stats(result: Dict, histogram: TrafficDensityHistogram, load, experiment_dir: str, + edge_data: DataFrame) -> List: + # avg_km_total = result["averageKmWithPassenger"] + result["averageKmToStartLocation"] + result["averageKmToStation"] \ + # + result["averageKmRebalancing"] + + # km total + transit_data = transit.load(experiment_dir) + + # km_total = int(round(avg_km_total * result["numberOfVehicles"])) + km_total = transit.get_total_distance(transit_data, edge_data) / 1000 / 100 + km_total_window = int(round(transit.get_total_distance(transit_data, edge_data, True) / 1000 / 100)) + + # average density + # average_density_list_total_future = histogram.get_average_density_list(load) + # average_density_in_time_window_non_empty_edges = np.average(average_density_list_total_future) + + # congested count + # congested_count_in_time_window = np.where(average_density_list_total_future > config.critical_density)[0].size + + dropped_demand_count = result["numberOfDemandsDropped"] + dropped_passengers_count = result["numberPassengersDropped"] + dropped_packages_count = result["numberPackagesDropped"] + + # half congested edges + # half_congested_count_in_time_window \ + # = np.where(average_density_list_total_future > (config.critical_density / 2))[0].size + + # used_cars = set() + # for row in occupancies: + # used_cars.add(row[1]) + + occupancies = occupancy.load(experiment_dir) + occupancies_in_window = occupancy.filter_window(occupancies) + # used_cars_count = len(occupancies_in_window[occupancies_in_window.occupancy > 0].vehicle_id.unique()) + used_cars_count = len(occupancies_in_window.vehicle_id.unique()) + + total_shared_requests = result["totalSharedRequests"] + + # performance + try: + performance_data = ridesharing.load(experiment_dir) + if 'PeopleFreight Heuristic Time' in performance_data: + avg_time = performance_data['PeopleFreight Heuristic Time'].mean() + else: + avg_time = performance_data['Group Generation Time'].mean() + performance_data['Solver Time'].mean() + # avg_time = int(round(avg_time / 1000)) + avg_time = int(round(avg_time)) + except pandas.errors.EmptyDataError: + print_info("Empty ridesharing statistic") + avg_time = "-1" + + # delay + service_stat = service.load_dataframe(experiment_dir) + delays_window = service.get_delays(service_stat, True, False) + mean_delay = int(round(delays_window.mean() / 1000)) + # mean_delay = delays_window.mean() + + return [km_total_window, dropped_passengers_count, dropped_packages_count, total_shared_requests, used_cars_count, avg_time, mean_delay] + + +# result data load + +# edges +loaded_edges = roadmaptools.inout.load_geojson(config.agentpolis.map_edges_filepath) +edge_data = edges.make_data_frame(loaded_edges) +edge_object_data = edges.load_edges_mapped_by_id(loaded_edges) + + + +exp_dir_8 = config.comparison.experiment_8_dir # 25k 1h manhattan +exp_dir_9 = config.comparison.experiment_9_dir +exp_dir_10 = config.comparison.experiment_10_dir + +exp_dir_11 = config.comparison.experiment_11_dir # 50k 1h manhattan +exp_dir_12 = config.comparison.experiment_12_dir +exp_dir_13 = config.comparison.experiment_13_dir + +exp_dir_14 = config.comparison.experiment_14_dir # 20k 24h manhattan +exp_dir_15 = config.comparison.experiment_15_dir +exp_dir_16 = config.comparison.experiment_16_dir + + +# exp_dir_1 = config.comparison.experiment_1_dir # 20k +# exp_dir_2 = config.comparison.experiment_2_dir +# exp_dir_3 = config.comparison.experiment_3_dir # 20k 10h +# exp_dir_4 = config.comparison.experiment_4_dir +# exp_dir_5 = config.comparison.experiment_5_dir # 20k 2h +# exp_dir_6 = config.comparison.experiment_6_dir +# exp_dir_7 = config.comparison.experiment_7_dir # 20k 1h +# exp_dir_8 = config.comparison.experiment_8_dir +# exp_dir_9 = config.comparison.experiment_9_dir # 20k Manhattan 1h +# exp_dir_10 = config.comparison.experiment_10_dir + + + +# result json files + +results_base_25k \ + = roadmaptools.inout.load_json(exp_dir_8 + config.statistics.result_file_name) +results_multipass_25k \ + = roadmaptools.inout.load_json(exp_dir_9 + config.statistics.result_file_name) +results_insertion_25k\ + = roadmaptools.inout.load_json(exp_dir_10 + config.statistics.result_file_name) + +results_base_50k \ + = roadmaptools.inout.load_json(exp_dir_11 + config.statistics.result_file_name) +results_multipass_50k \ + = roadmaptools.inout.load_json(exp_dir_12 + config.statistics.result_file_name) +results_insertion_50k\ + = roadmaptools.inout.load_json(exp_dir_13 + config.statistics.result_file_name) + +results_base_24k_24h \ + = roadmaptools.inout.load_json(exp_dir_14 + config.statistics.result_file_name) +results_multipass_24k_24h \ + = roadmaptools.inout.load_json(exp_dir_15 + config.statistics.result_file_name) +results_insertion_24k_24h\ + = roadmaptools.inout.load_json(exp_dir_16 + config.statistics.result_file_name) + +""" +results_PF_base \ + = roadmaptools.inout.load_json(exp_dir_1 + config.statistics.result_file_name) +results_PF_insertion\ + = roadmaptools.inout.load_json(exp_dir_2 + config.statistics.result_file_name) + +results_PF_base_10h \ + = roadmaptools.inout.load_json(exp_dir_3 + config.statistics.result_file_name) +results_PF_insertion_10h \ + = roadmaptools.inout.load_json(exp_dir_4 + config.statistics.result_file_name) + +results_PF_base_2h \ + = roadmaptools.inout.load_json(exp_dir_5 + config.statistics.result_file_name) +results_PF_insertion_2h\ + = roadmaptools.inout.load_json(exp_dir_6 + config.statistics.result_file_name) + +results_PF_base_1h \ + = roadmaptools.inout.load_json(exp_dir_7 + config.statistics.result_file_name) +results_PF_insertion_1h\ + = roadmaptools.inout.load_json(exp_dir_8 + config.statistics.result_file_name) + +results_PF_base_1h_manhattan \ + = roadmaptools.inout.load_json(exp_dir_9 + config.statistics.result_file_name) +results_PF_insertion_1h_manhattan\ + = roadmaptools.inout.load_json(exp_dir_10 + config.statistics.result_file_name) +""" + +# traffic load + +loads_base_25k = traffic_load.load_all_edges_load_history( + exp_dir_8 + config.statistics.all_edges_load_history_file_name) +loads_multipass_25k = traffic_load.load_all_edges_load_history( + exp_dir_9 + config.statistics.all_edges_load_history_file_name) +loads_insertion_25k = traffic_load.load_all_edges_load_history( + exp_dir_10 + config.statistics.all_edges_load_history_file_name) + +loads_base_50k = traffic_load.load_all_edges_load_history( + exp_dir_11 + config.statistics.all_edges_load_history_file_name) +loads_multipass_50k = traffic_load.load_all_edges_load_history( + exp_dir_12 + config.statistics.all_edges_load_history_file_name) +loads_insertion_50k = traffic_load.load_all_edges_load_history( + exp_dir_13 + config.statistics.all_edges_load_history_file_name) + +loads_base_24k_24h = traffic_load.load_all_edges_load_history( + exp_dir_14 + config.statistics.all_edges_load_history_file_name) +loads_multipass_24k_24h = traffic_load.load_all_edges_load_history( + exp_dir_15 + config.statistics.all_edges_load_history_file_name) +loads_insertion_24k_24h = traffic_load.load_all_edges_load_history( + exp_dir_16 + config.statistics.all_edges_load_history_file_name) + +""" +loads_PF_base = traffic_load.load_all_edges_load_history( + exp_dir_1 + config.statistics.all_edges_load_history_file_name) +loads_PF_insertion = traffic_load.load_all_edges_load_history( + exp_dir_2 + config.statistics.all_edges_load_history_file_name) + +loads_PF_base_10h = traffic_load.load_all_edges_load_history( + exp_dir_3 + config.statistics.all_edges_load_history_file_name) +loads_PF_insertion_10h = traffic_load.load_all_edges_load_history( + exp_dir_4 + config.statistics.all_edges_load_history_file_name) + +loads_PF_base_2h = traffic_load.load_all_edges_load_history( + exp_dir_5 + config.statistics.all_edges_load_history_file_name) +loads_PF_insertion_2h = traffic_load.load_all_edges_load_history( + exp_dir_6 + config.statistics.all_edges_load_history_file_name) + +loads_PF_base_1h = traffic_load.load_all_edges_load_history( + exp_dir_7 + config.statistics.all_edges_load_history_file_name) +loads_PF_insertion_1h = traffic_load.load_all_edges_load_history( + exp_dir_8 + config.statistics.all_edges_load_history_file_name) + +loads_PF_base_1h_manhattan = traffic_load.load_all_edges_load_history( + exp_dir_9 + config.statistics.all_edges_load_history_file_name) +loads_PF_insertion_1h_manhattan = traffic_load.load_all_edges_load_history( + exp_dir_10 + config.statistics.all_edges_load_history_file_name) +""" + + + +histogram = TrafficDensityHistogram(edge_object_data) + +# compute data for output from result + +base_data_1h_25k = compute_stats(results_base_25k, histogram, loads_base_25k["ALL"], exp_dir_8, edge_data) +multipass_data_1h_25k = compute_stats(results_multipass_25k, histogram, loads_multipass_25k["ALL"], exp_dir_9, edge_data) +insertion_data_1h_25k = compute_stats(results_insertion_25k, histogram, loads_insertion_25k["ALL"], exp_dir_10, edge_data) + +base_data_1h_50k = compute_stats(results_base_50k, histogram, loads_base_50k["ALL"], exp_dir_11, edge_data) +multipass_data_1h_50k = compute_stats(results_multipass_50k, histogram, loads_multipass_50k["ALL"], exp_dir_12, edge_data) +insertion_data_1h_50k = compute_stats(results_insertion_50k, histogram, loads_insertion_50k["ALL"], exp_dir_13, edge_data) + +base_data_24h_24k = compute_stats(results_base_24k_24h, histogram, loads_base_24k_24h["ALL"], exp_dir_14, edge_data) +multipass_data_24h_24k = compute_stats(results_multipass_24k_24h, histogram, loads_multipass_24k_24h["ALL"], exp_dir_15, edge_data) +insertion_data_24h_24k = compute_stats(results_insertion_24k_24h, histogram, loads_insertion_24k_24h["ALL"], exp_dir_16, edge_data) + +""" +# pf_base_data = compute_stats(results_PF_base, histogram, loads_PF_base["ALL"], exp_dir_1, edge_data) +# pf_insertion_data = compute_stats(results_PF_insertion, histogram, loads_PF_insertion["ALL"], +# exp_dir_2, edge_data) +# +# pf_base_data_10h = compute_stats(results_PF_base_10h, histogram, loads_PF_base_10h["ALL"], exp_dir_3, edge_data) +# pf_insertion_data_10h = compute_stats(results_PF_insertion_10h, histogram, loads_PF_insertion_10h["ALL"], +# exp_dir_4, edge_data) +# +# pf_base_data_2h = compute_stats(results_PF_base_2h, histogram, loads_PF_base_2h["ALL"], exp_dir_5, edge_data) +# pf_insertion_data_2h = compute_stats(results_PF_insertion_2h, histogram, loads_PF_insertion_2h["ALL"], +# exp_dir_6, edge_data) +# +# pf_base_data_1h = compute_stats(results_PF_base_1h, histogram, loads_PF_base_1h["ALL"], exp_dir_7, edge_data) +# pf_insertion_data_1h = compute_stats(results_PF_insertion_1h, histogram, loads_PF_insertion_1h["ALL"], +# exp_dir_8, edge_data) +# +# # Manhattan only +# pf_base_data_1h_manhattan = compute_stats(results_PF_base_1h_manhattan, histogram, loads_PF_base_1h_manhattan["ALL"], exp_dir_9, edge_data) +# pf_insertion_data_1h_manhattan = compute_stats(results_PF_insertion_1h_manhattan, histogram, loads_PF_insertion_1h_manhattan["ALL"], +# exp_dir_10, edge_data) +""" + + +output_table = np.array([["X", "1h 25k Manhattan BASE", "1h 25k Manhattan MULTIPASS", "1h 25k Manhattan INSERTION"], + ["Total veh. dist. traveled (km)", base_data_1h_25k[0], multipass_data_1h_25k[0], insertion_data_1h_25k[0]], + ["dropped passengers count", base_data_1h_25k[1], multipass_data_1h_25k[1], insertion_data_1h_25k[1]], + ["dropped packages count", base_data_1h_25k[2], multipass_data_1h_25k[2], insertion_data_1h_25k[2]], + ["shared demand count", base_data_1h_25k[3], multipass_data_1h_25k[3], insertion_data_1h_25k[3]], + ["used car count", base_data_1h_25k[4], multipass_data_1h_25k[4], insertion_data_1h_25k[4]], + ["avg. delay", base_data_1h_25k[6], multipass_data_1h_25k[6], insertion_data_1h_25k[6]], + ["avg. comp. time", base_data_1h_25k[5], multipass_data_1h_25k[5], insertion_data_1h_25k[5]]]) + +output_table_2 = np.array([["X", "1h 50k Manhattan BASE", "1h 50k Manhattan MULTIPASS", "1h 50k Manhattan INSERTION"], + ["Total veh. dist. traveled (km)", base_data_1h_50k[0], multipass_data_1h_50k[0], insertion_data_1h_50k[0]], + ["dropped passengers count", base_data_1h_50k[1], multipass_data_1h_50k[1], insertion_data_1h_50k[1]], + ["dropped packages count", base_data_1h_50k[2], multipass_data_1h_50k[2], insertion_data_1h_50k[2]], + ["shared demand count", base_data_1h_50k[3], multipass_data_1h_50k[3], insertion_data_1h_50k[3]], + ["used car count", base_data_1h_50k[4], multipass_data_1h_50k[4], insertion_data_1h_50k[4]], + ["avg. delay", base_data_1h_50k[6], multipass_data_1h_50k[6], insertion_data_1h_50k[6]], + ["avg. comp. time", base_data_1h_50k[5], multipass_data_1h_50k[5], insertion_data_1h_50k[5]]]) + +output_table_3 = np.array([["X", "24h 24k Manhattan BASE", "24h 24k Manhattan MULTIPASS", "24h 24k Manhattan INSERTION"], + ["Total veh. dist. traveled (km)", base_data_24h_24k[0], multipass_data_24h_24k[0], insertion_data_24h_24k[0]], + ["dropped passengers count", base_data_24h_24k[1], multipass_data_24h_24k[1], insertion_data_24h_24k[1]], + ["dropped packages count", base_data_24h_24k[2], multipass_data_24h_24k[2], insertion_data_24h_24k[2]], + ["shared demand count", base_data_24h_24k[3], multipass_data_24h_24k[3], insertion_data_24h_24k[3]], + ["used car count", base_data_24h_24k[4], multipass_data_24h_24k[4], insertion_data_24h_24k[4]], + ["avg. delay", base_data_24h_24k[6], multipass_data_24h_24k[6], insertion_data_24h_24k[6]], + ["avg. comp. time", base_data_24h_24k[5], multipass_data_24h_24k[5], insertion_data_24h_24k[5]]]) + +""" +# output_table = np.array([["X", "BASE", "INSERTION", "10h BASE", "10h INSERTION", "2h BASE", "2h INSERTION"], +# ["Total veh. dist. traveled (km)", pf_base_data[0], pf_insertion_data[0], pf_base_data_10h[0], pf_insertion_data_10h[0], pf_base_data_2h[0], pf_insertion_data_2h[0]], +# ["dropped passengers count", pf_base_data[1], pf_insertion_data[1], pf_base_data_10h[1], pf_insertion_data_10h[1], pf_base_data_2h[1], pf_insertion_data_2h[1]], +# ["dropped packages count", pf_base_data[2], pf_insertion_data[2], pf_base_data_10h[2], pf_insertion_data_10h[2], pf_base_data_2h[2], pf_insertion_data_2h[2]], +# ["shared demand count", pf_base_data[3], pf_insertion_data[3], pf_base_data_10h[3], pf_insertion_data_10h[3], pf_base_data_2h[3], pf_insertion_data_2h[3]], +# ["used car count", pf_base_data[4], pf_insertion_data[4], pf_base_data_10h[4], pf_insertion_data_10h[4], pf_base_data_2h[4], pf_insertion_data_2h[4]], +# ["avg. delay", pf_base_data[6], pf_insertion_data[6], pf_base_data_10h[6], pf_insertion_data_10h[6], pf_base_data_2h[6], pf_insertion_data_2h[6]], +# ["avg. comp. time", pf_base_data[5], pf_insertion_data[5], pf_base_data_10h[5], pf_insertion_data_10h[5], pf_base_data_2h[5], pf_insertion_data_2h[5]]]) +# +# output_table_2 = np.array([["X", "1h BASE", "1h INSERTION", "1h Manhattan BASE", "1h Manhattan INSERTION"], +# ["Total veh. dist. traveled (km)", pf_base_data_1h[0], pf_insertion_data_1h[0], pf_base_data_1h_manhattan[0], pf_insertion_data_1h_manhattan[0]], +# ["dropped passengers count", pf_base_data_1h[1], pf_insertion_data_1h[1], pf_base_data_1h_manhattan[1], pf_insertion_data_1h_manhattan[1]], +# ["dropped packages count", pf_base_data_1h[2], pf_insertion_data_1h[2], pf_base_data_1h_manhattan[2], pf_insertion_data_1h_manhattan[2]], +# ["shared demand count", pf_base_data_1h[3], pf_insertion_data_1h[3], pf_base_data_1h_manhattan[3], pf_insertion_data_1h_manhattan[3]], +# ["used car count", pf_base_data_1h[4], pf_base_data_1h[4], pf_base_data_1h_manhattan[4], pf_insertion_data_1h_manhattan[4]], +# ["avg. delay", pf_base_data_1h[6], pf_base_data_1h[6], pf_base_data_1h_manhattan[6], pf_insertion_data_1h_manhattan[6]], +# ["avg. comp. time", pf_base_data_1h[5], pf_base_data_1h[5], pf_base_data_1h_manhattan[5], pf_insertion_data_1h_manhattan[5]]]) +""" + +# console results +print("COMPARISON:") +print_table(output_table) +print() +print_table(output_table_2) +print() +print_table(output_table_3) + +""" +# latex table +print("Latex code:") +print(r"{\renewcommand{\arraystretch}{1.2}%") +print(r"\begin{tabular}{|+l|-r|-r|-r|-r|-r|-r|}") +print(r"\hline") +print(r" & & \multicolumn{5}{c|}{Mobility-on-Demand}") +print(r"\tabularnewline") +print(r"\cline{3-7}") +print(r" & \thead{Present} & \thead{No Ridesh.} & \thead{IH} & \thead{VGA} & \thead{VGA lim} & \thead{VGA PNAS}") +print(r"\tabularnewline") +print(r"\hline") +print(r"\hline") +print(r"Optimal & - & - & no & yes & no & no") +print(r"\tabularnewline") +print(r"\hline") +print(r"\rowstyle{\bfseries}") +print("Total veh. dist. (km) & \\num{{{}}} & \\num{{{}}}".format(present_state_data[0], pf_heuristic_data[0])) +print(r"\tabularnewline") +print(r"\hline") +print("Avg. delay (s) & {} & \\num{{{}}}".format("-", pf_heuristic_data[7])) +print(r"\tabularnewline") +print(r"\hline") +print(r"\hline") +print("Avg. density (veh/km) & \\num{{{}}} & \\num{{{}}}".format(round(present_state_data[1], 4), round(pf_heuristic_data[1], 4))) +print(r"\tabularnewline") +print(r"\hline") +print("Congested seg. & \\num{{{}}} & \\num{{{}}}".format(present_state_data[2], pf_heuristic_data[2])) +print(r"\tabularnewline") +print(r"\hline") +print("Heavily loaded seg. & \\num{{{}}} & \\num{{{}}}".format(round(present_state_data[4], 1), round(pf_heuristic_data[4], 1))) +print(r"\tabularnewline") +print(r"\hline") +print("Used Vehicles & \\num{{{}}} & \\num{{{}}}".format(present_state_data[5], pf_heuristic_data[5])) +print(r"\tabularnewline") +print(r"\hline") +print("Avg. comp. time (ms) & {} & \\num{{{}}}".format("-", pf_heuristic_data[6])) +print(r"\tabularnewline") +print(r"\hline") +print(r"\end{tabular}}") +""" + +""" +# To text +print("Abstract") + +percentage_reduction_compared_to_no_ridesharing \ + = int(round((pf_heuristic_data[0] - vga_data[0]) / pf_heuristic_data[0] * 100)) +print("We found that the system that uses optimal ridesharing assignments subject to the maximum travel delay of " + "4 minutes reduces the vehicle distance driven by \\SI{{{}}}{{\\percent}}".format( + percentage_reduction_compared_to_no_ridesharing)) + +percentage_reduction_compared_to_ih \ + = int(round((insertion_heuristic_data[0] - vga_data[0]) / insertion_heuristic_data[0] * 100)) +print("Furthermore, we found that the optimal assignments result in a \\SI{{{}}}{{\\percent}} " + " reduction in vehicle distance driven.".format( + percentage_reduction_compared_to_ih)) + +delay_reduction \ + = int(round((insertion_heuristic_data[7] - vga_data[7]) / insertion_heuristic_data[7] * 100)) +print("and \\SI{{{}}}{{\\percent}} lower average passenger travel delay compared to a system that uses " + "insertion heuristic".format(delay_reduction)) + +print("Our evaluation revealed that optimal ridesharing assignments can reduce the distance driven in the system by" + " \\SI{{{}}}{{\\percent}} ".format(percentage_reduction_compared_to_no_ridesharing)) + +print("Specifically, in the system that uses optimal assignments, the total vehicle distance driven is reduced by" + " \\SI{{{}}}{{\\percent}}, " + "and simultaneously, average passenger travel delay is reduced by~\\SI{{{}}}{{\\percent}}".format( + percentage_reduction_compared_to_ih, delay_reduction)) + +absolute_reduction_compared_to_ih = insertion_heuristic_data[0] - vga_data[0] +print("We can see that when using the \\gls{{vga}} method instead of Insertion Heuristic during the morning peak, we can " + "save almost \\SI{{{}}}{{\\km}} of vehicle distance driven, which is more than \\SI{{{}}}{{\\percent}} reduction." + .format(absolute_reduction_compared_to_ih, percentage_reduction_compared_to_ih)) + +absolute_reduction_compared_to_no_ridesharing = pf_heuristic_data[0] - vga_data[0] +absolute_reduction_compared_to_present_state = present_state_data[0] - vga_data[0] +percentage_reduction_compared_to_present_state \ + = int(round((present_state_data[0] - vga_data[0]) / present_state_data[0] * 100)) +print("When comparing with the no ridesharing scenario and with the present state, the \\gls{{vga}} method saves over " + "\\SI{{{}}}{{\\km}} (\\SI{{{}}}{{\\percent}}) and \\SI{{{}}}{{\\km}} (\\SI{{{}}}{{\\percent}}) respectively." + .format(absolute_reduction_compared_to_no_ridesharing, percentage_reduction_compared_to_no_ridesharing, + absolute_reduction_compared_to_present_state, percentage_reduction_compared_to_present_state)) + +vehicles_saved = insertion_heuristic_data[5] - vga_data[5] +vehicles_saved_percent = int(round((insertion_heuristic_data[5] - vga_data[5]) / insertion_heuristic_data[5] * 100)) +print("The results confirm that the \\gls{{vga}} mehod indeed makes the \\gls{{mod}} system more efficient, saving " + "over \\SI{{{}}}{{vehicles}}~(\\SI{{{}}}{{\percent}}) over the Insertion Heuristic." + .format(vehicles_saved, vehicles_saved_percent)) + +traffic_density_reduction_overih_percent = int(round((insertion_heuristic_data[1] - vga_data[1]) / insertion_heuristic_data[1] * 100)) +traffic_density_reduction_no_ridesharing_percent = int(round((pf_heuristic_data[1] - vga_data[1]) / pf_heuristic_data[1] * 100)) +traffic_density_reduction_current_state_percent = int(round((present_state_data[1] - vga_data[1]) / present_state_data[1] * 100)) +print("in the morning peak, using the VGA method decreases the average traffic density by \\SI{{{}}}{{\\percent}} over the " + "Insertion Heuristic ridesharing, and by \\SI{{{}}}{{\\percent}} and \\SI{{{}}}{{\\percent}} over the MoD without " + "ridesharing and the current state respectively.".format(traffic_density_reduction_overih_percent, + traffic_density_reduction_no_ridesharing_percent, traffic_density_reduction_current_state_percent)) + +percentage_increase_no_ridesharing_compared_to_present_state \ + = int(round((pf_heuristic_data[0] - present_state_data[0]) / present_state_data[0] * 100)) +# print("When using \\gls{{mod}}, the size of the vehicle fleet can be reduced almost four times, at the cost of about " +# "\\SI{{{}}}{{\\percent}} increase in traveled distance due to empty trips between passengers." +# .format(percentage_increase_no_ridesharing_compared_to_present_state)) + +percentage_reduction_ih_compared_to_present_state \ + = int(round((present_state_data[0] - insertion_heuristic_data[0]) / present_state_data[0] * 100)) +# print("We also demonstrated that when using Insertion Heuristic ridesharing, the number of vehicles can be reduced" +# " almost eight times compared to the present state, and the total traveled distance can be reduced " +# "by \\SI{{{}}}{{\\percent}}.".format(percentage_reduction_ih_compared_to_present_state)) + + +print("Finally, the results confirmed that the optimal \\gls{{vga}} method is significantly more efficient than " + "the Insertion Heuristic, reducing the traveled distance by \\SI{{{}}}{{\\percent}}:" + .format(percentage_reduction_compared_to_present_state)) + +print("The results confirmed that ridesharing dramatically increases the efficiency of an MoD system: by employing " + "the \\gls{{vga}} method, we reduce the total distance driven in the system by more then \\SI{{{}}}{{\\percent}}." + .format(percentage_reduction_compared_to_no_ridesharing)) + +print("Our results show that using the VGA method instead of the Insertion Heuristic, we can reduce the total distance " + "traveled by more than \\SI{{{}}}{{\\percent}} while reducing the passenger delays by \\SI{{{}}}{{\\percent}}." + .format(percentage_reduction_compared_to_ih, delay_reduction)) + +percentage_reduction_limited_compared_to_ih \ + = int(round((insertion_heuristic_data[0] - vga_limited_data[0]) / insertion_heuristic_data[0] * 100)) +computation_time_reduction_vga_limited_compared_to_vga \ + = int(round((vga_data[6] - vga_limited_data[6]) / vga_data[6] * 100)) +print("Finally, our resource-constrained VGA method provides more than \\SI{{{}}}{{\\percent}} travel distance saving" + " over IH while reducing the computational time by almost \\SI{{{}}}{{\\percent}}." + .format(percentage_reduction_limited_compared_to_ih, computation_time_reduction_vga_limited_compared_to_vga)) +""" diff --git a/python/simod/statistics/model/edges.py b/python/simod/statistics/model/edges.py index d51304e1..a276d2ba 100644 --- a/python/simod/statistics/model/edges.py +++ b/python/simod/statistics/model/edges.py @@ -16,7 +16,7 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . # -from amodsim.init import config +from simod.init import config import pandas import roadmaptools.inout diff --git a/python/simod/statistics/model/occupancy.py b/python/simod/statistics/model/occupancy.py index 46648a5d..8b6fec00 100644 --- a/python/simod/statistics/model/occupancy.py +++ b/python/simod/statistics/model/occupancy.py @@ -16,13 +16,14 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . # -from amodsim.init import config +from simod.init import config import pandas from pandas import DataFrame occupancy_cols = ["tick", "vehicle_id", "occupancy"] +combined_occupancy_cols = ["tick", "vehicle_id", "people_occupancy", "package_occupancy"] def load(experiment_dir: str) -> DataFrame: @@ -30,10 +31,28 @@ def load(experiment_dir: str) -> DataFrame: = pandas.read_csv(experiment_dir + config.statistics.occupancies_file_name, names=occupancy_cols) return occupancy_data +def load_packages(experiment_dir: str) -> DataFrame: + occupancy_data \ + = pandas.read_csv(experiment_dir + config.statistics.packages_occupancies_file_name, names=occupancy_cols) + return occupancy_data + +def load_combined_occupancy(experiment_dir: str) -> DataFrame: + occupancy_data = pandas.read_csv(experiment_dir + config.statistics.combined_occupancies_file_name, names=combined_occupancy_cols) + return occupancy_data + +def load_no_people(experiment_dir: str) -> DataFrame: + occupancy_data \ + = pandas.read_csv(experiment_dir + config.statistics.no_people_occupancies_file_name, names=occupancy_cols) + return occupancy_data + +def load_people_onboard(experiment_dir: str) -> DataFrame: + occupancy_data \ + = pandas.read_csv(experiment_dir + config.statistics.people_onboard_occupancies_file_name, names=occupancy_cols) + return occupancy_data def filter_window(data: DataFrame) -> DataFrame: tick_start = config.analysis.chosen_window_start * 10 - return data[data.tick > tick_start] + return data[data.tick > tick_start] def get_occupancies(data: DataFrame, window_only: bool = False): @@ -41,4 +60,12 @@ def get_occupancies(data: DataFrame, window_only: bool = False): tick_start = config.analysis.chosen_window_start * 10 data = data[data.tick > tick_start] - return data["occupancy"] \ No newline at end of file + return data["occupancy"] + + +def get_combined_occupancies(data: DataFrame, window_only: bool = False): + if window_only: + tick_start = config.analysis.chosen_window_start * 10 + data = data[data.tick > tick_start] + + return [data["people_occupancy"], data["package_occupancy"]] \ No newline at end of file diff --git a/python/simod/statistics/model/ridesharing.py b/python/simod/statistics/model/ridesharing.py index 26e9ad97..c0460b78 100644 --- a/python/simod/statistics/model/ridesharing.py +++ b/python/simod/statistics/model/ridesharing.py @@ -16,7 +16,7 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . # -from amodsim.init import config +from simod.init import config import pandas import roadmaptools.inout diff --git a/python/simod/statistics/model/service.py b/python/simod/statistics/model/service.py index aeb2e509..c45f62c3 100644 --- a/python/simod/statistics/model/service.py +++ b/python/simod/statistics/model/service.py @@ -16,7 +16,7 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . # -from amodsim.init import config +from simod.init import config import pandas diff --git a/python/simod/statistics/model/traffic_load.py b/python/simod/statistics/model/traffic_load.py index c5d4a2bf..3561e808 100644 --- a/python/simod/statistics/model/traffic_load.py +++ b/python/simod/statistics/model/traffic_load.py @@ -18,7 +18,7 @@ # from pandas.io.formats.format import return_docstring -from amodsim.init import config +from simod.init import config import json import matplotlib @@ -28,7 +28,7 @@ from matplotlib import cm from roadmaptools.printer import print_info -from amodsim.json_cache import load_json_file +from simod.json_cache import load_json_file CRITICAL_DENSITY = config.critical_density diff --git a/python/simod/statistics/model/transit.py b/python/simod/statistics/model/transit.py index c90f3e87..0adb661e 100644 --- a/python/simod/statistics/model/transit.py +++ b/python/simod/statistics/model/transit.py @@ -16,13 +16,13 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . # -from amodsim.init import config +from simod.init import config import pandas from typing import Union from pandas import DataFrame -from amodsim.statistics.model.vehicle_state import VehicleState +from simod.statistics.model.vehicle_state import VehicleState cols = ["time", "edge_id", "vehicle_state"] diff --git a/python/simod/statistics/occupancy.py b/python/simod/statistics/occupancy.py index d0802939..602e5e3b 100644 --- a/python/simod/statistics/occupancy.py +++ b/python/simod/statistics/occupancy.py @@ -17,14 +17,14 @@ # along with this program. If not, see . # -from amodsim.init import config +from simod.init import config from tqdm import tqdm import numpy as np import matplotlib.pyplot as plt import matplotlib import roadmaptools.inout -import amodsim.utils +import simod.utils from matplotlib.ticker import FuncFormatter from pandas import DataFrame diff --git a/python/simod/statistics/traffic_density_histogram.py b/python/simod/statistics/traffic_density_histogram.py index 0296e02c..81a22c68 100644 --- a/python/simod/statistics/traffic_density_histogram.py +++ b/python/simod/statistics/traffic_density_histogram.py @@ -16,17 +16,17 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . # -from amodsim.init import config +from simod.init import config import matplotlib.pyplot as plt import numpy as np from matplotlib import rcParams from roadmaptools.printer import print_info, print_table -from amodsim.statistics.model.traffic_load import WINDOW_START, WINDOW_END, WINDOW_LENGTH -from amodsim.statistics.model.vehicle_state import VehicleState -from amodsim.utils import to_percetnt, col_to_percent -import amodsim.statistics.model.traffic_load as traffic_load +from simod.statistics.model.traffic_load import WINDOW_START, WINDOW_END, WINDOW_LENGTH +from simod.statistics.model.vehicle_state import VehicleState +from simod.utils import to_percetnt, col_to_percent +import simod.statistics.model.traffic_load as traffic_load HISTOGRAM_SAMPLES = 16 diff --git a/src/main/java/cz/cvut/fel/aic/simod/DemandData.java b/src/main/java/cz/cvut/fel/aic/simod/DemandData.java index edcbe6a7..4501b4d0 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/DemandData.java +++ b/src/main/java/cz/cvut/fel/aic/simod/DemandData.java @@ -20,6 +20,7 @@ import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode; import cz.cvut.fel.aic.simod.entity.DemandAgent; +import cz.cvut.fel.aic.simod.ridesharing.peoplefreightsheuristic.DemandPackage; /** * @@ -29,11 +30,18 @@ public class DemandData { public SimulationNode[] locations; public DemandAgent demandAgent; + public DemandPackage demandPackage; public DemandData(SimulationNode[] locList, DemandAgent demandAgent) { this.locations = locList; this.demandAgent = demandAgent; + this.demandPackage = null; } + public DemandData(SimulationNode[] locList, DemandPackage demandPackage) { + this.locations = locList; + this.demandPackage = demandPackage; + this.demandAgent = null; + } } diff --git a/src/main/java/cz/cvut/fel/aic/simod/MainModule.java b/src/main/java/cz/cvut/fel/aic/simod/MainModule.java index 15d96090..00088385 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/MainModule.java +++ b/src/main/java/cz/cvut/fel/aic/simod/MainModule.java @@ -18,6 +18,8 @@ */ package cz.cvut.fel.aic.simod; +import cz.cvut.fel.aic.simod.ridesharing.*; +import cz.cvut.fel.aic.simod.ridesharing.peoplefreightsheuristic.*; import cz.cvut.fel.aic.simod.traveltimecomputation.DistanceMatrixTravelTimeProvider; import cz.cvut.fel.aic.simod.traveltimecomputation.TNRTravelTimeProvider; import cz.cvut.fel.aic.simod.traveltimecomputation.TNRAFTravelTimeProvider; @@ -57,11 +59,7 @@ import cz.cvut.fel.aic.simod.visio.DemandLayer; import cz.cvut.fel.aic.simod.visio.DemandLayerWithJitter; import cz.cvut.fel.aic.geographtools.TransportMode; -import cz.cvut.fel.aic.simod.ridesharing.DARPSolver; -import cz.cvut.fel.aic.simod.ridesharing.PlanCostProvider; -import cz.cvut.fel.aic.simod.ridesharing.RidesharingDispatcher; -import cz.cvut.fel.aic.simod.ridesharing.RidesharingOnDemandVehicleFactory; -import cz.cvut.fel.aic.simod.ridesharing.StandardPlanCostProvider; + import java.io.File; import java.io.IOException; import java.nio.file.Files; @@ -77,12 +75,12 @@ public class MainModule extends StandardAgentPolisModule{ private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(MainModule.class); - private final SimodConfig SimodConfig; - - public MainModule(SimodConfig SimodConfig, File localConfigFile) { - super(SimodConfig, localConfigFile, "agentpolis"); - setLoggerFilePath(SimodConfig.simodExperimentDir); - this.SimodConfig = SimodConfig; + private final SimodConfig simodConfig; + + public MainModule(SimodConfig simodConfig, File localConfigFile) { + super(simodConfig, localConfigFile, "agentpolis"); + setLoggerFilePath(simodConfig.simodExperimentDir); + this.simodConfig = simodConfig; init(); } @@ -94,11 +92,11 @@ protected void bindVisioInitializer() { @Override protected void configureNext() { bind(new TypeLiteral>(){}).toInstance(Sets.immutableEnumSet(TransportMode.CAR)); - bind(SimodConfig.class).toInstance(SimodConfig); + bind(SimodConfig.class).toInstance(simodConfig); bind(EntityStorage.class).to(VehicleStorage.class); bind(MapInitializer.class).to(GeojsonMapInitializer.class); - if(SimodConfig.useTripCache){ + if(simodConfig.useTripCache){ bind(TripsUtil.class).to(TripsUtilCached.class); } bind(DemandLayer.class).to(DemandLayerWithJitter.class); @@ -109,7 +107,7 @@ protected void configureNext() { bind(PhysicalVehicleDriveFactory.class).to(StandardDriveFactory.class); } - switch(SimodConfig.travelTimeProvider){ + switch(simodConfig.travelTimeProvider){ case "dm": bind(TravelTimeProvider.class).to(DistanceMatrixTravelTimeProvider.class); break; @@ -131,13 +129,39 @@ protected void configureNext() { break; } - if(SimodConfig.ridesharing.on){ - bind(OnDemandVehicleFactorySpec.class).to(RidesharingOnDemandVehicleFactory.class); - bind(StationsDispatcher.class).to(RidesharingDispatcher.class); + if(simodConfig.ridesharing.on) { + if (simodConfig.packagesOn) { + bind(OnDemandVehicleFactorySpec.class).to(PeopleFreightVehicleFactory.class); + bind(PeopleFreightVehicleFactorySpec.class).to(PeopleFreightVehicleFactory.class); + bind(StationsDispatcher.class).to(RidesharingPFDispatcher.class); + + install(new FactoryModuleBuilder().implement(DefaultPFPlanCompRequest.class, DefaultPFPlanCompRequest.class) + .build(DefaultPFPlanCompRequest.DefaultPFPlanComputationRequestFactory.class)); + install(new FactoryModuleBuilder().implement(PlanComputationRequestPeople.class, PlanComputationRequestPeople.class) + .build(PlanComputationRequestPeople.PlanComputationRequestPeopleFactory.class)); + install(new FactoryModuleBuilder().implement(PlanComputationRequestFreight.class, PlanComputationRequestFreight.class) + .build(PlanComputationRequestFreight.PlanComputationRequestFreightFactory.class)); + } + else { + bind(OnDemandVehicleFactorySpec.class).to(RidesharingOnDemandVehicleFactory.class); + bind(StationsDispatcher.class).to(RidesharingDispatcher.class); + + install(new FactoryModuleBuilder().implement(DefaultPlanComputationRequest.class, DefaultPlanComputationRequest.class) + .build(DefaultPlanComputationRequest.DefaultPlanComputationRequestFactory.class)); + } + bind(PlanCostProvider.class).to(StandardPlanCostProvider.class); - install(new FactoryModuleBuilder().implement(DefaultPlanComputationRequest.class, DefaultPlanComputationRequest.class) - .build(DefaultPlanComputationRequest.DefaultPlanComputationRequestFactory.class)); - switch(SimodConfig.ridesharing.method){ + +// if (simodConfig.packagesOn) { +// install(new FactoryModuleBuilder().implement(DefaultPFPlanCompRequest.class, DefaultPFPlanCompRequest.class) +// .build(DefaultPFPlanCompRequest.DefaultPFPlanComputationRequestFactory.class)); +// } +// else { +// install(new FactoryModuleBuilder().implement(DefaultPlanComputationRequest.class, DefaultPlanComputationRequest.class) +// .build(DefaultPlanComputationRequest.DefaultPlanComputationRequestFactory.class)); +// } + + switch(simodConfig.ridesharing.method) { case "insertion-heuristic": bind(DARPSolver.class).to(InsertionHeuristicSolver.class); break; @@ -146,15 +170,31 @@ protected void configureNext() { bind(SingleVehicleDARPSolver.class).to(ArrayOptimalVehiclePlanFinder.class); // bind(OptimalVehiclePlanFinder.class).to(PlanBuilderOptimalVehiclePlanFinder.class); break; + case "pf-base": + bind(DARPSolver.class).to(PFSolverBase.class); + bind(DARPSolverPFShared.class).to(PFSolverBase.class); + break; + case "pf-multipass": + bind(DARPSolver.class).to(PFSolverMultipass.class); + bind(DARPSolverPFShared.class).to(PFSolverMultipass.class); + break; + case "pf-multi-insertion": + bind(DARPSolver.class).to(PFSolverMultiInsertion.class); + bind(DARPSolverPFShared.class).to(PFSolverMultiInsertion.class); } } - else{ + else { bind(OnDemandVehicleFactorySpec.class).to(OnDemandVehicleFactory.class); } + install(new FactoryModuleBuilder().implement(DemandAgent.class, DemandAgent.class) .build(DemandAgentFactory.class)); + if (true) { // (simodConfig.packagesOn) + install(new FactoryModuleBuilder().implement(DemandPackage.class, DemandPackage.class) + .build(DemandPackage.DemandPackageFactory.class)); + } - if(SimodConfig.rebalancing.on){ + if(simodConfig.rebalancing.on){ install(new FactoryModuleBuilder().implement(OnDemandVehicleStation.class, RebalancingOnDemandVehicleStation.class) .build(RebalancingOnDemandVehicleStation.OnDemandVehicleStationFactory.class)); } @@ -192,7 +232,7 @@ private void setLoggerFilePath(String experiments_path) { } protected void init() { - deleteFiles(new File(SimodConfig.simodExperimentDir)); + deleteFiles(new File(simodConfig.simodExperimentDir)); } } diff --git a/src/main/java/cz/cvut/fel/aic/simod/OnDemandVehiclesSimulation.java b/src/main/java/cz/cvut/fel/aic/simod/OnDemandVehiclesSimulation.java index 1454ace0..20b010c7 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/OnDemandVehiclesSimulation.java +++ b/src/main/java/cz/cvut/fel/aic/simod/OnDemandVehiclesSimulation.java @@ -32,8 +32,10 @@ import cz.cvut.fel.aic.simod.traveltimecomputation.TravelTimeProvider; import cz.cvut.fel.aic.simod.statistics.Statistics; import cz.cvut.fel.aic.simod.tripUtil.TripsUtilCached; + import java.io.File; import java.net.MalformedURLException; + import org.slf4j.LoggerFactory; /** @@ -42,42 +44,42 @@ public class OnDemandVehiclesSimulation { private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(OnDemandVehiclesSimulation.class); - + public static void main(String[] args) throws MalformedURLException { new OnDemandVehiclesSimulation().run(args); } - public static void checkPaths(SimodConfig config, AgentpolisConfig agentpolisConfig){ + public static void checkPaths(SimodConfig config, AgentpolisConfig agentpolisConfig) { String[] pathsForRead = { - config.tripsPath, - config.stationPositionFilepath, - agentpolisConfig.mapNodesFilepath, - agentpolisConfig.mapEdgesFilepath + config.tripsPath, + config.stationPositionFilepath, + agentpolisConfig.mapNodesFilepath, + agentpolisConfig.mapEdgesFilepath }; - + String[] pathsForWrite = { - config.statistics.allEdgesLoadHistoryFilePath, - config.statistics.darpSolverComputationalTimesFilePath, - config.statistics.groupDataFilePath, - config.statistics.occupanciesFilePath, - config.statistics.resultFilePath, - config.statistics.ridesharingFilePath, - config.statistics.serviceFilePath, - config.statistics.transitStatisticFilePath, - config.statistics.tripDistancesFilePath, - config.ridesharing.vga.groupGeneratorLogFilepath + config.statistics.allEdgesLoadHistoryFilePath, + config.statistics.darpSolverComputationalTimesFilePath, + config.statistics.groupDataFilePath, + config.statistics.occupanciesFilePath, + config.statistics.resultFilePath, + config.statistics.ridesharingFilePath, + config.statistics.serviceFilePath, + config.statistics.transitStatisticFilePath, + config.statistics.tripDistancesFilePath, + config.ridesharing.vga.groupGeneratorLogFilepath }; - - try{ - for(String pathForRead: pathsForRead){ + + try { + for (String pathForRead : pathsForRead) { FileUtils.checkFilePathForRead(pathForRead); } - - for(String pathForWrite: pathsForWrite){ + + for (String pathForWrite : pathsForWrite) { FileUtils.checkFilePathForWrite(pathForWrite); } } - catch(Exception e){ + catch (Exception e) { e.printStackTrace(); System.exit(-1); } @@ -85,44 +87,51 @@ public static void checkPaths(SimodConfig config, AgentpolisConfig agentpolisCon public void run(String[] args) { SimodConfig config = new SimodConfig(); - + File localConfigFile = null; - if(args.length > 0){ + if (args.length > 0) { localConfigFile = new File(args[0]); - } + } Injector injector = new AgentPolisInitializer(new MainModule(config, localConfigFile)).initialize(); - + checkPaths(config, injector.getInstance(AgentpolisConfig.class)); - + // overide the disfunctional old no ridesharing setup - if(!config.ridesharing.on){ + if (!config.ridesharing.on) { config.ridesharing.on = true; config.ridesharing.vehicleCapacity = 1; } - - SimulationCreator creator = injector.getInstance(SimulationCreator.class); - + + SimulationCreator creator = injector.getInstance(SimulationCreator.class); + // prepare map, entity storages... creator.prepareSimulation(injector.getInstance(MapInitializer.class).getMap()); - + // load stations injector.getInstance(StationsInitializer.class).loadStations(); - if(config.rebalancing.on){ + if (config.rebalancing.on) { // start rebalancing injector.getInstance(ReactiveRebalancing.class).start(); } - + // load trips TripTransform tripTransform = injector.getInstance(TripTransform.class); injector.getInstance(EventInitializer.class).initialize( - tripTransform.loadTripsFromTxt(new File(config.tripsPath)), null); + tripTransform.loadTripsFromTxt(new File(config.tripsPath)), null); + + // if packages are existing -> load packages + if (config.packagesOn) { + injector.getInstance(EventInitializer.class).initializePackages( + tripTransform.loadPackagesFromTxt(new File(config.packagesPath)), null + ); + } injector.getInstance(StatisticInitializer.class).initialize(); - + // start it up creator.startSimulation(); diff --git a/src/main/java/cz/cvut/fel/aic/simod/StationsDispatcher.java b/src/main/java/cz/cvut/fel/aic/simod/StationsDispatcher.java index 09d80a39..bfea7aed 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/StationsDispatcher.java +++ b/src/main/java/cz/cvut/fel/aic/simod/StationsDispatcher.java @@ -48,8 +48,10 @@ public class StationsDispatcher extends EventHandlerAdapter{ - protected int numberOfDemandsDropped; - + protected int numberOfPassangersDropped; + + protected int numberOfPackagesDropped; + private int demandsCount; private int rebalancingDropped; @@ -63,7 +65,7 @@ public int getNumberOfDemandsNotServedFromNearestStation() { } public int getNumberOfDemandsDropped() { - return numberOfDemandsDropped; + return numberOfPassangersDropped; } public int getDemandsCount() { @@ -89,7 +91,8 @@ public StationsDispatcher(OnDemandvehicleStationStorage onDemandvehicleStationSt this.eventProcessor = eventProcessor; this.config = config; this.tripIdGenerator = tripIdGenerator; - numberOfDemandsDropped = 0; + numberOfPassangersDropped = 0; + numberOfPackagesDropped = 0; demandsCount = 0; rebalancingDropped = 0; } @@ -170,7 +173,7 @@ protected void serveDemand(SimulationNode startNode, DemandData demandData) { nearestStation.handleTripRequest(demandData); } else{ - numberOfDemandsDropped++; + numberOfPassangersDropped++; } } diff --git a/src/main/java/cz/cvut/fel/aic/simod/config/InsertionHeuristic.java b/src/main/java/cz/cvut/fel/aic/simod/config/InsertionHeuristic.java index 2f90429a..3bf0098c 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/config/InsertionHeuristic.java +++ b/src/main/java/cz/cvut/fel/aic/simod/config/InsertionHeuristic.java @@ -4,9 +4,9 @@ import java.util.Map; public class InsertionHeuristic { - public Boolean recomputeWaitingRequests; + public Boolean recomputeWaitingRequests; - public InsertionHeuristic(Map insertionHeuristic) { - this.recomputeWaitingRequests = (Boolean) insertionHeuristic.get("recompute_waiting_requests"); - } + public InsertionHeuristic(Map insertionHeuristic) { + this.recomputeWaitingRequests = (Boolean) insertionHeuristic.get("recompute_waiting_requests"); + } } diff --git a/src/main/java/cz/cvut/fel/aic/simod/config/SimodConfig.java b/src/main/java/cz/cvut/fel/aic/simod/config/SimodConfig.java index ef16dedd..234a4851 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/config/SimodConfig.java +++ b/src/main/java/cz/cvut/fel/aic/simod/config/SimodConfig.java @@ -8,46 +8,56 @@ import ninja.fido.config.GeneratedConfig; public class SimodConfig implements GeneratedConfig { - public Boolean useTripCache; - - public String simodExperimentDir; - - public String experimentName; - public String simodDataDir; - public String tripsFilename; - - public String distanceMatrixFilepath; + public Integer packagesMaxDelay; public String edgePairsFilePath; + public Boolean packagesOn; + public String tripCacheFile; - public Stations stations; + public String packagesFilename; public String mapDir; - public String travelTimeProvider; - public Shortestpaths shortestpaths; - public Integer startTime; - public String tripsPath; public String edgesFilePath; + public Integer packagesCapacity; + public Double tripsMultiplier; public Integer vehiclesPerStation; - public Boolean simplifyGraph; - public Ridesharing ridesharing; public String stationPositionFilepath; + public Boolean useTripCache; + + public String simodExperimentDir; + + public String experimentName; + + public String tripsFilename; + + public String distanceMatrixFilepath; + + public Stations stations; + + public String travelTimeProvider; + + public Integer startTime; + + public String packagesPath; + + public Boolean simplifyGraph; + public Rebalancing rebalancing; public Statistics statistics; @@ -56,26 +66,31 @@ public SimodConfig() { } public SimodConfig fill(Map simodConfig) { - this.useTripCache = (Boolean) simodConfig.get("use_trip_cache"); - this.simodExperimentDir = (String) simodConfig.get("simod_experiment_dir"); - this.experimentName = (String) simodConfig.get("experiment_name"); this.simodDataDir = (String) simodConfig.get("simod_data_dir"); - this.tripsFilename = (String) simodConfig.get("trips_filename"); - this.distanceMatrixFilepath = (String) simodConfig.get("distance_matrix_filepath"); + this.packagesMaxDelay = (Integer) simodConfig.get("packages_max_delay"); this.edgePairsFilePath = (String) simodConfig.get("edge_pairs_file_path"); + this.packagesOn = (Boolean) simodConfig.get("packages_on"); this.tripCacheFile = (String) simodConfig.get("trip_cache_file"); - this.stations = new Stations((Map) simodConfig.get("stations")); + this.packagesFilename = (String) simodConfig.get("packages_filename"); this.mapDir = (String) simodConfig.get("map_dir"); - this.travelTimeProvider = (String) simodConfig.get("travel_time_provider"); this.shortestpaths = new Shortestpaths((Map) simodConfig.get("shortestpaths")); - this.startTime = (Integer) simodConfig.get("start_time"); this.tripsPath = (String) simodConfig.get("trips_path"); this.edgesFilePath = (String) simodConfig.get("edges_file_path"); + this.packagesCapacity = (Integer) simodConfig.get("packages_capacity"); this.tripsMultiplier = (Double) simodConfig.get("trips_multiplier"); this.vehiclesPerStation = (Integer) simodConfig.get("vehicles_per_station"); - this.simplifyGraph = (Boolean) simodConfig.get("simplify_graph"); this.ridesharing = new Ridesharing((Map) simodConfig.get("ridesharing")); this.stationPositionFilepath = (String) simodConfig.get("station_position_filepath"); + this.useTripCache = (Boolean) simodConfig.get("use_trip_cache"); + this.simodExperimentDir = (String) simodConfig.get("simod_experiment_dir"); + this.experimentName = (String) simodConfig.get("experiment_name"); + this.tripsFilename = (String) simodConfig.get("trips_filename"); + this.distanceMatrixFilepath = (String) simodConfig.get("distance_matrix_filepath"); + this.stations = new Stations((Map) simodConfig.get("stations")); + this.travelTimeProvider = (String) simodConfig.get("travel_time_provider"); + this.startTime = (Integer) simodConfig.get("start_time"); + this.packagesPath = (String) simodConfig.get("packages_path"); + this.simplifyGraph = (Boolean) simodConfig.get("simplify_graph"); this.rebalancing = new Rebalancing((Map) simodConfig.get("rebalancing")); this.statistics = new Statistics((Map) simodConfig.get("statistics")); return this; diff --git a/src/main/java/cz/cvut/fel/aic/simod/config/Statistics.java b/src/main/java/cz/cvut/fel/aic/simod/config/Statistics.java index 7b6ecbc2..788fd0a9 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/config/Statistics.java +++ b/src/main/java/cz/cvut/fel/aic/simod/config/Statistics.java @@ -5,60 +5,88 @@ import java.util.Map; public class Statistics { - public String resultFilePath; + public String resultFilePath; - public String occupanciesFilePath; + public String occupanciesFilePath; - public String ridesharingFileName; + public String occupanciesFileName; - public Integer statisticIntervalMilis; + public String packagesOccupanciesFilePath; - public String groupDataFilePath; + public String packagesOccupanciesFileName; - public String transitStatisticFilePath; + public String combinedOccupanciesFileName; - public String allEdgesLoadHistoryFilePath; + public String combinedOccupanciesFilePath; - public OnDemandVehicleStatistic onDemandVehicleStatistic; +// public String noPeopleOccupanciesFileName; - public String resultFileName; +// public String noPeopleOccupanciesFilePath; - public Integer allEdgesLoadIntervalMilis; +// public String peopleOnboardOccupanciesFileName; - public String tripDistancesFilePath; +// public String peopleOnboardOccupanciesFilePath; - public String occupanciesFileName; + public String ridesharingFileName; - public String darpSolverComputationalTimesFilePath; + public String ridesharingFilePath; - public String groupDataFilename; + public Integer statisticIntervalMilis; - public String allEdgesLoadHistoryFileName; + public String groupDataFilePath; - public String serviceFileName; + public String transitStatisticFilePath; - public String serviceFilePath; + public String allEdgesLoadHistoryFilePath; - public String ridesharingFilePath; + public OnDemandVehicleStatistic onDemandVehicleStatistic; - public Statistics(Map statistics) { - this.resultFilePath = (String) statistics.get("result_file_path"); - this.occupanciesFilePath = (String) statistics.get("occupancies_file_path"); - this.ridesharingFileName = (String) statistics.get("ridesharing_file_name"); - this.statisticIntervalMilis = (Integer) statistics.get("statistic_interval_milis"); - this.groupDataFilePath = (String) statistics.get("group_data_file_path"); - this.transitStatisticFilePath = (String) statistics.get("transit_statistic_file_path"); - this.allEdgesLoadHistoryFilePath = (String) statistics.get("all_edges_load_history_file_path"); - this.onDemandVehicleStatistic = new OnDemandVehicleStatistic((Map) statistics.get("on_demand_vehicle_statistic")); - this.resultFileName = (String) statistics.get("result_file_name"); - this.allEdgesLoadIntervalMilis = (Integer) statistics.get("all_edges_load_interval_milis"); - this.tripDistancesFilePath = (String) statistics.get("trip_distances_file_path"); - this.occupanciesFileName = (String) statistics.get("occupancies_file_name"); - this.darpSolverComputationalTimesFilePath = (String) statistics.get("darp_solver_computational_times_file_path"); - this.groupDataFilename = (String) statistics.get("group_data_filename"); - this.allEdgesLoadHistoryFileName = (String) statistics.get("all_edges_load_history_file_name"); - this.serviceFileName = (String) statistics.get("service_file_name"); - this.serviceFilePath = (String) statistics.get("service_file_path"); - this.ridesharingFilePath = (String) statistics.get("ridesharing_file_path"); - } + public String resultFileName; + + public Integer allEdgesLoadIntervalMilis; + + public String tripDistancesFilePath; + + public String darpSolverComputationalTimesFilePath; + + public String groupDataFilename; + + public String allEdgesLoadHistoryFileName; + + public String serviceFileName; + + public String serviceFilePath; + + + public Statistics(Map statistics) { + this.resultFilePath = (String) statistics.get("result_file_path"); + this.resultFileName = (String) statistics.get("result_file_name"); + this.ridesharingFileName = (String) statistics.get("ridesharing_file_name"); + this.ridesharingFilePath = (String) statistics.get("ridesharing_file_path"); + + this.occupanciesFilePath = (String) statistics.get("occupancies_file_path"); + this.occupanciesFileName = (String) statistics.get("occupancies_file_name"); + this.packagesOccupanciesFilePath = (String) statistics.get("packages_occupancies_file_path"); + this.packagesOccupanciesFileName = (String) statistics.get("packages_occupancies_file_name"); + this.combinedOccupanciesFilePath = (String) statistics.get("combined_occupancies_file_path"); + this.combinedOccupanciesFileName = (String) statistics.get("combined_occupancies_file_name"); + +// this.noPeopleOccupanciesFileName = (String) statistics.get("no_people_occupancies_file_name"); +// this.noPeopleOccupanciesFilePath = (String) statistics.get("no_people_occupancies_file_path"); +// this.peopleOnboardOccupanciesFileName = (String) statistics.get("people_onboard_occupancies_file_name"); +// this.peopleOnboardOccupanciesFilePath = (String) statistics.get("people_onboard_occupancies_file_path"); + + this.statisticIntervalMilis = (Integer) statistics.get("statistic_interval_milis"); + this.groupDataFilePath = (String) statistics.get("group_data_file_path"); + this.transitStatisticFilePath = (String) statistics.get("transit_statistic_file_path"); + this.allEdgesLoadHistoryFilePath = (String) statistics.get("all_edges_load_history_file_path"); + this.onDemandVehicleStatistic = new OnDemandVehicleStatistic((Map) statistics.get("on_demand_vehicle_statistic")); + this.allEdgesLoadIntervalMilis = (Integer) statistics.get("all_edges_load_interval_milis"); + this.tripDistancesFilePath = (String) statistics.get("trip_distances_file_path"); + this.darpSolverComputationalTimesFilePath = (String) statistics.get("darp_solver_computational_times_file_path"); + this.groupDataFilename = (String) statistics.get("group_data_filename"); + this.allEdgesLoadHistoryFileName = (String) statistics.get("all_edges_load_history_file_name"); + this.serviceFileName = (String) statistics.get("service_file_name"); + this.serviceFilePath = (String) statistics.get("service_file_path"); + } } diff --git a/src/main/java/cz/cvut/fel/aic/simod/entity/DemandAgent.java b/src/main/java/cz/cvut/fel/aic/simod/entity/DemandAgent.java index 3998c4bd..d44d25c1 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/entity/DemandAgent.java +++ b/src/main/java/cz/cvut/fel/aic/simod/entity/DemandAgent.java @@ -26,7 +26,6 @@ import cz.cvut.fel.aic.agentpolis.simmodel.Agent; import cz.cvut.fel.aic.agentpolis.simmodel.agent.TransportEntity; import cz.cvut.fel.aic.agentpolis.simmodel.entity.EntityType; -import cz.cvut.fel.aic.agentpolis.simmodel.entity.TransportableEntity; import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode; import cz.cvut.fel.aic.alite.common.event.Event; import cz.cvut.fel.aic.alite.common.event.EventHandler; @@ -34,66 +33,67 @@ import cz.cvut.fel.aic.simod.DemandData; import cz.cvut.fel.aic.simod.DemandSimulationEntityType; import cz.cvut.fel.aic.simod.StationsDispatcher; -import cz.cvut.fel.aic.simod.entity.vehicle.OnDemandVehicle; +import cz.cvut.fel.aic.simod.entity.vehicle.OnDemandVehicleInterface; import cz.cvut.fel.aic.simod.event.OnDemandVehicleStationsCentralEvent; import cz.cvut.fel.aic.simod.io.TimeTrip; +import cz.cvut.fel.aic.simod.ridesharing.peoplefreightsheuristic.TransportableDemandEntity; import cz.cvut.fel.aic.simod.statistics.DemandServiceStatistic; import cz.cvut.fel.aic.simod.statistics.StatisticEvent; import cz.cvut.fel.aic.simod.storage.DemandStorage; + import java.util.logging.Level; import java.util.logging.Logger; + import org.slf4j.LoggerFactory; /** - * * @author F-I-D-O */ -public class DemandAgent extends Agent implements EventHandler, TransportableEntity { - + +public class DemandAgent extends Agent implements EventHandler, TransportableDemandEntity { + private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(DemandAgent.class); - + private final int simpleId; - + private final TimeTrip trip; - + private final StationsDispatcher onDemandVehicleStationsCentral; - + private final EventProcessor eventProcessor; - + private final DemandStorage demandStorage; - + private final StandardTimeProvider timeProvider; - + private final TripsUtil tripsUtil; - + /** * Request announcement time in milliseconds */ private final long demandTime; - - + + private DemandAgentState state; - - private OnDemandVehicle onDemandVehicle; - + + private OnDemandVehicleInterface onDemandVehicleInterface; + private TransportEntity transportEntity; - + private SimulationNode lastFromPosition; - + // private long scheduledPickupDelay; - + private long realPickupTime = 0; - + private long minDemandServiceDuration; - + // only to save compuatational time it|s // private long currentServiceDuration; - + private boolean dropped; - - - + public int getSimpleId() { return simpleId; } @@ -118,13 +118,13 @@ public DemandAgentState getState() { return state; } - public OnDemandVehicle getVehicle() { - return onDemandVehicle; + public OnDemandVehicleInterface getVehicleInterface() { + return onDemandVehicleInterface; } - public OnDemandVehicle getOnDemandVehicle() { - return onDemandVehicle; - } +// public OnDemandVehicle getOnDemandVehicle() { +// return onDemandVehicle; +// } public long getMinDemandServiceDuration() { return minDemandServiceDuration; @@ -137,16 +137,17 @@ public void setDropped(boolean dropped) { public boolean isDropped() { return dropped; } - - - - - + @Inject - public DemandAgent(StationsDispatcher onDemandVehicleStationsCentral, EventProcessor eventProcessor, - DemandStorage demandStorage, StandardTimeProvider timeProvider, TripsUtil tripsUtil, - @Assisted String agentId, @Assisted int id, @Assisted TimeTrip trip) { + public DemandAgent(StationsDispatcher onDemandVehicleStationsCentral, + EventProcessor eventProcessor, + DemandStorage demandStorage, + StandardTimeProvider timeProvider, + TripsUtil tripsUtil, + @Assisted String agentId, + @Assisted int id, + @Assisted TimeTrip trip) { super(agentId, trip.getLocations()[0]); this.simpleId = id; this.trip = trip; @@ -161,13 +162,11 @@ public DemandAgent(StationsDispatcher onDemandVehicleStationsCentral, EventProce computeMinServiceDuration(); } - - @Override public void born() { demandStorage.addEntity(this); - eventProcessor.addEvent(OnDemandVehicleStationsCentralEvent.DEMAND, onDemandVehicleStationsCentral, null, + eventProcessor.addEvent(OnDemandVehicleStationsCentralEvent.DEMAND, onDemandVehicleStationsCentral, null, new DemandData(trip.getLocations(), this)); } @@ -183,41 +182,43 @@ public EventProcessor getEventProcessor() { @Override public void handleEvent(Event event) { - onDemandVehicle = (OnDemandVehicle) event.getContent(); + this.onDemandVehicleInterface = (OnDemandVehicleInterface) event.getContent(); // vehicle = onDemandVehicle.getVehicle(); -// rideAsPassengerActivity.usingVehicleAsPassenger(this.getId(), onDemandVehicle.getVehicleId(), +// rideAsPassengerActivity.usingVehicleAsPassenger(this.getId(), onDemandVehicle.getVehicleId(), // onDemandVehicle.getDemandTrip(this), this); } - + @Override public void tripEnded() { - if(!getPosition().equals(trip.getLastLocation())){ + if (!getPosition().equals(trip.getLastLocation())) { // TODO proc nefunguje getPosition() z Agenta?? try { throw new Exception("Demand not served properly"); - } catch (Exception ex) { + } + catch (Exception ex) { LOGGER.error(null, ex); } } - eventProcessor.addEvent(StatisticEvent.DEMAND_DROPPED_OFF, null, null, - new DemandServiceStatistic(demandTime, realPickupTime, timeProvider.getCurrentSimTime(), - minDemandServiceDuration, getId(), onDemandVehicle.getId())); - + eventProcessor.addEvent(StatisticEvent.DEMAND_DROPPED_OFF, null, null, + new DemandServiceStatistic(demandTime, realPickupTime, timeProvider.getCurrentSimTime(), + minDemandServiceDuration, getId(), onDemandVehicleInterface.getId())); + die(); } - public void tripStarted(OnDemandVehicle vehicle) { - if(state == DemandAgentState.DRIVING){ + public void tripStarted(OnDemandVehicleInterface vehicle) { + if (state == DemandAgentState.DRIVING) { try { throw new Exception(String.format("Demand Agent %s already driving in vehicle %s, it cannot be picked up by" - + "another vehicle %s", this, onDemandVehicle, vehicle)); - } catch (Exception ex) { + + "another vehicle %s", this, onDemandVehicleInterface, vehicle)); + } + catch (Exception ex) { Logger.getLogger(DemandAgent.class.getName()).log(Level.SEVERE, null, ex); } } - else{ + else { state = DemandAgentState.DRIVING; realPickupTime = timeProvider.getCurrentSimTime(); - this.onDemandVehicle = vehicle; + this.onDemandVehicleInterface = vehicle; } } @@ -246,11 +247,9 @@ private void computeMinServiceDuration() { minDemandServiceDuration = tripsUtil.getTripDuration(minTrip); } - - - + public interface DemandAgentFactory { public DemandAgent create(String agentId, int id, TimeTrip osmNodeTrip); } - + } diff --git a/src/main/java/cz/cvut/fel/aic/simod/entity/DemandEntityType.java b/src/main/java/cz/cvut/fel/aic/simod/entity/DemandEntityType.java new file mode 100644 index 00000000..e6a86a20 --- /dev/null +++ b/src/main/java/cz/cvut/fel/aic/simod/entity/DemandEntityType.java @@ -0,0 +1,6 @@ +package cz.cvut.fel.aic.simod.entity; + +public enum DemandEntityType { + AGENT, + PACKAGE +} diff --git a/src/main/java/cz/cvut/fel/aic/simod/entity/OnDemandVehicleStation.java b/src/main/java/cz/cvut/fel/aic/simod/entity/OnDemandVehicleStation.java index e25fd5e3..d00baf13 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/entity/OnDemandVehicleStation.java +++ b/src/main/java/cz/cvut/fel/aic/simod/entity/OnDemandVehicleStation.java @@ -34,6 +34,7 @@ import cz.cvut.fel.aic.simod.config.SimodConfig; import cz.cvut.fel.aic.simod.entity.vehicle.OnDemandVehicle; import cz.cvut.fel.aic.simod.entity.vehicle.OnDemandVehicleFactorySpec; +import cz.cvut.fel.aic.simod.ridesharing.peoplefreightsheuristic.PeopleFreightVehicleFactorySpec; import cz.cvut.fel.aic.simod.storage.OnDemandVehicleStorage; import cz.cvut.fel.aic.simod.storage.OnDemandvehicleStationStorage; import cz.cvut.fel.aic.geographtools.GPSLocation; @@ -46,6 +47,7 @@ import java.util.Iterator; import java.util.LinkedList; import java.util.List; + import org.locationtech.jts.geom.Coordinate; import org.slf4j.LoggerFactory; @@ -84,13 +86,29 @@ public OnDemandVehicleStation(SimodConfig config, EventProcessor eventProcessor, this.eventProcessor = eventProcessor; parkedVehicles = new ArrayList<>(); // initialVehicleCount = 10; - for (int i = 0; i < initialVehicleCount; i++) { - String onDemandVehicelId = String.format("%s-%d", id, i); - OnDemandVehicle newVehicle = onDemandVehicleFactory.create(onDemandVehicelId, getPosition()); - parkedVehicles.add(newVehicle); - newVehicle.setParkedIn(this); - onDemandVehicleStorage.addEntity(newVehicle); + + + if (config.packagesOn) { + int vehiclePackagesCapacity = config.packagesCapacity; + PeopleFreightVehicleFactorySpec PFVehicleFactory = (PeopleFreightVehicleFactorySpec) onDemandVehicleFactory; + for (int i = 0; i < initialVehicleCount; i++) { + String onDemandVehicleId = String.format("%s-%d", id, i); + OnDemandVehicle newVehicle = PFVehicleFactory.create(onDemandVehicleId, getPosition(), vehiclePackagesCapacity); + parkedVehicles.add(newVehicle); + newVehicle.setParkedIn(this); + onDemandVehicleStorage.addEntity(newVehicle); + } } + else { + for (int i = 0; i < initialVehicleCount; i++) { + String onDemandVehicleId = String.format("%s-%d", id, i); + OnDemandVehicle newVehicle = onDemandVehicleFactory.create(onDemandVehicleId, getPosition()); + parkedVehicles.add(newVehicle); + newVehicle.setParkedIn(this); + onDemandVehicleStorage.addEntity(newVehicle); + } + } + onDemandVehicleStationStorage.addEntity(this); this.departureCards = new LinkedList<>(); this.transformer = transformer; diff --git a/src/main/java/cz/cvut/fel/aic/simod/entity/vehicle/OnDemandVehicle.java b/src/main/java/cz/cvut/fel/aic/simod/entity/vehicle/OnDemandVehicle.java index 4b5d7c1b..30bafba0 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/entity/vehicle/OnDemandVehicle.java +++ b/src/main/java/cz/cvut/fel/aic/simod/entity/vehicle/OnDemandVehicle.java @@ -32,7 +32,9 @@ import cz.cvut.fel.aic.agentpolis.simmodel.agent.DelayData; import cz.cvut.fel.aic.agentpolis.simmodel.agent.Driver; import cz.cvut.fel.aic.agentpolis.simmodel.entity.EntityType; +import cz.cvut.fel.aic.agentpolis.simmodel.entity.TransportableEntity; import cz.cvut.fel.aic.agentpolis.simmodel.entity.vehicle.PhysicalTransportVehicle; +import cz.cvut.fel.aic.agentpolis.simmodel.entity.vehicle.PhysicalVehicle; import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.EGraphType; import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode; import cz.cvut.fel.aic.agentpolis.simulator.visualization.visio.VisioPositionUtil; @@ -61,12 +63,11 @@ * * @author fido */ -public class OnDemandVehicle extends Agent implements EventHandler, PlanningAgent, +public class OnDemandVehicle extends Agent implements EventHandler, PlanningAgent, OnDemandVehicleInterface, Driver{ private static final int LENGTH = 4; - - + private final int index; protected PhysicalTransportVehicle vehicle; @@ -122,8 +123,17 @@ public class OnDemandVehicle extends Agent implements EventHandler, PlanningAgen protected OnDemandVehicleStation parkedIn; - - + + + @Override + public String toString() { + return "Agent " + getType().toString() + " " + getId(); + } + + @Override + public String getId() { + return super.getId(); + } public int getIndex() { return index; @@ -176,7 +186,7 @@ public void setParkedIn(OnDemandVehicleStation parkedIn) { @Inject public OnDemandVehicle( - PhysicalTransportVehicleStorage vehicleStorage, + PhysicalTransportVehicleStorage vehicleStorage, TripsUtil tripsUtil, StationsDispatcher onDemandVehicleStationsCentral, PhysicalVehicleDriveFactory driveFactory, @@ -187,7 +197,10 @@ public OnDemandVehicle( SimodConfig config, IdGenerator idGenerator, AgentpolisConfig agentpolisConfig, - @Assisted String vehicleId, @Assisted SimulationNode startPosition) { + @Assisted String vehicleId, + @Assisted SimulationNode startPosition, + @Assisted PhysicalTransportVehicle physVehicle) + { super(vehicleId, startPosition); this.tripsUtil = tripsUtil; this.onDemandVehicleStationsCentral = onDemandVehicleStationsCentral; @@ -197,29 +210,38 @@ public OnDemandVehicle( this.timeProvider = timeProvider; this.rebalancingIdGenerator = rebalancingIdGenerator; this.config = config; - + vehicleStorage.addEntity(physVehicle); + + physVehicle.setDriver(this); + index = idGenerator.getId(); - - vehicle = new PhysicalTransportVehicle(vehicleId + " - vehicle", - DemandSimulationEntityType.VEHICLE, LENGTH, config.ridesharing.vehicleCapacity, - EGraphType.HIGHWAY, startPosition, - agentpolisConfig.maxVehicleSpeedInMeters); - - vehicleStorage.addEntity(vehicle); - vehicle.setDriver(this); + state = OnDemandVehicleState.WAITING; - + // set the physical vehicle + try + { + this.vehicle = physVehicle; + } + catch (Exception e) + { + System.out.println(e.toString()); + } + vehicle.setDriver(this); + metersWithPassenger = 0; metersToStartLocation = 0; metersToStation = 0; metersRebalancing = 0; } + + + @Override public EventProcessor getEventProcessor() { return null; } - + public String getVehicleId(){ return vehicle.getId(); } @@ -228,15 +250,15 @@ public String getVehicleId(){ public void handleEvent(Event event) { currentlyServedDemmand = (DemandData) event.getContent(); SimulationNode[] locations = currentlyServedDemmand.locations; - + demandNodes = new ArrayList<>(); demandNodes.add(locations[0]); demandNodes.add(locations[locations.length - 1]); - + leavingStationEvent(); driveToDemandStartLocation(); } - + public void finishedDriving(boolean wasStopped) { switch(state){ case DRIVING_TO_START_LOCATION: diff --git a/src/main/java/cz/cvut/fel/aic/simod/entity/vehicle/OnDemandVehicleFactory.java b/src/main/java/cz/cvut/fel/aic/simod/entity/vehicle/OnDemandVehicleFactory.java index 03d31815..1aff2c73 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/entity/vehicle/OnDemandVehicleFactory.java +++ b/src/main/java/cz/cvut/fel/aic/simod/entity/vehicle/OnDemandVehicleFactory.java @@ -25,9 +25,12 @@ import cz.cvut.fel.aic.agentpolis.siminfrastructure.time.StandardTimeProvider; import cz.cvut.fel.aic.agentpolis.simmodel.IdGenerator; import cz.cvut.fel.aic.agentpolis.simmodel.activity.activityFactory.PhysicalVehicleDriveFactory; +import cz.cvut.fel.aic.agentpolis.simmodel.entity.vehicle.PhysicalTransportVehicle; +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.EGraphType; import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode; import cz.cvut.fel.aic.agentpolis.simulator.visualization.visio.VisioPositionUtil; import cz.cvut.fel.aic.alite.common.event.EventProcessor; +import cz.cvut.fel.aic.simod.DemandSimulationEntityType; import cz.cvut.fel.aic.simod.StationsDispatcher; import cz.cvut.fel.aic.simod.config.SimodConfig; import cz.cvut.fel.aic.simod.storage.PhysicalTransportVehicleStorage; @@ -62,7 +65,7 @@ public class OnDemandVehicleFactory implements OnDemandVehicleFactorySpec{ protected final AgentpolisConfig agentpolisConfig; - + private static final int LENGTH = 4; @Inject @@ -92,7 +95,8 @@ public OnDemandVehicleFactory( @Override - public OnDemandVehicle create(String vehicleId, SimulationNode startPosition){ + public OnDemandVehicle create(String vehicleId, SimulationNode startPosition) { + return new OnDemandVehicle( vehicleStorage, tripsUtil, @@ -106,6 +110,14 @@ public OnDemandVehicle create(String vehicleId, SimulationNode startPosition){ idGenerator, agentpolisConfig, vehicleId, - startPosition); + startPosition, + new PhysicalTransportVehicle( + vehicleId, + DemandSimulationEntityType.VEHICLE, + LENGTH, + config.ridesharing.vehicleCapacity, + EGraphType.HIGHWAY, + startPosition, + agentpolisConfig.maxVehicleSpeedInMeters)); } } diff --git a/src/main/java/cz/cvut/fel/aic/simod/entity/vehicle/OnDemandVehicleInterface.java b/src/main/java/cz/cvut/fel/aic/simod/entity/vehicle/OnDemandVehicleInterface.java new file mode 100644 index 00000000..6d23cd3a --- /dev/null +++ b/src/main/java/cz/cvut/fel/aic/simod/entity/vehicle/OnDemandVehicleInterface.java @@ -0,0 +1,7 @@ +package cz.cvut.fel.aic.simod.entity.vehicle; + +public interface OnDemandVehicleInterface { + public String getId(); + + public String toString(); +} diff --git a/src/main/java/cz/cvut/fel/aic/simod/experiment/SetBenchmark.java b/src/main/java/cz/cvut/fel/aic/simod/experiment/SetBenchmark.java index c3d924ee..66069b4e 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/experiment/SetBenchmark.java +++ b/src/main/java/cz/cvut/fel/aic/simod/experiment/SetBenchmark.java @@ -24,6 +24,8 @@ import cz.cvut.fel.aic.simod.ridesharing.model.PlanActionDropoff; import cz.cvut.fel.aic.simod.ridesharing.model.PlanActionPickup; import cz.cvut.fel.aic.simod.ridesharing.model.PlanComputationRequest; +import cz.cvut.fel.aic.simod.ridesharing.peoplefreightsheuristic.TransportableDemandEntity; + import java.math.BigInteger; import java.util.HashSet; import java.util.Objects; @@ -300,7 +302,7 @@ public PlanActionDropoff getDropOffAction() { } @Override - public DemandAgent getDemandAgent() { + public TransportableDemandEntity getDemandEntity() { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } diff --git a/src/main/java/cz/cvut/fel/aic/simod/init/EventInitializer.java b/src/main/java/cz/cvut/fel/aic/simod/init/EventInitializer.java index 4029b5e6..813547e3 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/init/EventInitializer.java +++ b/src/main/java/cz/cvut/fel/aic/simod/init/EventInitializer.java @@ -35,12 +35,15 @@ import cz.cvut.fel.aic.simod.entity.OnDemandVehicleStation; import cz.cvut.fel.aic.simod.event.OnDemandVehicleStationsCentralEvent; import cz.cvut.fel.aic.simod.io.TimeTrip; + import java.util.List; import java.util.Random; + +import cz.cvut.fel.aic.simod.ridesharing.peoplefreightsheuristic.DemandPackageEventHandler; +import cz.cvut.fel.aic.simod.ridesharing.peoplefreightsheuristic.PackageContent; import org.slf4j.LoggerFactory; /** - * * @author fido */ @Singleton @@ -49,125 +52,150 @@ public class EventInitializer { // private static final double TRIP_MULTIPLICATION_FACTOR = 13.63; // private static final double TRIP_MULTIPLICATION_FACTOR = 1.615; // private static final double TRIP_MULTIPLICATION_FACTOR = 3.433; - + private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(EventInitializer.class); - + private static final long TRIP_MULTIPLICATION_TIME_SHIFT = 240_000; - + private static final long MAX_EVENTS = 0; - + private static final int RANDOM_SEED = 1; - - - - + + private final EventProcessor eventProcessor; private final DemandEventHandler demandEventHandler; - + + private final DemandPackageEventHandler packageEventHandler; + private final StationsDispatcher onDemandVehicleStationsCentral; - - private final SimodConfig SimodConfig; - + + private final SimodConfig simodConfig; + private final AgentpolisConfig agentpolisConfig; - + private final SimulationUtils simulationUtils; - + private long eventCount; - + private long impossibleTripsCount; - - + + @Inject - public EventInitializer(EventProcessor eventProcessor, - StationsDispatcher onDemandVehicleStationsCentral, SimodConfig config, - DemandEventHandler demandEventHandler, AgentpolisConfig agentpolisConfig, SimulationUtils simulationUtils) { + public EventInitializer(EventProcessor eventProcessor, + StationsDispatcher onDemandVehicleStationsCentral, SimodConfig config, + DemandEventHandler demandEventHandler, AgentpolisConfig agentpolisConfig, SimulationUtils simulationUtils, DemandPackageEventHandler packageEventHandler) { this.eventProcessor = eventProcessor; this.demandEventHandler = demandEventHandler; + this.packageEventHandler = packageEventHandler; this.onDemandVehicleStationsCentral = onDemandVehicleStationsCentral; - this.SimodConfig = config; + this.simodConfig = config; this.agentpolisConfig = agentpolisConfig; this.simulationUtils = simulationUtils; eventCount = 0; impossibleTripsCount = 0; } - - - public void initialize(List> trips, List> rebalancingTrips){ + + // PackageContent contains the trip and weight + public void initializePackages(List contents, List> rebalancingTrips) { Random random = new Random(RANDOM_SEED); - + + for (PackageContent packageContent : contents) { + TimeTrip trip = packageContent.trip; + long startTime = trip.getStartTime() - simodConfig.startTime; + // trip has to start at least 1ms after start of the simulation and no later then last + if (startTime < 1 || startTime > simulationUtils.computeSimulationDuration()) { + impossibleTripsCount++; +// LOGGER.info("Trip out of simulation time. Total: {}", impossibleTripsCount); + continue; + } + + for (int i = 0; i < simodConfig.tripsMultiplier; i++) { + if (i + 1 >= simodConfig.tripsMultiplier) { + double randomNum = random.nextDouble(); + if (randomNum > simodConfig.tripsMultiplier - i) { + break; + } + } + + startTime = startTime + i * TRIP_MULTIPLICATION_TIME_SHIFT; + eventProcessor.addEvent(null, packageEventHandler, null, packageContent, startTime); // demand package handler + eventCount++; + if (MAX_EVENTS != 0 && eventCount >= MAX_EVENTS) { + return; + } + } + } + } + + public void initialize(List> trips, List> rebalancingTrips) { + Random random = new Random(RANDOM_SEED); + for (TimeTrip trip : trips) { - long startTime = trip.getStartTime() - SimodConfig.startTime; + long startTime = trip.getStartTime() - simodConfig.startTime; // trip have to start at least 1ms after start of the simulation and no later then last - if(startTime < 1 || startTime > simulationUtils.computeSimulationDuration()){ + if (startTime < 1 || startTime > simulationUtils.computeSimulationDuration()) { impossibleTripsCount++; // LOGGER.info("Trip out of simulation time. Total: {}", impossibleTripsCount); continue; } - - for(int i = 0; i < SimodConfig.tripsMultiplier; i++){ - if(i + 1 >= SimodConfig.tripsMultiplier){ + + for (int i = 0; i < simodConfig.tripsMultiplier; i++) { + if (i + 1 >= simodConfig.tripsMultiplier) { double randomNum = random.nextDouble(); - if(randomNum > SimodConfig.tripsMultiplier - i){ + if (randomNum > simodConfig.tripsMultiplier - i) { break; } } - + startTime = startTime + i * TRIP_MULTIPLICATION_TIME_SHIFT; eventProcessor.addEvent(null, demandEventHandler, null, trip, startTime); eventCount++; - if(MAX_EVENTS != 0 && eventCount >= MAX_EVENTS){ + if (MAX_EVENTS != 0 && eventCount >= MAX_EVENTS) { return; } } } - if(rebalancingTrips != null){ + if (rebalancingTrips != null) { for (TimeTrip rebalancingTrip : rebalancingTrips) { - long startTime = rebalancingTrip.getStartTime() - SimodConfig.startTime; - if(startTime < 1 || startTime > simulationUtils.computeSimulationDuration()){ - impossibleTripsCount++; - continue; - } - eventProcessor.addEvent(OnDemandVehicleStationsCentralEvent.REBALANCING, onDemandVehicleStationsCentral, + long startTime = rebalancingTrip.getStartTime() - simodConfig.startTime; + if (startTime < 1 || startTime > simulationUtils.computeSimulationDuration()) { + impossibleTripsCount++; + continue; + } + eventProcessor.addEvent(OnDemandVehicleStationsCentralEvent.REBALANCING, onDemandVehicleStationsCentral, null, rebalancingTrip, startTime); } } - + LOGGER.info("{} trips discarded because they are not within simulation time bounds", impossibleTripsCount); } - - - - - public static class DemandEventHandler extends EventHandlerAdapter{ - + + + public static class DemandEventHandler extends EventHandlerAdapter { + private final IdGenerator demandIdGenerator; - + private final DemandAgentFactory demandAgentFactory; - - - - + + @Inject public DemandEventHandler(IdGenerator demandIdGenerator, DemandAgentFactory demandAgentFactory, - SimulationCreator simulationCreator) { + SimulationCreator simulationCreator) { this.demandIdGenerator = demandIdGenerator; this.demandAgentFactory = demandAgentFactory; } - - - @Override public void handleEvent(Event event) { TimeTrip trip = (TimeTrip) event.getContent(); - + int id = demandIdGenerator.getId(); - - DemandAgent demandAgent = demandAgentFactory.create("Demand " + Integer.toString(id), id, trip); - + + DemandAgent demandAgent = demandAgentFactory.create("Agent " + Integer.toString(id), id, trip); + demandAgent.born(); } - } + } } diff --git a/src/main/java/cz/cvut/fel/aic/simod/init/StationsInitializer.java b/src/main/java/cz/cvut/fel/aic/simod/init/StationsInitializer.java index 6f43e17d..bd07475b 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/init/StationsInitializer.java +++ b/src/main/java/cz/cvut/fel/aic/simod/init/StationsInitializer.java @@ -27,6 +27,7 @@ import cz.cvut.fel.aic.simod.entity.OnDemandVehicleStation; import cz.cvut.fel.aic.simod.entity.OnDemandVehicleStation.OnDemandVehicleStationFactory; import cz.cvut.fel.aic.simod.traveltimecomputation.DistanceMatrixTravelTimeProvider; + import java.io.BufferedReader; import java.io.FileInputStream; import java.io.FileNotFoundException; @@ -38,23 +39,21 @@ import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; + import org.slf4j.LoggerFactory; /** - * * @author david */ public class StationsInitializer { private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(DistanceMatrixTravelTimeProvider.class); - + private final OnDemandVehicleStation.OnDemandVehicleStationFactory onDemandVehicleStationFactory; - + private final NodesMappedByIndex nodesMappedByIndex; - + private final SimodConfig config; - - - + @Inject public StationsInitializer(OnDemandVehicleStationFactory onDemandVehicleStationFactory, NodesMappedByIndex nodesMappedByIndex, SimodConfig config) { @@ -62,40 +61,46 @@ public StationsInitializer(OnDemandVehicleStationFactory onDemandVehicleStationF this.nodesMappedByIndex = nodesMappedByIndex; this.config = config; } - - - public void loadStations(){ + + + public void loadStations() { List stationRows = loadStationRows(config.stationPositionFilepath); LOGGER.info("{} Stations indexes loaded from {}", stationRows.size(), config.stationPositionFilepath); - + int counter = 0; int discarded = 0; - for(String[] row: stationRows){ + int i = 0; // temp for-cycle iteration variable + for (String[] row : stationRows) { int index = Integer.parseInt(row[0]); SimulationNode node = nodesMappedByIndex.getNodeByIndex(index); - if(node == null){ + + + if (node == null) { LOGGER.info("Station at node with index {} discarded as it is not in the Agentpolis road graph", index); discarded++; } - else{ - int initCount = Integer.parseInt(row[1]) + 100; - if(initCount < 500){ - initCount += 100; - } + + else { +// int initCount = Integer.parseInt(row[1]) + 100; // TODO: odkomentovat puvodni kod +// if (initCount < 500) { +// initCount += 100; +// } + int initCount = config.vehiclesPerStation; createStation(node, initCount, counter++); } + } LOGGER.info("{} Stations Discarded", discarded); } - - private List loadStationRows(String filepath){ + + private List loadStationRows(String filepath) { LOGGER.info("Loading station positions from: {}", filepath); - + try { Reader reader - = new BufferedReader(new InputStreamReader(new FileInputStream(filepath), "utf-8")); + = new BufferedReader(new InputStreamReader(new FileInputStream(filepath), "utf-8")); CsvParserSettings settings = new CsvParserSettings(); - + settings.getFormat().setLineSeparator("\r\n"); //turning off features enabled by default @@ -103,13 +108,13 @@ private List loadStationRows(String filepath){ settings.setIgnoreTrailingWhitespaces(false); settings.setSkipEmptyLines(false); settings.setColumnReorderingEnabled(false); - + CsvParser parser = new CsvParser(settings); - + Iterator it = parser.iterate(reader).iterator(); - + String[] row; - + // first row processing List stationRows = new ArrayList<>(); while (it.hasNext()) { @@ -118,14 +123,14 @@ private List loadStationRows(String filepath){ } parser.stopParsing(); return stationRows; - } + } catch (FileNotFoundException | UnsupportedEncodingException ex) { Logger.getLogger(DistanceMatrixTravelTimeProvider.class.getName()).log(Level.SEVERE, null, ex); return null; } } - - private void createStation(SimulationNode position, int vehicleCount, int id){ + + private void createStation(SimulationNode position, int vehicleCount, int id) { onDemandVehicleStationFactory.create(Integer.toString(id), position, vehicleCount); } } diff --git a/src/main/java/cz/cvut/fel/aic/simod/io/TripTransform.java b/src/main/java/cz/cvut/fel/aic/simod/io/TripTransform.java index 19b24430..e0f07a4b 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/io/TripTransform.java +++ b/src/main/java/cz/cvut/fel/aic/simod/io/TripTransform.java @@ -31,6 +31,7 @@ import cz.cvut.fel.aic.geographtools.GPSLocation; import cz.cvut.fel.aic.geographtools.Graph; import cz.cvut.fel.aic.geographtools.WKTPrintableCoord; + import java.io.BufferedReader; import java.io.File; import java.io.FileReader; @@ -38,48 +39,45 @@ import java.util.ArrayList; import java.util.LinkedList; import java.util.List; + +import cz.cvut.fel.aic.simod.ridesharing.peoplefreightsheuristic.PackageContent; import me.tongfei.progressbar.ProgressBar; import org.slf4j.LoggerFactory; /** - * * @author F-I-D-O */ @Singleton public class TripTransform { - + private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(TripTransform.class); - + // private PathPlanner pathPlanner; - + private int zeroLenghtTripsCount = 0; - + private int sameStartAndTargetInDataCount = 0; - - private final Graph highwayGraph; - + + private final Graph highwayGraph; + private final NearestElementUtils nearestElementUtils; - + private IdGenerator tripIdGenerator; - + @Inject - public TripTransform(HighwayNetwork highwayNetwork, NearestElementUtils nearestElementUtils,IdGenerator tripIdGenerator) { + public TripTransform(HighwayNetwork highwayNetwork, NearestElementUtils nearestElementUtils, IdGenerator tripIdGenerator) { this.highwayGraph = highwayNetwork.getNetwork(); this.nearestElementUtils = nearestElementUtils; this.tripIdGenerator = tripIdGenerator; } - - - - - - + + // public List> gpsTripsToOsmNodeTrips(List> gpsTrips, // File osmFile, int srid){ // return gpsTripsToOsmNodeTrips(gpsTrips, osmFile, srid, true); // } - + // public List> gpsTripsToOsmNodeTrips(List> gpsTrips, // File osmFile, int srid, boolean completedTrips){ // Graph highwayGraph = OsmUtil.getHigwayGraph(osmFile,srid); @@ -107,74 +105,122 @@ public TripTransform(HighwayNetwork highwayNetwork, NearestElementUtils nearestE // // return osmNodeTrips; // } - - public static void tripsToJson(List> trips, File outputFile) throws IOException{ + + public static void tripsToJson(List> trips, File outputFile) throws IOException { ObjectMapper mapper = new ObjectMapper(); - + mapper.writeValue(outputFile, trips); } - - public static List> jsonToTrips(File inputFile, Class locationType) throws IOException{ + + public static List> jsonToTrips(File inputFile, Class locationType) throws IOException { ObjectMapper mapper = new ObjectMapper(); TypeFactory typeFactory = mapper.getTypeFactory(); - + return mapper.readValue(inputFile, typeFactory.constructCollectionType( List.class, typeFactory.constructParametricType(TimeTrip.class, locationType))); } - - public List> loadTripsFromTxt(File inputFile){ + + public List> loadTripsFromTxt(File inputFile) { + List> gpsTrips = new LinkedList<>(); + LOGGER.info("Loading trips from: {}", inputFile); + try (BufferedReader br = new BufferedReader(new FileReader(inputFile))) { + String line; + while ((line = br.readLine()) != null) { + + String[] parts = line.split(" "); + GPSLocation startLocation + = new GPSLocation(Double.parseDouble(parts[1]), Double.parseDouble(parts[2]), 0, 0); + GPSLocation targetLocation + = new GPSLocation(Double.parseDouble(parts[3]), Double.parseDouble(parts[4]), 0, 0); + + if (startLocation.equals(targetLocation)) { + sameStartAndTargetInDataCount++; + } + else { + gpsTrips.add( + new TimeTrip<>(tripIdGenerator.getId(), Long.parseLong(parts[0].split("\\.")[0]), startLocation, targetLocation)); + } + } + } + catch (IOException ex) { + LOGGER.error(null, ex); + } + + List> trips = new ArrayList<>(); + + for (TimeTrip trip : ProgressBar.wrap(gpsTrips, "Process GPS trip: ")) { + processGpsTrip(trip, trips); + } + + LOGGER.info("Number of trips with same source and destination: {}", sameStartAndTargetInDataCount); + LOGGER.info("{} trips with zero lenght discarded", zeroLenghtTripsCount); + + return trips; + } + + public List loadPackagesFromTxt(File inputFile) { List> gpsTrips = new LinkedList<>(); + List weights = new ArrayList<>(); LOGGER.info("Loading trips from: {}", inputFile); try (BufferedReader br = new BufferedReader(new FileReader(inputFile))) { String line; while ((line = br.readLine()) != null) { - String[] parts = line.split(" "); - GPSLocation startLocation - = new GPSLocation(Double.parseDouble(parts[1]), Double.parseDouble(parts[2]), 0, 0); - GPSLocation targetLocation - = new GPSLocation(Double.parseDouble(parts[3]), Double.parseDouble(parts[4]), 0, 0); - - if(startLocation.equals(targetLocation)){ - sameStartAndTargetInDataCount++; - } - else{ + + String[] parts = line.split(" "); + GPSLocation startLocation + = new GPSLocation(Double.parseDouble(parts[1]), Double.parseDouble(parts[2]), 0, 0); + GPSLocation targetLocation + = new GPSLocation(Double.parseDouble(parts[3]), Double.parseDouble(parts[4]), 0, 0); + + if (startLocation.equals(targetLocation)) { + sameStartAndTargetInDataCount++; + } + else { gpsTrips.add( - new TimeTrip<>(tripIdGenerator.getId(),Long.parseLong(parts[0].split("\\.")[0]), startLocation, targetLocation)); - } + new TimeTrip<>(tripIdGenerator.getId(), Long.parseLong(parts[0].split("\\.")[0]), startLocation, targetLocation)); + weights.add(Integer.parseInt(parts[6])); // parsing package weight + } } - } catch (IOException ex) { + } + catch (IOException ex) { LOGGER.error(null, ex); } - + List> trips = new ArrayList<>(); for (TimeTrip trip : ProgressBar.wrap(gpsTrips, "Process GPS trip: ")) { processGpsTrip(trip, trips); } - + LOGGER.info("Number of trips with same source and destination: {}", sameStartAndTargetInDataCount); LOGGER.info("{} trips with zero lenght discarded", zeroLenghtTripsCount); - - return trips; + + // putting together the trips and weights + List contents = new ArrayList<>(); + for (int i = 0; i < trips.size(); i++) { + contents.add(new PackageContent(trips.get(i), weights.get(i))); + } + + return contents; } - - private void processGpsTrip(TimeTrip gpsTrip, List>trips) { + + private void processGpsTrip(TimeTrip gpsTrip, List> trips) { GPSLocation[] locations = gpsTrip.getLocations(); SimulationNode startNode = nearestElementUtils.getNearestElement(locations[0], EGraphType.HIGHWAY); - SimulationNode targetNode + SimulationNode targetNode = nearestElementUtils.getNearestElement(locations[locations.length - 1], EGraphType.HIGHWAY); - - if(startNode != targetNode){ + + if (startNode != targetNode) { SimulationNode[] nodesList = new SimulationNode[2]; nodesList[0] = startNode; nodesList[1] = targetNode; - trips.add(new TimeTrip<>(tripIdGenerator.getId(),gpsTrip.getStartTime(), gpsTrip.getEndTime(), nodesList)); - } - else{ + trips.add(new TimeTrip<>(tripIdGenerator.getId(), gpsTrip.getStartTime(), gpsTrip.getEndTime(), nodesList)); + } + else { zeroLenghtTripsCount++; } } - + // public void tripsFromTxtToJson(File inputFile, File osmFile, int srid, File outputFile) throws IOException{ // List> gpsTrips = new LinkedList<>(); // try (BufferedReader br = new BufferedReader(new FileReader(inputFile))) { @@ -232,5 +278,5 @@ private void processGpsTrip(TimeTrip gpsTrip, List plan = new LinkedList<>(); plan.add(new PlanActionCurrentPosition(getPosition())); currentPlan = new DriverPlan(plan, 0, 0); } - @Override - public void handleEvent(Event event) { - - } - - public int getOnBoardCount(){ + +// @Override +// public void handleEvent(Event event) { +// +// } + + public int getOnBoardCount() { return vehicle.getTransportedEntities().size(); } - - public int getFreeCapacity(){ + + public int getFreeCapacity() { return vehicle.getCapacity() - vehicle.getTransportedEntities().size(); } - - public void replan(DriverPlan plan){ + + public void replan(DriverPlan plan) { currentPlan = plan; // The vehicle now waits, we have to start moving. - if(state == OnDemandVehicleState.WAITING && plan.getLength() > 1){ + if (state == OnDemandVehicleState.WAITING && plan.getLength() > 1) { driveToNextTask(); } // SPECIAL CASES - we don't have to do anything and let the current Drive action continue. - - else if( - // The first action in the new plan is the same as the current action - (plan.getLength() > 1 && currentTask != null && currentTask.equals(plan.getNextTask())) - // The new plan is empty and the vehicle is waiting or driving to station - || (plan.getLength() == 1 && (state == OnDemandVehicleState.WAITING || state == OnDemandVehicleState.DRIVING_TO_STATION))){ + + else if ( + // The first action in the new plan is the same as the current action + (plan.getLength() > 1 && currentTask != null && currentTask.equals(plan.getNextTask())) + // The new plan is empty and the vehicle is waiting or driving to station + || (plan.getLength() == 1 && (state == OnDemandVehicleState.WAITING || state == OnDemandVehicleState.DRIVING_TO_STATION))) { } // We end the current Drive action and start the execution of the new plan. - else{ + else { ((PhysicalVehicleDrive) getCurrentTopLevelActivity()).end(); } - } @Override protected void driveToDemandStartLocation() { // safety check that prevents request from being picked up twice because of the delayed pickup event - if(((PlanActionPickup) currentTask).request.isOnboard()){ + if (((PlanActionPickup) currentTask).request.isOnboard()) { currentPlan.taskCompleted(); driveToNextTask(); } state = OnDemandVehicleState.DRIVING_TO_START_LOCATION; - if(getPosition().id == currentTask.getPosition().id){ + if (getPosition().id == currentTask.getPosition().id) { pickupAndContinue(); } - else{ + else { currentTrip = tripsUtil.createTrip(getPosition(), currentTask.getPosition(), vehicle); - DemandAgent demandAgent = ((PlanActionPickup) currentTask).getRequest().getDemandAgent(); +// DemandAgent demandAgent = ((PlanActionPickup) currentTask).getRequest().getDemandAgent(); driveFactory.runActivity(this, vehicle, currentTrip); } } @@ -169,10 +175,10 @@ protected void driveToDemandStartLocation() { @Override protected void driveToTargetLocation() { state = OnDemandVehicleState.DRIVING_TO_TARGET_LOCATION; - if(getPosition().id == currentTask.getPosition().id){ + if (getPosition().id == currentTask.getPosition().id) { dropOffAndContinue(); } - else{ + else { currentTrip = tripsUtil.createTrip(getPosition(), currentTask.getPosition(), vehicle); driveFactory.runActivity(this, vehicle, currentTrip); } @@ -182,11 +188,11 @@ protected void driveToTargetLocation() { protected void driveToNearestStation() { state = OnDemandVehicleState.DRIVING_TO_STATION; targetStation = onDemandVehicleStationsCentral.getNearestStation(getPosition()); - - if(getPosition().equals(targetStation.getPosition())){ + + if (getPosition().equals(targetStation.getPosition())) { finishDrivingToStation(); } - else{ + else { currentTrip = tripsUtil.createTrip(getPosition(), targetStation.getPosition(), vehicle); driveFactory.runActivity(this, vehicle, currentTrip); } @@ -195,12 +201,12 @@ protected void driveToNearestStation() { @Override public void finishedDriving(boolean wasStopped) { logTraveledDistance(wasStopped); - - if(wasStopped){ + + if (wasStopped) { driveToNextTask(); } - else{ - switch(state){ + else { + switch (state) { case DRIVING_TO_START_LOCATION: pickupAndContinue(); break; @@ -217,82 +223,83 @@ public void finishedDriving(boolean wasStopped) { } } - private void driveToNextTask() { - if(currentPlan.getLength() == 1){ + protected void driveToNextTask() { + if (currentPlan.getLength() == 1) { currentTask = null; - if(state != OnDemandVehicleState.WAITING){ - if(onDemandVehicleStationsCentral.stationsOn()){ + if (state != OnDemandVehicleState.WAITING) { + if (onDemandVehicleStationsCentral.stationsOn()) { driveToNearestStation(); } - else{ + else { park(); } } } - else{ + else { currentTask = currentPlan.getNextTask(); - if(parkedIn != null){ + if (parkedIn != null) { parkedIn.releaseVehicle(this); leavingStationEvent(); } - if(currentTask instanceof PlanActionPickup){ + if (currentTask instanceof PlanActionPickup) { driveToDemandStartLocation(); } - else{ + else { driveToTargetLocation(); } } } - private void pickupAndContinue() { + protected void pickupAndContinue() { try { - DemandAgent demandAgent = ((PlanActionPickup) currentTask).getRequest().getDemandAgent(); - if(demandAgent.isDropped()){ + TransportableDemandEntity demandEntity = ((PlanActionPickup) currentTask).getRequest().getDemandEntity(); + if (demandEntity.isDropped()) { long currentTime = timeProvider.getCurrentSimTime(); - long droppTime = demandAgent.getDemandTime() + config.ridesharing.maxProlongationInSeconds * 1000; + long droppTime = demandEntity.getDemandTime() + config.ridesharing.maxProlongationInSeconds * 1000; throw new Exception( - String.format("Demand agent %s cannot be picked up, he is already dropped! Current simulation " - + "time: %s, dropp time: %s", demandAgent, currentTime, droppTime)); + String.format("Demand agent %s cannot be picked up, he is already dropped! Current simulation " + + "time: %s, drop time: %s", demandEntity, currentTime, droppTime)); } - demandAgent.tripStarted(this); - vehicle.pickUp(demandAgent); + demandEntity.tripStarted(this); + vehicle.pickUp(demandEntity); - // statistics TODO demand tirp? - // demandTrip = tripsUtil.createTrip(currentTask.getDemandAgent().getPosition().id, - // currentTask.getLocation().id, vehicle); + // statistics TODO demand trip? + // demandTrip = tripsUtil.createTrip(currentTask.getDemandAgent().getPosition().id, + // currentTask.getLocation().id, vehicle); // demand trip length 0 - need to find out where the statistic is used, does it make sense with rebalancing? - eventProcessor.addEvent(OnDemandVehicleEvent.PICKUP, null, null, - new PickupEventContent(timeProvider.getCurrentSimTime(), - demandAgent.getSimpleId(), getId(), - (int) Math.round(demandAgent.getMinDemandServiceDuration() / 1000))); + eventProcessor.addEvent(OnDemandVehicleEvent.PICKUP, null, null, + new PickupEventContent(timeProvider.getCurrentSimTime(), + demandEntity.getSimpleId(), getId(), + (int) Math.round(demandEntity.getMinDemandServiceDuration() / 1000))); currentPlan.taskCompleted(); driveToNextTask(); - } catch (Exception ex) { + } + catch (Exception ex) { Logger.getLogger(RideSharingOnDemandVehicle.class.getName()).log(Level.SEVERE, null, ex); } } - private void dropOffAndContinue() { - DemandAgent demandAgent = ((PlanActionDropoff) currentTask).getRequest().getDemandAgent(); - demandAgent.tripEnded(); - vehicle.dropOff(demandAgent); - + protected void dropOffAndContinue() { + TransportableDemandEntity demandEntity = ((PlanActionDropoff) currentTask).getRequest().getDemandEntity(); + demandEntity.tripEnded(); + vehicle.dropOff(demandEntity); + // statistics - eventProcessor.addEvent(OnDemandVehicleEvent.DROP_OFF, null, null, - new OnDemandVehicleEventContent(timeProvider.getCurrentSimTime(), - demandAgent.getSimpleId(), getId())); + eventProcessor.addEvent(OnDemandVehicleEvent.DROP_OFF, null, null, + new OnDemandVehicleEventContent(timeProvider.getCurrentSimTime(), + demandEntity.getSimpleId(), getId())); currentPlan.taskCompleted(); driveToNextTask(); } @Override protected void leavingStationEvent() { - eventProcessor.addEvent(OnDemandVehicleEvent.LEAVE_STATION, null, null, - new OnDemandVehicleEventContent(timeProvider.getCurrentSimTime(), - ((PlanRequestAction) currentTask).getRequest().getDemandAgent().getSimpleId(), getId())); + eventProcessor.addEvent(OnDemandVehicleEvent.LEAVE_STATION, null, null, + new OnDemandVehicleEventContent(timeProvider.getCurrentSimTime(), + ((PlanRequestAction) currentTask).getRequest().getDemandEntity().getSimpleId(), getId())); } - + @Override public VehicleTrip getCurrentTripPlan() { return currentTrip; @@ -301,30 +308,30 @@ public VehicleTrip getCurrentTripPlan() { public boolean hasFreeCapacity() { return getFreeCapacity() > 0; } - - public List getPlanForRendering(){ + + public List getPlanForRendering() { List trips = new ArrayList<>(currentPlan.getLength()); SimulationNode lastPosition = getPosition(); - for(PlanAction action: currentPlan){ - if(action instanceof PlanRequestAction && lastPosition != action.getPosition()){ + for (PlanAction action : currentPlan) { + if (action instanceof PlanRequestAction && lastPosition != action.getPosition()) { VehicleTrip newTrip = tripsUtil.createTrip(lastPosition, action.getPosition(), vehicle); - trips.add(new PlanLayerTrip(tripIdGenerator.getId(),(PlanRequestAction) action, newTrip.getLocations())); + trips.add(new PlanLayerTrip(tripIdGenerator.getId(), (PlanRequestAction) action, newTrip.getLocations())); lastPosition = action.getPosition(); } } return trips; } - private void logTraveledDistance(boolean wasStopped) { + protected void logTraveledDistance(boolean wasStopped) { int length = wasStopped ? positionUtil.getTripLengthInMeters(currentTrip, getPosition()) : positionUtil.getTripLengthInMeters(currentTrip); - - if(getOnBoardCount() > 0){ + + if (getOnBoardCount() > 0) { metersWithPassenger += length; } - else{ - switch(state){ + else { + switch (state) { case DRIVING_TO_START_LOCATION: metersToStartLocation += length; break; @@ -333,7 +340,7 @@ private void logTraveledDistance(boolean wasStopped) { break; } } - + } } diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/RidesharingDispatcher.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/RidesharingDispatcher.java index edf88420..4672a7c2 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/RidesharingDispatcher.java +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/RidesharingDispatcher.java @@ -66,29 +66,29 @@ @Singleton public class RidesharingDispatcher extends StationsDispatcher implements Routine, EventHandler{ - private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(RidesharingDispatcher.class); + protected static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(RidesharingDispatcher.class); - private final TimeProvider timeProvider; + protected final TimeProvider timeProvider; - protected final DefaultPlanComputationRequest.DefaultPlanComputationRequestFactory requestFactory; + private final DefaultPlanComputationRequest.DefaultPlanComputationRequestFactory requestFactory; - private final DARPSolver solver; + protected final DARPSolver solver; - private final List darpSolverComputationalTimes; - - private final LinkedHashSet waitingRequests; - - private final Map requestsMapByDemandAgents; - - private final PositionUtil positionUtil; - - - private List newRequests; - - private int requestCounter; + protected final List darpSolverComputationalTimes; + + protected List newRequests; + + protected final LinkedHashSet waitingRequests; + + protected final Map requestsMapByDemandAgents; + + protected final PositionUtil positionUtil; + + + protected int requestCounter; - private IdGenerator tripIdGenerator; + protected IdGenerator tripIdGenerator; @@ -115,15 +115,17 @@ public RidesharingDispatcher(OnDemandvehicleStationStorage onDemandvehicleStatio this.tripIdGenerator = tripIdGenerator; newRequests = new ArrayList<>(); waitingRequests = new LinkedHashSet<>(); - darpSolverComputationalTimes = new ArrayList(); + darpSolverComputationalTimes = new ArrayList<>(); requestsMapByDemandAgents = new HashMap<>(); requestCounter = 0; if(config.ridesharing.batchPeriod != 0){ ticker.registerRoutine(this, config.ridesharing.batchPeriod * 1000); } - setEventHandeling(); - - solver.setDispatcher(this); + + if (!config.packagesOn) { + setEventHandeling(); + solver.setDispatcher(this); + } } @@ -136,7 +138,7 @@ protected void serveDemand(SimulationNode startNode, DemandData demandData) { demandData.locations[1], demandData.demandAgent); waitingRequests.add(newRequest); newRequests.add(newRequest); - requestsMapByDemandAgents.put(newRequest.getDemandAgent().getSimpleId(), newRequest); + requestsMapByDemandAgents.put(newRequest.getDemandEntity().getSimpleId(), newRequest); if(config.ridesharing.batchPeriod == 0){ replan(); @@ -157,8 +159,8 @@ protected void replan(){ while(waitingRequestIterator.hasNext()){ PlanComputationRequest request = waitingRequestIterator.next(); if(request.getMaxPickupTime() + 5 < currentTimeSec){ - request.getDemandAgent().setDropped(true); - numberOfDemandsDropped++; + request.getDemandEntity().setDropped(true); + numberOfPassangersDropped++; droppedDemandsThisBatch++; waitingRequestIterator.remove(); eventProcessor.addEvent(DemandEvent.LEFT, null, null, request); @@ -166,8 +168,8 @@ protected void replan(){ } } LOGGER.info("Demands dropped in this batch: {}", droppedDemandsThisBatch); - LOGGER.info("Total dropped demands count: {}", numberOfDemandsDropped); - + LOGGER.info("Total dropped demands count: {}", numberOfPassangersDropped); + // DARP solving long startTime = System.nanoTime(); Map newPlans @@ -176,9 +178,9 @@ protected void replan(){ darpSolverComputationalTimes.add(totalTime); // executing new plans - for(Entry entry: newPlans.entrySet()){ + for(Entry entry : newPlans.entrySet()){ RideSharingOnDemandVehicle vehicle = entry.getKey(); - DriverPlan plan = entry.getValue(); + DriverPlan plan = entry.getValue(); vehicle.replan(plan); } @@ -269,7 +271,7 @@ public PlanComputationRequest getRequest(int demandId){ return requestsMapByDemandAgents.get(demandId); } - private void setEventHandeling() { + protected void setEventHandeling() { List typesToHandle = new LinkedList<>(); typesToHandle.add(OnDemandVehicleEvent.PICKUP); eventProcessor.addEventHandler(this, typesToHandle); diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/RidesharingOnDemandVehicleFactory.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/RidesharingOnDemandVehicleFactory.java index a44247de..5f68ac60 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/RidesharingOnDemandVehicleFactory.java +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/RidesharingOnDemandVehicleFactory.java @@ -24,9 +24,12 @@ import cz.cvut.fel.aic.agentpolis.siminfrastructure.planner.TripsUtil; import cz.cvut.fel.aic.agentpolis.siminfrastructure.time.StandardTimeProvider; import cz.cvut.fel.aic.agentpolis.simmodel.IdGenerator; +import cz.cvut.fel.aic.agentpolis.simmodel.entity.vehicle.PhysicalTransportVehicle; +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.EGraphType; import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode; import cz.cvut.fel.aic.agentpolis.simulator.visualization.visio.VisioPositionUtil; import cz.cvut.fel.aic.alite.common.event.EventProcessor; +import cz.cvut.fel.aic.simod.DemandSimulationEntityType; import cz.cvut.fel.aic.simod.StationsDispatcher; import cz.cvut.fel.aic.simod.config.SimodConfig; import cz.cvut.fel.aic.simod.entity.vehicle.OnDemandVehicle; @@ -34,33 +37,34 @@ import cz.cvut.fel.aic.simod.storage.PhysicalTransportVehicleStorage; /** - * * @author F.I.D.O. */ @Singleton -public class RidesharingOnDemandVehicleFactory extends OnDemandVehicleFactory{ - +public class RidesharingOnDemandVehicleFactory extends OnDemandVehicleFactory { + + private static final int LENGTH = 4; + @Inject public RidesharingOnDemandVehicleFactory( - PhysicalTransportVehicleStorage vehicleStorage, - TripsUtil tripsUtil, + PhysicalTransportVehicleStorage vehicleStorage, + TripsUtil tripsUtil, StationsDispatcher onDemandVehicleStationsCentral, - VisioPositionUtil positionUtil, - EventProcessor eventProcessor, - StandardTimeProvider timeProvider, - IdGenerator rebalancingIdGenerator, + VisioPositionUtil positionUtil, + EventProcessor eventProcessor, + StandardTimeProvider timeProvider, + IdGenerator rebalancingIdGenerator, SimodConfig config, IdGenerator idGenerator, AgentpolisConfig agentpolisConfig) { super( - vehicleStorage, - tripsUtil, - onDemandVehicleStationsCentral, - positionUtil, - eventProcessor, - timeProvider, - rebalancingIdGenerator, - config, + vehicleStorage, + tripsUtil, + onDemandVehicleStationsCentral, + positionUtil, + eventProcessor, + timeProvider, + rebalancingIdGenerator, + config, idGenerator, agentpolisConfig); } @@ -68,22 +72,27 @@ public RidesharingOnDemandVehicleFactory( @Override public OnDemandVehicle create(String vehicleId, SimulationNode startPosition) { return new RideSharingOnDemandVehicle( - vehicleStorage, - tripsUtil, - onDemandVehicleStationsCentral, - driveActivityFactory, + vehicleStorage, + tripsUtil, + onDemandVehicleStationsCentral, + driveActivityFactory, positionUtil, - rebalancingIdGenerator, + rebalancingIdGenerator, eventProcessor, - timeProvider, - rebalancingIdGenerator, - config, - idGenerator, + timeProvider, + rebalancingIdGenerator, + config, + idGenerator, agentpolisConfig, - vehicleId, - startPosition); + vehicleId, + startPosition, + new PhysicalTransportVehicle( + vehicleId, + DemandSimulationEntityType.VEHICLE, + LENGTH, + config.ridesharing.vehicleCapacity, + EGraphType.HIGHWAY, + startPosition, + agentpolisConfig.maxVehicleSpeedInMeters)); } - - - } diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/insertionheuristic/InsertionHeuristicSolver.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/insertionheuristic/InsertionHeuristicSolver.java index c7561a6d..909b4403 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/insertionheuristic/InsertionHeuristicSolver.java +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/insertionheuristic/InsertionHeuristicSolver.java @@ -49,90 +49,90 @@ import cz.cvut.fel.aic.simod.statistics.content.RidesharingBatchStatsIH; import cz.cvut.fel.aic.simod.storage.OnDemandVehicleStorage; import cz.cvut.fel.aic.simod.storage.OnDemandvehicleStationStorage; + import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; + import me.tongfei.progressbar.ProgressBar; import org.slf4j.LoggerFactory; /** - * * @author F.I.D.O. */ @Singleton -public class InsertionHeuristicSolver extends DARPSolver implements EventHandler{ - +public class InsertionHeuristicSolver extends DARPSolver implements EventHandler +{ + private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(InsertionHeuristicSolver.class); - - private static final int INFO_PERIOD = 1000; + + private static final int INFO_PERIOD = 1000; private final PositionUtil positionUtil; - + private final SimodConfig config; - + private final double maxDistance; - + private final double maxDistanceSquared; - + private final int maxDelayTime; - + private final TimeProvider timeProvider; - + private final TypedSimulation eventProcessor; - + private final DroppedDemandsAnalyzer droppedDemandsAnalyzer; - + private final OnDemandvehicleStationStorage onDemandvehicleStationStorage; - - - + + private long callCount = 0; - + private long totalTime = 0; - + private long iterationTime = 0; - + private volatile long canServeRequestCallCount = 0; - + private long vehiclePlanningAllCallCount = 0; - + private Map planMap; - + private int failFastTime; - + private int insertionHeuristicTime; - + private int debugFailTime; - + private double minCostIncrement; - + private PlanData bestPlan; - + OnDemandVehicle vehicleFromNearestStation; - + private int[] usedVehiclesPerStation; - + private List vehiclesForPlanning; - - - - + + @Inject public InsertionHeuristicSolver( - TravelTimeProvider travelTimeProvider, - PlanCostProvider travelCostProvider, - OnDemandVehicleStorage vehicleStorage, + TravelTimeProvider travelTimeProvider, + PlanCostProvider travelCostProvider, + OnDemandVehicleStorage vehicleStorage, PositionUtil positionUtil, - SimodConfig config, - TimeProvider timeProvider, + SimodConfig config, + TimeProvider timeProvider, DefaultPlanComputationRequestFactory requestFactory, - TypedSimulation eventProcessor, + TypedSimulation eventProcessor, DroppedDemandsAnalyzer droppedDemandsAnalyzer, OnDemandvehicleStationStorage onDemandvehicleStationStorage, - AgentpolisConfig agentpolisConfig) { + AgentpolisConfig agentpolisConfig) + { super(vehicleStorage, travelTimeProvider, travelCostProvider, requestFactory); this.positionUtil = positionUtil; this.config = config; @@ -140,70 +140,80 @@ public InsertionHeuristicSolver( this.eventProcessor = eventProcessor; this.droppedDemandsAnalyzer = droppedDemandsAnalyzer; this.onDemandvehicleStationStorage = onDemandvehicleStationStorage; - - + + // max distance in meters between vehicle and request for the vehicle to be considered to serve the request - maxDistance = (double) config.ridesharing.maxProlongationInSeconds + maxDistance = (double) config.ridesharing.maxProlongationInSeconds * agentpolisConfig.maxVehicleSpeedInMeters; maxDistanceSquared = maxDistance * maxDistance; - + // the traveltime from vehicle to request cannot be greater than max prolongation in milliseconds for the // vehicle to be considered to serve the request - maxDelayTime = config.ridesharing.maxProlongationInSeconds * 1000; - + maxDelayTime = config.ridesharing.maxProlongationInSeconds * 1000; + setEventHandeling(); } @Override - public Map solve(List newRequests, - List waitingRequests) { + public Map solve(List newRequests, + List waitingRequests) + { callCount++; long startTime = System.nanoTime(); - + planMap = new ConcurrentHashMap<>(); - + // statistics failFastTime = 0; insertionHeuristicTime = 0; debugFailTime = 0; - - List requests = config.ridesharing.insertionHeuristic.recomputeWaitingRequests + + List requests = config.ridesharing.insertionHeuristic.recomputeWaitingRequests ? waitingRequests : newRequests; - + // discard current plans if the recomputing is on - if(config.ridesharing.insertionHeuristic.recomputeWaitingRequests){ - for(AgentPolisEntity tVvehicle: vehicleStorage.getEntitiesForIteration()){ + if (config.ridesharing.insertionHeuristic.recomputeWaitingRequests) + { + for (AgentPolisEntity tVvehicle : vehicleStorage.getEntitiesForIteration()) + { RideSharingOnDemandVehicle vehicle = (RideSharingOnDemandVehicle) tVvehicle; DriverPlan currentPlan = vehicle.getCurrentPlan(); Iterator actionIterator = currentPlan.iterator(); - while(actionIterator.hasNext()){ + while (actionIterator.hasNext()) + { PlanAction action = actionIterator.next(); - if(action instanceof PlanRequestAction && !((PlanRequestAction) action).request.isOnboard()){ + if (action instanceof PlanRequestAction && !((PlanRequestAction) action).request.isOnboard()) + { actionIterator.remove(); } } planMap.put(vehicle, currentPlan); } } - + // List vehiclesForPlanning = getDrivingVehicles(); usedVehiclesPerStation = new int[onDemandvehicleStationStorage.size()]; - + getVehiclesForPlanning(); - - if(requests.size() > 10){ - for(PlanComputationRequest request: ProgressBar.wrap(requests, "Processing new requests")){ + + if (requests.size() > 10) + { + for (PlanComputationRequest request : ProgressBar.wrap(requests, "Processing new requests")) + { processRequest(request); } } - else{ - for(PlanComputationRequest request: requests){ + else + { + for (PlanComputationRequest request : requests) + { processRequest(request); } } - + totalTime += System.nanoTime() - startTime; - if(callCount % InsertionHeuristicSolver.INFO_PERIOD == 0){ + if (callCount % InsertionHeuristicSolver.INFO_PERIOD == 0) + { StringBuilder sb = new StringBuilder(); sb.append("Insetrion Heuristic Stats: \n"); sb.append("Real time: ").append(System.nanoTime()).append(readableTime(System.nanoTime())).append("\n"); @@ -217,263 +227,308 @@ public Map solve(List typesToHandle = new LinkedList<>(); typesToHandle.add(OnDemandVehicleEvent.PICKUP); eventProcessor.addEventHandler(this, typesToHandle); } - - private boolean canServeRequest(RideSharingOnDemandVehicle vehicle, PlanComputationRequest request){ + + private boolean canServeRequest(RideSharingOnDemandVehicle vehicle, PlanComputationRequest request) + { canServeRequestCallCount++; - + // do not mess with rebalancing - if(vehicle.getState() == OnDemandVehicleState.REBALANCING){ + if (vehicle.getState() == OnDemandVehicleState.REBALANCING) + { return false; } - + // node identity - if(vehicle.getPosition() == request.getFrom()){ + if (vehicle.getPosition() == request.getFrom()) + { return true; } - + // euclidean distance check double dist_x = vehicle.getPosition().getLatitudeProjected() - request.getFrom().getLatitudeProjected(); double dist_y = vehicle.getPosition().getLongitudeProjected() - request.getFrom().getLongitudeProjected(); double distanceSquared = dist_x * dist_x + dist_y * dist_y; - if(distanceSquared > maxDistanceSquared){ + if (distanceSquared > maxDistanceSquared) + { return false; } - - // real feasibility check - boolean canServe = travelTimeProvider.getTravelTime(vehicle, request.getFrom()) + + // real feasibility check + boolean canServe = travelTimeProvider.getTravelTime(vehicle, request.getFrom()) < maxDelayTime; - - + + return canServe; } - - private void computeOptimalPlan(RideSharingOnDemandVehicle vehicle, PlanComputationRequest planComputationRequest) { + + private void computeOptimalPlan(RideSharingOnDemandVehicle vehicle, PlanComputationRequest planComputationRequest) + { computeOptimalPlan(vehicle, vehicle.getCurrentPlan(), planComputationRequest); } - private void computeOptimalPlan(RideSharingOnDemandVehicle vehicle, DriverPlan currentPlan, PlanComputationRequest planComputationRequest) { - + private void computeOptimalPlan(RideSharingOnDemandVehicle vehicle, DriverPlan currentPlan, PlanComputationRequest planComputationRequest) + { + int freeCapacity = vehicle.getFreeCapacity(); - - for(int pickupOptionIndex = 1; pickupOptionIndex <= currentPlan.getLength(); pickupOptionIndex++){ - + + for (int pickupOptionIndex = 1; pickupOptionIndex <= currentPlan.getLength(); pickupOptionIndex++) + { + // continue if the vehicle is full - if(freeCapacity == 0){ + if (freeCapacity == 0) + { continue; } - - for(int dropoffOptionIndex = pickupOptionIndex + 1; dropoffOptionIndex <= currentPlan.getLength() + 1; - dropoffOptionIndex++){ - DriverPlan potentialPlan = insertIntoPlan(currentPlan, pickupOptionIndex, dropoffOptionIndex, + + for (int dropoffOptionIndex = pickupOptionIndex + 1; dropoffOptionIndex <= currentPlan.getLength() + 1; + dropoffOptionIndex++) + { + DriverPlan potentialPlan = insertIntoPlan(currentPlan, pickupOptionIndex, dropoffOptionIndex, vehicle, planComputationRequest); - if(potentialPlan != null){ + if (potentialPlan != null) + { double costIncrement = potentialPlan.cost - currentPlan.cost; PlanData bestPlanData = new PlanData(vehicle, potentialPlan, costIncrement); tryUpdateBestPlan(bestPlanData); } } - + // change free capacity for next index - if(pickupOptionIndex < currentPlan.getLength()){ - if(currentPlan.plan.get(pickupOptionIndex) instanceof PlanActionPickup){ + if (pickupOptionIndex < currentPlan.getLength()) + { + if (currentPlan.plan.get(pickupOptionIndex) instanceof PlanActionPickup) + { freeCapacity--; } - else{ + else + { freeCapacity++; } } } } - + /** * Returns list of plan tasks with new request actions added at specified indexes or null if the plan is infeasible. - * @param currentPlan Current plan, starting with the current position action - * @param pickupOptionIndex Pick up index: 1 - current plan length - * @param dropoffOptionIndex Drop off index: 2 - current plan length + 1 + * + * @param currentPlan Current plan, starting with the current position action + * @param pickupOptionIndex Pick up index: 1 - current plan length + * @param dropoffOptionIndex Drop off index: 2 - current plan length + 1 * @param vehicle * @param planComputationRequest * @return list of plan tasks with new request actions added at specified indexes or null if the plan is infeasible. */ - private DriverPlan insertIntoPlan(final DriverPlan currentPlan, final int pickupOptionIndex, - final int dropoffOptionIndex, final RideSharingOnDemandVehicle vehicle, - final PlanComputationRequest planComputationRequest) { - + private DriverPlan insertIntoPlan(final DriverPlan currentPlan, final int pickupOptionIndex, + final int dropoffOptionIndex, final RideSharingOnDemandVehicle vehicle, + final PlanComputationRequest planComputationRequest) + { + List newPlanTasks = new LinkedList<>(); - - + + // travel time of the new plan in milliseconds int newPlanTravelTime = 0; - + // discomfort of the new plan in milliseconds int newPlanDiscomfort = 0; - + PlanAction previousTask = null; - + // index of the lastly added action from the old plan (not considering current position action) int indexInOldPlan = -1; - + Iterator oldPlanIterator = currentPlan.iterator(); int freeCapacity = vehicle.getFreeCapacity(); - - for(int newPlanIndex = 0; newPlanIndex <= currentPlan.getLength() + 1; newPlanIndex++){ - + + for (int newPlanIndex = 0; newPlanIndex <= currentPlan.getLength() + 1; newPlanIndex++) + { + /* get new task */ PlanAction newTask = null; - if(newPlanIndex == pickupOptionIndex){ + if (newPlanIndex == pickupOptionIndex) + { newTask = planComputationRequest.getPickUpAction(); // new PlanActionPickup(request.getDemandAgent(), request.getDemandAgent().getPosition()); } - else if(newPlanIndex == dropoffOptionIndex){ + else if (newPlanIndex == dropoffOptionIndex) + { newTask = planComputationRequest.getDropOffAction(); // = new DriverPlanTask(DriverPlanTaskType.DROPOFF, request.getDemandAgent(), // request.getTargetLocation()); } - else{ + else + { newTask = oldPlanIterator.next(); } - + // travel time increment - if(previousTask != null){ - if(previousTask instanceof PlanActionCurrentPosition){ + if (previousTask != null) + { + if (previousTask instanceof PlanActionCurrentPosition) + { newPlanTravelTime += travelTimeProvider.getTravelTime(vehicle, newTask.getPosition()); } - else{ - newPlanTravelTime += travelTimeProvider.getTravelTime(vehicle, previousTask.getPosition(), + else + { + newPlanTravelTime += travelTimeProvider.getTravelTime(vehicle, previousTask.getPosition(), newTask.getPosition()); } } long currentTaskTimeInSeconds = (timeProvider.getCurrentSimTime() + newPlanTravelTime) / 1000; // LOGGER.debug("currentTaskTimeInSeconds: {}", currentTaskTimeInSeconds); - + /* check max time for all unfinished demands */ - + // check max time check for the new action - if(newTask instanceof PlanRequestAction){ + if (newTask instanceof PlanRequestAction) + { int maxTime = ((PlanRequestAction) newTask).getMaxTime(); - if(maxTime < currentTaskTimeInSeconds){ + if (maxTime < currentTaskTimeInSeconds) + { // LOGGER.debug("currentTaskTimeInSeconds {} \n> maxTime {}",currentTaskTimeInSeconds, maxTime); return null; } } - + // check max time for actions in the current plan - for(int index = indexInOldPlan + 1; index < currentPlan.getLength(); index++){ + for (int index = indexInOldPlan + 1; index < currentPlan.getLength(); index++) + { PlanAction remainingAction = currentPlan.plan.get(index); - if(!(remainingAction instanceof PlanActionCurrentPosition)){ + if (!(remainingAction instanceof PlanActionCurrentPosition)) + { PlanRequestAction remainingRequestAction = (PlanRequestAction) remainingAction; - if(remainingRequestAction.getMaxTime() < currentTaskTimeInSeconds){ + if (remainingRequestAction.getMaxTime() < currentTaskTimeInSeconds) + { return null; } } } - + // check max time for pick up action - if(newPlanIndex <= pickupOptionIndex){ - if(planComputationRequest.getPickUpAction().getMaxTime() < currentTaskTimeInSeconds){ - return null; + if (newPlanIndex <= pickupOptionIndex) + { + if (planComputationRequest.getPickUpAction().getMaxTime() < currentTaskTimeInSeconds) + { + return null; } } - + // check max time for drop off action - if(newPlanIndex <= dropoffOptionIndex){ - if(planComputationRequest.getDropOffAction().getMaxTime() < currentTaskTimeInSeconds){ + if (newPlanIndex <= dropoffOptionIndex) + { + if (planComputationRequest.getDropOffAction().getMaxTime() < currentTaskTimeInSeconds) + { return null; } } - - + + /* pickup and drop off handeling */ - if(newTask instanceof PlanActionDropoff){ + if (newTask instanceof PlanActionDropoff) + { freeCapacity++; - + // discomfort increment PlanComputationRequest newRequest = ((PlanActionDropoff) newTask).getRequest(); long taskExecutionTime = timeProvider.getCurrentSimTime() + newPlanTravelTime; - newPlanDiscomfort += taskExecutionTime - newRequest.getOriginTime() * 1000 + newPlanDiscomfort += taskExecutionTime - newRequest.getOriginTime() * 1000 - newRequest.getMinTravelTime() * 1000; } - else if(newTask instanceof PlanActionPickup){ + else if (newTask instanceof PlanActionPickup) + { // capacity check - if(freeCapacity == 0){ + if (freeCapacity == 0) + { return null; } freeCapacity--; } - + // index in old plan if the action was not new - if(newPlanIndex != pickupOptionIndex && newPlanIndex != dropoffOptionIndex){ + if (newPlanIndex != pickupOptionIndex && newPlanIndex != dropoffOptionIndex) + { indexInOldPlan++; } - + newPlanTasks.add(newTask); previousTask = newTask; } - + // cost computation double newPlanCost = planCostProvider.calculatePlanCost(newPlanDiscomfort, newPlanTravelTime); - + return new DriverPlan(newPlanTasks, newPlanTravelTime, newPlanCost); } - private String readableTime(long nanoTime) { + private String readableTime(long nanoTime) + { long milisTotal = (long) nanoTime / 1000000; long millis = milisTotal % 1000; long second = (milisTotal / 1000) % 60; long minute = (milisTotal / (1000 * 60)) % 60; long hour = (milisTotal / (1000 * 60 * 60)) % 24; - + return String.format(" (%02d:%02d:%02d:%d)", hour, minute, second, millis); } - private void logRidesharingStats(List requests) { - ridesharingStats.add(new RidesharingBatchStatsIH(failFastTime, insertionHeuristicTime, debugFailTime, + private void logRidesharingStats(List requests) + { + ridesharingStats.add(new RidesharingBatchStatsIH(failFastTime, insertionHeuristicTime, debugFailTime, requests.size())); } - private void computeBestPlanForRequest(PlanComputationRequest request) { + private void computeBestPlanForRequest(PlanComputationRequest request) + { resetBestPlan(); - + // in case of station system, add one vehicle from the nearest station - if(config.stations.on){ //!onDemandvehicleStationStorage.isEmpty()){ // - OnDemandVehicleStation nearestStation = onDemandvehicleStationStorage.getNearestStation(request.getFrom(), - OnDemandvehicleStationStorage.NearestType.TRAVELTIME_FROM); + if (config.stations.on) + { //!onDemandvehicleStationStorage.isEmpty()){ // + OnDemandVehicleStation nearestStation = onDemandvehicleStationStorage.getNearestStation(request.getFrom(), + OnDemandvehicleStationStorage.NearestType.TRAVELTIME_FROM); int indexFromEnd = usedVehiclesPerStation[Integer.parseInt(nearestStation.getId())]; int index = nearestStation.getParkedVehiclesCount() - 1 - indexFromEnd; - if(index >= 0){ + if (index >= 0) + { vehicleFromNearestStation = nearestStation.getVehicle(index); vehiclesForPlanning.add(vehicleFromNearestStation); } - else{ + else + { LOGGER.warn("Nearest station {} empty for request {}", nearestStation, request); } } - - + + long iterationStartTime = System.nanoTime(); vehiclesForPlanning.stream().parallel().forEach((tVvehicle) -> { @@ -482,56 +537,67 @@ private void computeBestPlanForRequest(PlanComputationRequest request) { iterationTime += System.nanoTime() - iterationStartTime; } - - private void processRequestVehicleCombination(PlanComputationRequest request, AgentPolisEntity tVvehicle){ + + private void processRequestVehicleCombination(PlanComputationRequest request, AgentPolisEntity tVvehicle) + { RideSharingOnDemandVehicle vehicle = (RideSharingOnDemandVehicle) tVvehicle; - + DriverPlan currentPlan = vehicle.getCurrentPlan(); - + // if the plan was already changed - if(planMap.containsKey(vehicle)){ + if (planMap.containsKey(vehicle)) + { currentPlan = planMap.get(vehicle); } - + tryToAddRequestToPlan(request, vehicle, currentPlan); } - - public void tryToAddRequestToPlan(PlanComputationRequest request, RideSharingOnDemandVehicle vehicle, DriverPlan plan){ + + public void tryToAddRequestToPlan(PlanComputationRequest request, RideSharingOnDemandVehicle vehicle, DriverPlan plan) + { // fail fast - if(canServeRequest(vehicle, request)){ + if (canServeRequest(vehicle, request)) + { computeOptimalPlan(vehicle, plan, request); } } - - private synchronized void tryUpdateBestPlan(PlanData newPlanData){ + + private synchronized void tryUpdateBestPlan(PlanData newPlanData) + { vehiclePlanningAllCallCount++; - - if(newPlanData != null && newPlanData.increment < minCostIncrement){ + + if (newPlanData != null && newPlanData.increment < minCostIncrement) + { minCostIncrement = newPlanData.increment; bestPlan = newPlanData; } } - private void processRequest(PlanComputationRequest request) { + private void processRequest(PlanComputationRequest request) + { Benchmark benchmark = new Benchmark(); benchmark.measureTime(() -> computeBestPlanForRequest(request)); insertionHeuristicTime += benchmark.getDurationMsInt(); - if(bestPlan != null){ + if (bestPlan != null) + { planMap.put(bestPlan.vehicle, bestPlan.plan); - - if(bestPlan.vehicle == vehicleFromNearestStation){ + + if (bestPlan.vehicle == vehicleFromNearestStation) + { usedVehiclesPerStation[Integer.parseInt(vehicleFromNearestStation.getParkedIn().getId())]++; } // remove nearest vehicle if not used - else{ + else + { vehiclesForPlanning.remove(vehicleFromNearestStation); } } - else{ + else + { LOGGER.debug("Request {} cannot be served!", request); - benchmark = new Benchmark(); - benchmark.measureTime(() -> droppedDemandsAnalyzer.debugFail(request, usedVehiclesPerStation)); + benchmark = new Benchmark(); + benchmark.measureTime(() -> droppedDemandsAnalyzer.debugFail(request, usedVehiclesPerStation)); debugFailTime += benchmark.getDurationMs(); } } @@ -545,43 +611,51 @@ private void processRequest(PlanComputationRequest request) { // } // return listForPlanning; // } - - private List getVehiclesForPlanning() { + + private List getVehiclesForPlanning() + { vehiclesForPlanning = new ArrayList<>(); - for(OnDemandVehicle vehicle: vehicleStorage){ - if(vehicle.getState() != OnDemandVehicleState.REBALANCING - && (!config.stations.on || vehicle.getState() != OnDemandVehicleState.WAITING)){ + for (OnDemandVehicle vehicle : vehicleStorage) + { + if (vehicle.getState() != OnDemandVehicleState.REBALANCING + && (!config.stations.on || vehicle.getState() != OnDemandVehicleState.WAITING)) + { vehiclesForPlanning.add(vehicle); } } - + return vehiclesForPlanning; } - public void resetBestPlan() { + public void resetBestPlan() + { minCostIncrement = Double.MAX_VALUE; bestPlan = null; } - - public DriverPlan getBestPlan(){ - if(bestPlan == null){ + + public DriverPlan getBestPlan() + { + if (bestPlan == null) + { return null; } return bestPlan.plan; } - - private class PlanData{ + + private class PlanData + { final DriverPlan plan; - + final double increment; - + final RideSharingOnDemandVehicle vehicle; - public PlanData(RideSharingOnDemandVehicle vehicle, DriverPlan plan, double increment) { + public PlanData(RideSharingOnDemandVehicle vehicle, DriverPlan plan, double increment) + { this.vehicle = vehicle; this.plan = plan; this.increment = increment; } } - + } diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/DefaultPlanComputationRequest.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/DefaultPlanComputationRequest.java index 677cf48f..82a9c71d 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/DefaultPlanComputationRequest.java +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/DefaultPlanComputationRequest.java @@ -23,6 +23,7 @@ import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode; import cz.cvut.fel.aic.simod.config.SimodConfig; import cz.cvut.fel.aic.simod.entity.DemandAgent; +import cz.cvut.fel.aic.simod.ridesharing.peoplefreightsheuristic.TransportableDemandEntity; import cz.cvut.fel.aic.simod.traveltimecomputation.TravelTimeProvider; import java.util.Random; @@ -36,7 +37,7 @@ public class DefaultPlanComputationRequest implements PlanComputationRequest{ */ private final int originTime; - private final DemandAgent demandAgent; + private final TransportableDemandEntity demandEntity; private final PlanActionPickup pickUpAction; @@ -79,14 +80,14 @@ public void setOnboard(boolean onboard) { } @Override - public DemandAgent getDemandAgent() { - return demandAgent; + public TransportableDemandEntity getDemandEntity() { + return demandEntity; } @Inject - private DefaultPlanComputationRequest(TravelTimeProvider travelTimeProvider, @Assisted int id, + public DefaultPlanComputationRequest(TravelTimeProvider travelTimeProvider, @Assisted int id, SimodConfig SimodConfig, @Assisted("origin") SimulationNode origin, @Assisted("destination") SimulationNode destination, @Assisted DemandAgent demandAgent){ this.id = id; @@ -109,7 +110,7 @@ private DefaultPlanComputationRequest(TravelTimeProvider travelTimeProvider, @As int maxPickUpTime = originTime + maxProlongation; int maxDropOffTime = originTime + minTravelTime + maxProlongation; - this.demandAgent = demandAgent; + this.demandEntity = demandAgent; onboard = false; pickUpAction = new PlanActionPickup(this, origin, maxPickUpTime); @@ -145,7 +146,7 @@ public int hashCode() { Random rand = new Random(); int a = rand.nextInt(p) + 1; int b = rand.nextInt(p); - hash = (int) (((long) a * demandAgent.getSimpleId() + b) % p) % 1_200_000 ; + hash = (int) (((long) a * demandEntity.getSimpleId() + b) % p) % 1_200_000 ; } return hash; } @@ -153,7 +154,7 @@ public int hashCode() { @Override public String toString() { - return String.format("%s - from: %s to: %s", demandAgent, getFrom(), getTo()); + return String.format("%s - from: %s to: %s", demandEntity, getFrom(), getTo()); } @Override diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/PlanActionDropoff.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/PlanActionDropoff.java index d267be5f..6061db60 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/PlanActionDropoff.java +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/PlanActionDropoff.java @@ -36,7 +36,7 @@ public PlanActionDropoff(PlanComputationRequest request, SimulationNode node, in @Override public String toString() { - return String.format("Drop off demand %s at node %s", request.getDemandAgent().getId(), location.id); + return String.format("Drop off demand %s at node %s", request.getDemandEntity().getId(), location.id); } diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/PlanActionPickup.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/PlanActionPickup.java index d1b64484..e439125d 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/PlanActionPickup.java +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/PlanActionPickup.java @@ -36,7 +36,7 @@ public PlanActionPickup(PlanComputationRequest request, SimulationNode node, int @Override public String toString() { - return String.format("Pick up demand %s at node %s", request.getDemandAgent().getId(), location.id); + return String.format("Pick up demand %s at node %s", request.getDemandEntity().getId(), location.id); } diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/PlanComputationRequest.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/PlanComputationRequest.java index 3d6c0b53..55ecbd54 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/PlanComputationRequest.java +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/PlanComputationRequest.java @@ -19,7 +19,7 @@ package cz.cvut.fel.aic.simod.ridesharing.model; import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode; -import cz.cvut.fel.aic.simod.entity.DemandAgent; +import cz.cvut.fel.aic.simod.ridesharing.peoplefreightsheuristic.TransportableDemandEntity; /** * @@ -65,7 +65,7 @@ public interface PlanComputationRequest { public PlanActionDropoff getDropOffAction(); - public DemandAgent getDemandAgent(); + public TransportableDemandEntity getDemandEntity(); public int getId(); diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/PlanRequestAction.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/PlanRequestAction.java index e86f588e..62d43ad0 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/PlanRequestAction.java +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/model/PlanRequestAction.java @@ -29,7 +29,7 @@ public abstract class PlanRequestAction extends PlanAction{ /** * Time constraint in seconds */ - private final int maxTime; + private final int maxTime; // do kdy public PlanComputationRequest getRequest() { return request; diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/DARPSolverPFShared.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/DARPSolverPFShared.java new file mode 100644 index 00000000..cd5e3cef --- /dev/null +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/DARPSolverPFShared.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2021 Czech Technical University in Prague. + * + * This file is part of the SiMoD project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package cz.cvut.fel.aic.simod.ridesharing.peoplefreightsheuristic; + +import cz.cvut.fel.aic.simod.ridesharing.DARPSolver; +import cz.cvut.fel.aic.simod.ridesharing.PlanCostProvider; +//import cz.cvut.fel.aic.simod.ridesharing.peoplefreightsheuristic.RidesharingPFDispatcher; +import cz.cvut.fel.aic.simod.ridesharing.insertionheuristic.DriverPlan; +import cz.cvut.fel.aic.simod.ridesharing.model.PlanComputationRequest; +import cz.cvut.fel.aic.simod.storage.OnDemandVehicleStorage; +import cz.cvut.fel.aic.simod.traveltimecomputation.TravelTimeProvider; +import cz.cvut.fel.aic.simod.statistics.content.RidesharingBatchStats; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + + + +public abstract class DARPSolverPFShared extends DARPSolver { + + protected final OnDemandVehicleStorage vehicleStorage; + + protected final TravelTimeProvider travelTimeProvider; + + protected final PlanCostProvider planCostProvider; + + protected final DefaultPFPlanCompRequest.DefaultPFPlanComputationRequestFactory requestFactory; + + protected final List ridesharingStats; + + + protected RidesharingPFDispatcher ridesharingDispatcher; + + + + public List getRidesharingStats() { + return ridesharingStats; + } + + + public void setDispatcher(RidesharingPFDispatcher ridesharingDispatcher){ + this.ridesharingDispatcher = ridesharingDispatcher; + } + + + + + + public DARPSolverPFShared(OnDemandVehicleStorage vehicleStorage, TravelTimeProvider travelTimeProvider, + PlanCostProvider travelCostProvider, DefaultPFPlanCompRequest.DefaultPFPlanComputationRequestFactory requestFactory) { + super(vehicleStorage, travelTimeProvider, travelCostProvider, null); + this.vehicleStorage = vehicleStorage; + this.travelTimeProvider = travelTimeProvider; + this.planCostProvider = travelCostProvider; + this.requestFactory = requestFactory; + ridesharingStats = new ArrayList<>(); + } + + + + + public abstract Map solve(List newPeopleRequests, + List waitingPeopleRequests, + List newFreightRequests, + List waitingFreightRequests); +} + diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/DefaultPFPlanCompRequest.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/DefaultPFPlanCompRequest.java new file mode 100644 index 00000000..1ad31e7f --- /dev/null +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/DefaultPFPlanCompRequest.java @@ -0,0 +1,163 @@ +package cz.cvut.fel.aic.simod.ridesharing.peoplefreightsheuristic; + +import com.google.inject.Inject; +import com.google.inject.assistedinject.Assisted; +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode; +import cz.cvut.fel.aic.simod.config.SimodConfig; +import cz.cvut.fel.aic.simod.ridesharing.model.PlanActionDropoff; +import cz.cvut.fel.aic.simod.ridesharing.model.PlanActionPickup; +import cz.cvut.fel.aic.simod.ridesharing.model.PlanComputationRequest; +import cz.cvut.fel.aic.simod.traveltimecomputation.TravelTimeProvider; + +import java.util.Random; + + +public class DefaultPFPlanCompRequest implements PlanComputationRequest { + + public final int id; + + /** + * Request origin time in seconds. + */ + private final int originTime; + + private final TransportableDemandEntity demandEntity; + + private final PlanActionPickup pickUpAction; + + private final PlanActionDropoff dropOffAction; + + /** + * Min travel time in seconds + */ + private final int minTravelTime; + + private boolean onboard; + + private int hash; + + + @Inject + public DefaultPFPlanCompRequest(TravelTimeProvider travelTimeProvider, @Assisted int id, + SimodConfig simodConfig, @Assisted("origin") SimulationNode origin, + @Assisted("destination") SimulationNode destination, @Assisted TransportableDemandEntity demandEntity) { + this.id = id; + + hash = 0; + + originTime = (int) Math.round(demandEntity.getDemandTime() / 1000.0); + minTravelTime = (int) Math.round( + travelTimeProvider.getExpectedTravelTime(origin, destination) / 1000.0); + + int maxProlongation; + if (simodConfig.ridesharing.discomfortConstraint.equals("absolute")) { + maxProlongation = simodConfig.ridesharing.maxProlongationInSeconds; + } + else { + maxProlongation = (int) Math.round( + simodConfig.ridesharing.maximumRelativeDiscomfort * minTravelTime); + } + + // for packages, the delay can be longer + if (demandEntity instanceof DemandPackage) { + maxProlongation += simodConfig.packagesMaxDelay; + } + + int maxPickUpTime = originTime + maxProlongation; + int maxDropOffTime = originTime + minTravelTime + maxProlongation; + + this.demandEntity = demandEntity; + onboard = false; + + pickUpAction = new PlanActionPickup(this, origin, maxPickUpTime); + dropOffAction = new PlanActionDropoff(this, destination, maxDropOffTime); + } + + + @Override + public int getId() { + return id; + } + + @Override + public PlanActionPickup getPickUpAction() { + return pickUpAction; + } + + @Override + public PlanActionDropoff getDropOffAction() { + return dropOffAction; + } + + @Override + public boolean isOnboard() { + return onboard; + } + + public void setOnboard(boolean onboard) { + this.onboard = onboard; + } + + @Override + public TransportableDemandEntity getDemandEntity() { + return demandEntity; + } + + @Override + public int getOriginTime() { + return originTime; + } + + @Override + public boolean equals(Object obj) { + return this == obj; + } + + @Override + public int hashCode() { + if (hash == 0) { + int p = 1_200_007; + Random rand = new Random(); + int a = rand.nextInt(p) + 1; + int b = rand.nextInt(p); + hash = (int) (((long) a * demandEntity.getSimpleId() + b) % p) % 1_200_000; + } + return hash; + } + + @Override + public String toString() { + return String.format("%s - from: %s to: %s", demandEntity, getFrom(), getTo()); + } + + @Override + public int getMaxPickupTime() { + return pickUpAction.getMaxTime(); + } + + @Override + public int getMaxDropoffTime() { + return dropOffAction.getMaxTime(); + } + + @Override + public int getMinTravelTime() { + return minTravelTime; + } + + @Override + public SimulationNode getFrom() { + return pickUpAction.getPosition(); + } + + @Override + public SimulationNode getTo() { + return dropOffAction.getPosition(); + } + + + public interface DefaultPFPlanComputationRequestFactory { + public DefaultPFPlanCompRequest create(int id, @Assisted("origin") SimulationNode origin, + @Assisted("destination") SimulationNode destination, TransportableDemandEntity demandEntity); + } +} diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/DemandPackage.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/DemandPackage.java new file mode 100644 index 00000000..0a51df1b --- /dev/null +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/DemandPackage.java @@ -0,0 +1,219 @@ +package cz.cvut.fel.aic.simod.ridesharing.peoplefreightsheuristic; + +import com.google.inject.Inject; +import com.google.inject.assistedinject.Assisted; +import cz.cvut.fel.aic.agentpolis.siminfrastructure.planner.TripsUtil; +import cz.cvut.fel.aic.agentpolis.siminfrastructure.planner.trip.Trip; +import cz.cvut.fel.aic.agentpolis.siminfrastructure.time.StandardTimeProvider; +import cz.cvut.fel.aic.agentpolis.simmodel.agent.TransportEntity; +import cz.cvut.fel.aic.agentpolis.simmodel.entity.AgentPolisEntity; +import cz.cvut.fel.aic.agentpolis.simmodel.entity.EntityType; +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode; +import cz.cvut.fel.aic.alite.common.event.EventProcessor; +import cz.cvut.fel.aic.simod.DemandData; +import cz.cvut.fel.aic.simod.DemandSimulationEntityType; +import cz.cvut.fel.aic.simod.StationsDispatcher; +import cz.cvut.fel.aic.simod.entity.DemandAgent; +import cz.cvut.fel.aic.simod.entity.DemandAgentState; +import cz.cvut.fel.aic.simod.entity.vehicle.OnDemandVehicleInterface; +import cz.cvut.fel.aic.simod.event.OnDemandVehicleStationsCentralEvent; +import cz.cvut.fel.aic.simod.io.TimeTrip; +import cz.cvut.fel.aic.simod.statistics.DemandServiceStatistic; +import cz.cvut.fel.aic.simod.statistics.StatisticEvent; +import org.slf4j.LoggerFactory; + +import java.util.logging.Level; +import java.util.logging.Logger; + +public class DemandPackage extends AgentPolisEntity implements TransportableDemandEntity { + private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(DemandAgent.class); + + private final int simpleId; + + private final TimeTrip trip; + + private final StationsDispatcher onDemandVehicleStationsCentral; + + private final EventProcessor eventProcessor; + + private final DemandPackageStorage demandStorage; + + private final StandardTimeProvider timeProvider; + + private final TripsUtil tripsUtil; + + /** + * Request announcement time in milliseconds + */ + private final long demandTime; + + + private DemandAgentState state; + + private OnDemandVehicleInterface onDemandVehicle; + + private TransportEntity transportEntity; + + private SimulationNode lastFromPosition; + +// private long scheduledPickupDelay; + + private long realPickupTime = 0; + + private long minDemandServiceDuration; + + // only to save compuatational time it|s +// private long currentServiceDuration; + + private boolean dropped; + + private final int weight; + + + @Inject + public DemandPackage(StationsDispatcher onDemandVehicleStationsCentral, + EventProcessor eventProcessor, + DemandPackageStorage demandStorage, + StandardTimeProvider timeProvider, + TripsUtil tripsUtil, + @Assisted("weight") int packageWeight, + @Assisted String packageId, + @Assisted("id") int id, + @Assisted TimeTrip trip) { + super(packageId, trip.getLocations()[0]); + this.simpleId = id; + this.trip = trip; + this.onDemandVehicleStationsCentral = onDemandVehicleStationsCentral; + this.eventProcessor = eventProcessor; + this.demandStorage = demandStorage; + this.timeProvider = timeProvider; + this.tripsUtil = tripsUtil; + this.weight = packageWeight; + state = DemandAgentState.WAITING; + dropped = false; + demandTime = timeProvider.getCurrentSimTime(); + computeMinServiceDuration(); + } + + + public void create() { + demandStorage.addEntity(this); + eventProcessor.addEvent(OnDemandVehicleStationsCentralEvent.DEMAND, onDemandVehicleStationsCentral, null, + new DemandData(trip.getLocations(), this)); + } + + public void destroy() { + demandStorage.removeEntity(this); + } + + public int getSimpleId() { + return simpleId; + } + +// public void setScheduledPickupDelay(long scheduledPickupDelay) { +// this.scheduledPickupDelay = scheduledPickupDelay; +// } +// +// public long getScheduledPickupDelay() { +// return scheduledPickupDelay; +// } + + public long getRealPickupTime() { + return realPickupTime; + } + + public long getDemandTime() { + return demandTime; + } + + public DemandAgentState getState() { + return state; + } + + public OnDemandVehicleInterface getOnDemandVehicle() { + return onDemandVehicle; + } + + public long getMinDemandServiceDuration() { + return minDemandServiceDuration; + } + + public void setDropped(boolean dropped) { + this.dropped = dropped; + } + + public boolean isDropped() { + return dropped; + } + + public int getWeight() { + return weight; + } + + + public void tripEnded() { + if (!getPosition().equals(trip.getLastLocation())) { + try { + throw new Exception("Demand package not served properly"); + } + catch (Exception ex) { + LOGGER.error(null, ex); + } + } + eventProcessor.addEvent(StatisticEvent.DEMAND_DROPPED_OFF, null, null, + new DemandServiceStatistic(demandTime, realPickupTime, timeProvider.getCurrentSimTime(), + minDemandServiceDuration, getId(), onDemandVehicle.getId())); + + destroy(); + } + + public void tripStarted(OnDemandVehicleInterface vehicle) { + if (state == DemandAgentState.DRIVING) { + try { + throw new Exception(String.format("Demand Package %s already driving in vehicle %s, it cannot be picked up by" + + "another vehicle %s", this, onDemandVehicle, vehicle)); + } + catch (Exception ex) { + Logger.getLogger(DemandPackage.class.getName()).log(Level.SEVERE, null, ex); + } + } + else { + state = DemandAgentState.DRIVING; + realPickupTime = timeProvider.getCurrentSimTime(); + this.onDemandVehicle = vehicle; + } + } + + @Override + public EntityType getType() { + return DemandSimulationEntityType.DEMAND; + } + + @Override + public T getTransportingEntity() { + return (T) transportEntity; + } + + @Override + public void setTransportingEntity(T transportingEntity) { + this.transportEntity = transportingEntity; + } + + @Override + public void setLastFromPosition(SimulationNode lastFromPosition) { + this.lastFromPosition = lastFromPosition; + } + + private void computeMinServiceDuration() { + Trip minTrip = tripsUtil.createTrip(getPosition(), trip.getLastLocation()); + minDemandServiceDuration = tripsUtil.getTripDuration(minTrip); + } + + public String toString() { + return "Package " + this.getType().toString() + " " + this.getId(); + } + + public interface DemandPackageFactory { + DemandPackage create(String packageId, @Assisted("id") int id, TimeTrip osmNodeTrip, @Assisted("weight") int weight); + } +} diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/DemandPackageEventHandler.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/DemandPackageEventHandler.java new file mode 100644 index 00000000..b722873d --- /dev/null +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/DemandPackageEventHandler.java @@ -0,0 +1,35 @@ +package cz.cvut.fel.aic.simod.ridesharing.peoplefreightsheuristic; + +import com.google.inject.Inject; +import cz.cvut.fel.aic.agentpolis.simmodel.IdGenerator; +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode; +import cz.cvut.fel.aic.alite.common.event.Event; +import cz.cvut.fel.aic.alite.common.event.EventHandlerAdapter; +import cz.cvut.fel.aic.simod.io.TimeTrip; + +public class DemandPackageEventHandler extends EventHandlerAdapter { + + private final IdGenerator demandIdGenerator; + + private final DemandPackage.DemandPackageFactory demandPackageFactory; + + + @Inject + public DemandPackageEventHandler(IdGenerator demandIdGenerator, DemandPackage.DemandPackageFactory demandPackageFactory) { + this.demandIdGenerator = demandIdGenerator; + this.demandPackageFactory = demandPackageFactory; + } + + + @Override + public void handleEvent(Event event) { + int id = demandIdGenerator.getId(); + + TimeTrip trip = ((PackageContent) event.getContent()).trip; + + int weight = ((PackageContent) event.getContent()).packageWeight; + + DemandPackage demandPackage = demandPackageFactory.create("Package " + Integer.toString(id), id, trip, weight); + demandPackage.create(); + } +} diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/DemandPackageStorage.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/DemandPackageStorage.java new file mode 100644 index 00000000..c8ecf9ee --- /dev/null +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/DemandPackageStorage.java @@ -0,0 +1,14 @@ +package cz.cvut.fel.aic.simod.ridesharing.peoplefreightsheuristic; + +import com.google.inject.Singleton; +import cz.cvut.fel.aic.agentpolis.simmodel.environment.EntityStorage; +import cz.cvut.fel.aic.simod.ridesharing.peoplefreightsheuristic.DemandPackage; + +@Singleton +public class DemandPackageStorage extends EntityStorage +{ + public DemandPackageStorage() + { + super(); + } +} diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/HelperStructures.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/HelperStructures.java new file mode 100644 index 00000000..5f92e7fc --- /dev/null +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/HelperStructures.java @@ -0,0 +1,46 @@ +package cz.cvut.fel.aic.simod.ridesharing.peoplefreightsheuristic; + +import cz.cvut.fel.aic.simod.ridesharing.model.PlanAction; +import cz.cvut.fel.aic.simod.ridesharing.model.PlanComputationRequest; +import cz.cvut.fel.aic.simod.ridesharing.model.PlanRequestAction; + +import java.util.Comparator; +import java.util.List; + +/** + * comparator for sorting Requests + */ +class SortRequestsByOriginTime implements Comparator { + public int compare(PlanComputationRequest a, PlanComputationRequest b) { + return a.getOriginTime() - b.getOriginTime(); + } +} + +class SortActionsByMaxTime implements Comparator { + public int compare(PlanAction a, PlanAction b) { + return ((PlanRequestAction) a).getMaxTime() - ((PlanRequestAction) b).getMaxTime(); + } +} + +// structure to store a taxi schedule, it's duration and it's cost +class ScheduleWithDuration { + protected final List schedule; + protected final long duration; + protected final double planCost; + + public ScheduleWithDuration(List schedule, long duration, double planCost) { + this.schedule = schedule; + this.duration = duration; + this.planCost = planCost; + } +} + +class TimeWindow { + protected long earlyTime; + protected long lateTime; + + public TimeWindow(long earlyTime, long lateTime) { + this.earlyTime = earlyTime; + this.lateTime = lateTime; + } +} diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/PFSolverBase.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/PFSolverBase.java new file mode 100644 index 00000000..89899094 --- /dev/null +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/PFSolverBase.java @@ -0,0 +1,454 @@ +package cz.cvut.fel.aic.simod.ridesharing.peoplefreightsheuristic; + +import com.google.inject.Inject; +import com.google.inject.Singleton; +import cz.cvut.fel.aic.agentpolis.config.AgentpolisConfig; +import cz.cvut.fel.aic.agentpolis.siminfrastructure.time.TimeProvider; +import cz.cvut.fel.aic.agentpolis.simmodel.entity.AgentPolisEntity; +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode; +import cz.cvut.fel.aic.agentpolis.utils.Benchmark; +import cz.cvut.fel.aic.agentpolis.utils.PositionUtil; +import cz.cvut.fel.aic.alite.common.event.Event; +import cz.cvut.fel.aic.alite.common.event.EventHandler; +import cz.cvut.fel.aic.alite.common.event.EventProcessor; +import cz.cvut.fel.aic.alite.common.event.typed.TypedSimulation; +import cz.cvut.fel.aic.simod.config.SimodConfig; +import cz.cvut.fel.aic.simod.entity.DemandAgent; +import cz.cvut.fel.aic.simod.entity.OnDemandVehicleState; +import cz.cvut.fel.aic.simod.entity.vehicle.OnDemandVehicle; +import cz.cvut.fel.aic.simod.event.OnDemandVehicleEvent; +import cz.cvut.fel.aic.simod.ridesharing.*; +import cz.cvut.fel.aic.simod.ridesharing.insertionheuristic.DriverPlan; +import cz.cvut.fel.aic.simod.ridesharing.model.*; +import cz.cvut.fel.aic.simod.storage.OnDemandVehicleStorage; +import cz.cvut.fel.aic.simod.traveltimecomputation.TravelTimeProvider; +import cz.cvut.fel.aic.simod.storage.OnDemandvehicleStationStorage; + +import java.lang.*; +import java.util.*; + +import org.apache.commons.lang.NotImplementedException; +import org.slf4j.LoggerFactory; + + +@Singleton +public class PFSolverBase extends DARPSolverPFShared implements EventHandler { + + private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(PFSolverBase.class); + + private static final int INFO_PERIOD = 1000; + + private final PositionUtil positionUtil; + + private final SimodConfig config; + + private final double maxDistance; + + private final double maxDistanceSquared; + + private final int maxDelayTime; + + private final TimeProvider timeProvider; + + private final TypedSimulation eventProcessor; + + private final DroppedDemandsAnalyzer droppedDemandsAnalyzer; + + private final OnDemandvehicleStationStorage onDemandvehicleStationStorage; + + + private long callCount = 0; + + private long totalTime = 0; + + private long iterationTime = 0; + + private long peopleFreightHeuristicTime; + + private volatile long canServeRequestCallCount = 0; + + private long vehiclePlanningAllCallCount = 0; + + private int failFastTime; + + private int debugFailTime; + + private double minCostIncrement; + + OnDemandVehicle vehicleFromNearestStation; + + private int[] usedVehiclesPerStation; + + long totalCost = 0; + + private List allVehicles; + + private List> taxiSchedules; + + List taxiCurrentPositions; + + List taxiCurrentPositionsActions; + + ScheduleWithDuration newSchedule; + + @Inject + public PFSolverBase( + TravelTimeProvider travelTimeProvider, + PlanCostProvider travelCostProvider, + OnDemandVehicleStorage vehicleStorage, + PositionUtil positionUtil, + SimodConfig config, + TimeProvider timeProvider, + DefaultPFPlanCompRequest.DefaultPFPlanComputationRequestFactory requestFactory, + TypedSimulation eventProcessor, + DroppedDemandsAnalyzer droppedDemandsAnalyzer, + OnDemandvehicleStationStorage onDemandvehicleStationStorage, + AgentpolisConfig agentpolisConfig) { + super(vehicleStorage, travelTimeProvider, travelCostProvider, requestFactory); + this.positionUtil = positionUtil; + this.config = config; + this.timeProvider = timeProvider; + this.eventProcessor = eventProcessor; + this.droppedDemandsAnalyzer = droppedDemandsAnalyzer; + this.onDemandvehicleStationStorage = onDemandvehicleStationStorage; + this.newSchedule = null; + + setEventHandeling(); + + + // max distance in meters between vehicle and request for the vehicle to be considered to serve the request + maxDistance = (double) config.ridesharing.maxProlongationInSeconds + * agentpolisConfig.maxVehicleSpeedInMeters; + maxDistanceSquared = maxDistance * maxDistance; + // the traveltime from vehicle to request cannot be greater than max prolongation in milliseconds for the + // vehicle to be considered to serve the request + maxDelayTime = config.ridesharing.maxProlongationInSeconds * 1000; + + + } + + + /** + * @param newRequestsPeople - people requests + * @param waitingRequestsPeople - not used + * @param newRequestsFreight - freight requests + * @param waitingRequestsFreight - not used + * @return list of plans for all vehicles + */ + @Override + public Map solve( + List newRequestsPeople, + List waitingRequestsPeople, + List newRequestsFreight, + List waitingRequestsFreight) { + +// --------------------------- INIT --------------------------------------- + allVehicles = new ArrayList<>(); + taxiSchedules = new ArrayList<>(); + taxiCurrentPositions = new ArrayList<>(); + taxiCurrentPositionsActions = new ArrayList<>(); + + // statistics + peopleFreightHeuristicTime = 0; + + // initializing the vehicles and plans + for (AgentPolisEntity taxiEntity : vehicleStorage.getEntitiesForIteration()) { + PeopleFreightVehicle newTaxi = (PeopleFreightVehicle) taxiEntity; + allVehicles.add(newTaxi); + List newTaxiCurrentPlan = newTaxi.getCurrentPlanNoUpdate().plan; + + taxiCurrentPositionsActions.add((PlanActionCurrentPosition) newTaxiCurrentPlan.remove(0)); // separate the PlanActionCurrentPosition from the plan + taxiCurrentPositions.add(newTaxi.getPosition()); + taxiSchedules.add(new ArrayList<>(newTaxiCurrentPlan)); + } +// --------------------------- END INIT ------------------------------------ + + // maybe in future: calculate plan discomfort + int planDiscomfort = 0; + + + // list of plan durations for each taxi + List planDurations = new ArrayList<>(Arrays.asList(new Integer[allVehicles.size()])); + Collections.fill(planDurations, 0); + + + List newRequestsAll = new ArrayList<>(); + if (newRequestsPeople != null) { + newRequestsAll.addAll(newRequestsPeople); + } + if (newRequestsFreight != null) { + newRequestsAll.addAll(newRequestsFreight); + } + + + // sort requests incrementally by time windows - maxPickupTime + newRequestsAll.sort(new SortRequestsByOriginTime()); + + List availableTaxis; + + for (int i = 0; i < newRequestsAll.size(); i++) { + DefaultPFPlanCompRequest currentRequest = (DefaultPFPlanCompRequest) newRequestsAll.get(i); + + // select vehicles available at the moment + availableTaxis = new ArrayList<>(); + for (int j = 0; j < allVehicles.size(); j++) { + // first check if vehicle is in a range of maxDistance + if (!(canServeRequest(allVehicles.get(j), currentRequest))) { + continue; + } + + // if taxi j is not carrying person at the moment + if (!allVehicles.get(j).isPassengerOnboard()) { + + // if currentRequest is of type package: check if vehicle has enough space for the package + if (currentRequest instanceof PlanComputationRequestFreight) { + if (((PlanComputationRequestFreight) currentRequest).getWeight() <= allVehicles.get(j).getFreePackagesCapacity()) { + availableTaxis.add(allVehicles.get(j)); + } + } + // otherwise add it right away + else { + availableTaxis.add(allVehicles.get(j)); + } + } + } + + double lowestCostIncrease; + int bestTaxiIdx = -1; // k* - taxi to serve request i to get the lowest cost increase + + if (availableTaxis.size() > 0) { + lowestCostIncrease = Double.POSITIVE_INFINITY; + for (int k = 0; k < availableTaxis.size(); k++) { + PeopleFreightVehicle currentTaxi = availableTaxis.get(k); + // current plan cost + double currentPlanCost_k = planCostProvider.calculatePlanCost(planDiscomfort, (int) (currentTaxi.getCurrentPlanNoUpdate().totalTime / 1000)); + + + // check if schedule is feasible + Benchmark benchmark = new Benchmark(); + benchmark.measureTime(() -> trySchedule(allVehicles.indexOf(currentTaxi), currentRequest)); + peopleFreightHeuristicTime += benchmark.getDurationMsInt(); + + // if current schedule is not feasible, continue to next taxi + if (newSchedule == null) { + continue; + } + + // new plan cost if taxi k serves request i + double newCost_k_i = planCostProvider.calculatePlanCost(planDiscomfort, (int) (newSchedule.duration / 1000)); + double costIncrease_k_i = newCost_k_i - currentPlanCost_k; + if (costIncrease_k_i < lowestCostIncrease) { + lowestCostIncrease = costIncrease_k_i; + bestTaxiIdx = allVehicles.indexOf(currentTaxi); // updating the idx of best taxi so far + } + } + // if suitable taxi was found + if (bestTaxiIdx != -1) { + // Insert request i into route of taxi k∗ + trySchedule(bestTaxiIdx, currentRequest); + taxiSchedules.set(bestTaxiIdx, newSchedule.schedule); // NullPointerException won't happen, because this block happens only if at least 1 taxi was found + planDurations.set(bestTaxiIdx, (int) (newSchedule.duration / 1000)); + + // update total cost + totalCost += lowestCostIncrease; + } + } + // else: reject request i => DO nothing + } + + + Map returnMap = new HashMap<>(); + + for (int i = 0; i < taxiSchedules.size(); i++) { + List actionsList = new ArrayList<>(taxiSchedules.get(i)); + actionsList.add(0, taxiCurrentPositionsActions.get(i)); + int planTime = planDurations.get(i); + double planCost = planCostProvider.calculatePlanCost(planDiscomfort, planTime); + + DriverPlan newPlan = new DriverPlan(actionsList, planTime, planCost); + returnMap.put(allVehicles.get(i), newPlan); + } + + logRidesharingStats(newRequestsAll); + + return returnMap; + } + + + /** + * returns sorted list of new taxi schedule (or null if the schedule is not feasible) and duration of this schedule + */ + private void trySchedule(int taxiIndex, PlanComputationRequest newRequest) { + + int planDiscomfort = 0; + newSchedule = null; + List possibleTaxiSchedule = new ArrayList<>(taxiSchedules.get(taxiIndex)); + + possibleTaxiSchedule.add(newRequest.getPickUpAction()); + possibleTaxiSchedule.add(newRequest.getDropOffAction()); + possibleTaxiSchedule.sort(new SortActionsByMaxTime()); + + // pairs of EarlyTime and LateTime + List timeWindows = new ArrayList<>(); + + long currentTime = timeProvider.getCurrentSimTime(); + SimulationNode firstDemandPosition = possibleTaxiSchedule.get(0).getPosition(); + + long firstTravelTime = travelTimeProvider.getTravelTime(allVehicles.get(taxiIndex), firstDemandPosition); + long firstActionMaxTime = ((PlanRequestAction) possibleTaxiSchedule.get(0)).request.getMaxPickupTime() * 1000L; + long timeAtFirstAction = currentTime + firstTravelTime; + + // if the arrival time to the first action is higher than it's maxTime -> Terminate (not feasible) + if (timeAtFirstAction >= firstActionMaxTime) { + return; + } + + // setup time windows + for (PlanAction planAction : possibleTaxiSchedule) { + timeWindows.add(new TimeWindow(timeAtFirstAction, ((PlanRequestAction) planAction).getMaxTime() * 1000L)); + } + + // for every Node: check if taxi is capable of carrying the passenger or package and whether it's possible to get to the next node + boolean personOnBoard = allVehicles.get(taxiIndex).isPassengerOnboard(); + String personOnBoardId = ""; + if (personOnBoard) { + personOnBoardId = ((DemandAgent) allVehicles.get(taxiIndex).getVehicle().getTransportedEntities().get(0)).getId(); + } + int curFreightWeight = allVehicles.get(taxiIndex).getCurrentPackagesWeight(); + final int taxiMaxCapacity = allVehicles.get(taxiIndex).getMaxPackagesCapacity(); + for (int i = 0; i < possibleTaxiSchedule.size() - 1; i++) { // "size - 1" ... the last Node of taxi has no following Node to be checked + // check for sufficient person capacity + PlanAction action = possibleTaxiSchedule.get(i); + if (action instanceof PlanActionPickup) { + // if person is on board, reject + if (personOnBoard) { + return; + } + PlanActionPickup pickAction = (PlanActionPickup) action; + PlanComputationRequest pickRequest = pickAction.request; + // if Package + // checking sufficient freight capacity + if (pickRequest instanceof PlanComputationRequestFreight) { + // if not sufficient freight capacity, reject + if (((PlanComputationRequestFreight) pickRequest).getWeight() + curFreightWeight > taxiMaxCapacity) { + return; + } + // adding the package onBoard + curFreightWeight += ((PlanComputationRequestFreight) pickRequest).getWeight(); + } + // if Agent + else { + // adding the person onBoard + personOnBoard = true; + personOnBoardId = pickRequest.getDemandEntity().getId(); + } + } + else if (action instanceof PlanActionDropoff) { + PlanActionDropoff dropAction = (PlanActionDropoff) action; + PlanComputationRequest dropRequest = dropAction.request; + + // if Agent + if (dropRequest instanceof PlanComputationRequestPeople) { + if (personOnBoard && (((PlanActionDropoff) action).request).getDemandEntity().getId().equals(personOnBoardId)) { + // remove the person from the taxi + personOnBoard = false; + personOnBoardId = ""; + } + else { + return; + } + } + // if Package + else { + if (personOnBoard) { + return; + } + else { + curFreightWeight -= ((PlanComputationRequestFreight) dropRequest).getWeight(); + } + } + } + else { + throw new NotImplementedException("PeopleFreightHeuristicSolver.trySchedule(): Action is neither pickup nor dropoff"); + } + + + TimeWindow currentTimeWindow = timeWindows.get(i); + long travelTime = travelTimeProvider.getExpectedTravelTime(possibleTaxiSchedule.get(i).getPosition(), + possibleTaxiSchedule.get(i + 1).getPosition()); + long earlyTime = currentTimeWindow.earlyTime + travelTime; + long lateTime = currentTimeWindow.lateTime + travelTime; + + // if taxi is getting to the next Node after maxTime of the Node + if (earlyTime > timeWindows.get(i + 1).lateTime) { + // not feasible -> terminate + return; + } + timeWindows.set(i + 1, new TimeWindow(Math.max(earlyTime, timeWindows.get(i + 1).earlyTime), + Math.min(lateTime, timeWindows.get(i + 1).lateTime))); + } + // planDuration = earlyTime of last time window - earlyTime of first time window + long planDuration = timeWindows.get(timeWindows.size() - 1).earlyTime - timeWindows.get(0).earlyTime; + double planCost = planCostProvider.calculatePlanCost(planDiscomfort, (int) planDuration / 1000); + + newSchedule = new ScheduleWithDuration(possibleTaxiSchedule, planDuration, planCost); + } + + + private void logRidesharingStats(List requests) { + ridesharingStats.add(new RidesharingBatchStatsPFH(requests.size(), peopleFreightHeuristicTime, 0, 0)); + } + + private boolean canServeRequest(RideSharingOnDemandVehicle vehicle, PlanComputationRequest request) { + canServeRequestCallCount++; + + // do not mess with rebalancing + if (vehicle.getState() == OnDemandVehicleState.REBALANCING) { + return false; + } + + // node identity + if (vehicle.getPosition() == request.getFrom()) { + return true; + } + + // euclidean distance check + double dist_x = vehicle.getPosition().getLatitudeProjected() - request.getFrom().getLatitudeProjected(); + double dist_y = vehicle.getPosition().getLongitudeProjected() - request.getFrom().getLongitudeProjected(); + double distanceSquared = dist_x * dist_x + dist_y * dist_y; + if (distanceSquared > maxDistanceSquared) { + return false; + } + + // real feasibility check + boolean canServe = travelTimeProvider.getTravelTime(vehicle, request.getFrom()) + < maxDelayTime; + + + return canServe; + } + + @Override + public void handleEvent(Event event) { + + } + + @Override + public EventProcessor getEventProcessor() { + return eventProcessor; + } + + + private void setEventHandeling() { + List typesToHandle = new LinkedList<>(); + typesToHandle.add(OnDemandVehicleEvent.PICKUP); + eventProcessor.addEventHandler(this, typesToHandle); + } + + @Override + public Map solve(List newRequests, + List waitingRequests) { + throw new NotImplementedException("Not implemented in People Freight Heuristic Solver class."); + } + +} diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/PFSolverMultiInsertion.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/PFSolverMultiInsertion.java new file mode 100644 index 00000000..9b3af6bb --- /dev/null +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/PFSolverMultiInsertion.java @@ -0,0 +1,473 @@ +package cz.cvut.fel.aic.simod.ridesharing.peoplefreightsheuristic; + +import com.google.inject.Inject; +import com.google.inject.Singleton; +import cz.cvut.fel.aic.agentpolis.config.AgentpolisConfig; +import cz.cvut.fel.aic.agentpolis.siminfrastructure.time.TimeProvider; +import cz.cvut.fel.aic.agentpolis.simmodel.entity.AgentPolisEntity; +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode; +import cz.cvut.fel.aic.agentpolis.utils.Benchmark; +import cz.cvut.fel.aic.agentpolis.utils.PositionUtil; +import cz.cvut.fel.aic.alite.common.event.Event; +import cz.cvut.fel.aic.alite.common.event.EventHandler; +import cz.cvut.fel.aic.alite.common.event.EventProcessor; +import cz.cvut.fel.aic.alite.common.event.typed.TypedSimulation; +import cz.cvut.fel.aic.simod.config.SimodConfig; +import cz.cvut.fel.aic.simod.entity.DemandAgent; +import cz.cvut.fel.aic.simod.entity.OnDemandVehicleState; +import cz.cvut.fel.aic.simod.entity.vehicle.OnDemandVehicle; +import cz.cvut.fel.aic.simod.event.OnDemandVehicleEvent; +import cz.cvut.fel.aic.simod.ridesharing.*; +import cz.cvut.fel.aic.simod.ridesharing.insertionheuristic.DriverPlan; +import cz.cvut.fel.aic.simod.ridesharing.model.*; +import cz.cvut.fel.aic.simod.storage.OnDemandVehicleStorage; +import cz.cvut.fel.aic.simod.traveltimecomputation.TravelTimeProvider; +import cz.cvut.fel.aic.simod.storage.OnDemandvehicleStationStorage; + +import java.lang.*; +import java.util.*; + +import org.apache.commons.lang.NotImplementedException; +import org.slf4j.LoggerFactory; + + + +@Singleton +public class PFSolverMultiInsertion extends DARPSolverPFShared implements EventHandler { + + private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(PFSolverMultiInsertion.class); + + private static final int INFO_PERIOD = 1000; + + private final PositionUtil positionUtil; + + private final SimodConfig config; + + private final double maxDistance ; + + private final double maxDistanceSquared; + + private final int maxDelayTime; + + private final TimeProvider timeProvider; + + private final TypedSimulation eventProcessor; + + private final DroppedDemandsAnalyzer droppedDemandsAnalyzer; + + private final OnDemandvehicleStationStorage onDemandvehicleStationStorage; + + + private long callCount = 0; + + private long totalTime = 0; + + private long iterationTime = 0; + + private long peopleFreightHeuristicTime; + + private volatile long canServeRequestCallCount = 0; + + private long vehiclePlanningAllCallCount = 0; + + private int failFastTime; + + private int debugFailTime; + + private double minCostIncrement; + + OnDemandVehicle vehicleFromNearestStation; + + private int[] usedVehiclesPerStation; + + long totalBenefit = 0; + + private List allVehicles; + + private List> taxiSchedules; + + List taxiCurrentPositions; + + List taxiCurrentPositionsActions; + + ScheduleWithDuration bestPlan; + + int bestPlanTaxiIndex; + + @Inject + public PFSolverMultiInsertion( + TravelTimeProvider travelTimeProvider, + PlanCostProvider travelCostProvider, + OnDemandVehicleStorage vehicleStorage, + PositionUtil positionUtil, + SimodConfig config, + TimeProvider timeProvider, + DefaultPFPlanCompRequest.DefaultPFPlanComputationRequestFactory requestFactory, + TypedSimulation eventProcessor, + DroppedDemandsAnalyzer droppedDemandsAnalyzer, + OnDemandvehicleStationStorage onDemandvehicleStationStorage, + AgentpolisConfig agentpolisConfig) { + super(vehicleStorage, travelTimeProvider, travelCostProvider, requestFactory); + this.positionUtil = positionUtil; + this.config = config; + this.timeProvider = timeProvider; + this.eventProcessor = eventProcessor; + this.droppedDemandsAnalyzer = droppedDemandsAnalyzer; + this.onDemandvehicleStationStorage = onDemandvehicleStationStorage; + this.bestPlan = null; + + + // max distance in meters between vehicle and request for the vehicle to be considered to serve the request + maxDistance = (double) config.ridesharing.maxProlongationInSeconds + * agentpolisConfig.maxVehicleSpeedInMeters; + maxDistanceSquared = maxDistance * maxDistance; + + // the traveltime from vehicle to request cannot be greater than max prolongation in milliseconds for the + // vehicle to be considered to serve the request + maxDelayTime = config.ridesharing.maxProlongationInSeconds * 1000; + + setEventHandeling(); + } + + + /** + * @param newRequestsPeople - people requests + * @param waitingRequestsPeople - not used + * @param newRequestsFreight - freight requests + * @param waitingRequestsFreight - not used + * @return list of plans for all vehicles + */ + @Override + public Map solve( + List newRequestsPeople, + List waitingRequestsPeople, + List newRequestsFreight, + List waitingRequestsFreight) { + + +// --------------------------- INIT --------------------------------------- + allVehicles = new ArrayList<>(); + taxiSchedules = new ArrayList<>(); + taxiCurrentPositions = new ArrayList<>(); + taxiCurrentPositionsActions = new ArrayList<>(); + + // statistics + peopleFreightHeuristicTime = 0; + + // initializing the vehicles and plans + for (AgentPolisEntity taxiEntity : vehicleStorage.getEntitiesForIteration()) { + PeopleFreightVehicle newTaxi = (PeopleFreightVehicle) taxiEntity; + allVehicles.add(newTaxi); + List newTaxiCurrentPlan = newTaxi.getCurrentPlanNoUpdate().plan; + + taxiCurrentPositionsActions.add((PlanActionCurrentPosition) newTaxiCurrentPlan.remove(0)); // separate the PlanActionCurrentPosition from the plan + taxiCurrentPositions.add(newTaxi.getPosition()); + taxiSchedules.add(new ArrayList<>(newTaxiCurrentPlan)); + } +// --------------------------- END INIT ------------------------------------ + + // maybe in future: calculate plan discomfort + int planDiscomfort = 0; + + + // list of plan durations for each taxi + List planDurations = new ArrayList<>(Arrays.asList(new Integer[allVehicles.size()])); + Collections.fill(planDurations, 0); + + + List newRequestsAll = new ArrayList<>(); + if (newRequestsPeople != null) { + newRequestsAll.addAll(newRequestsPeople); + } + if (newRequestsFreight != null) { + newRequestsAll.addAll(newRequestsFreight); + } + + + // sort requests incrementally by time windows (their maxPickupTime) + newRequestsAll.sort(new SortRequestsByOriginTime()); + + List availableTaxis; + + for (int i = 0; i < newRequestsAll.size(); i++) { + DefaultPFPlanCompRequest currentRequest = (DefaultPFPlanCompRequest) newRequestsAll.get(i); + // reset the bestPlan + bestPlan = new ScheduleWithDuration(null, 0, Double.MAX_VALUE); + + bestPlanTaxiIndex = -1; + + // select vehicles available at the moment + availableTaxis = new ArrayList<>(); + for (int j = 0; j < allVehicles.size(); j++) { + // first check if vehicle is in a range of maxDistance + if (!(canServeRequest(allVehicles.get(j), currentRequest))) { + continue; + } + + // if currentRequest is of type package: check if vehicle has enough space for the package + if (currentRequest instanceof PlanComputationRequestFreight) { + if (((PlanComputationRequestFreight) currentRequest).getWeight() <= allVehicles.get(j).getFreePackagesCapacity()) { + availableTaxis.add(allVehicles.get(j)); + } + } + // otherwise: check if vehicle has enough passenger capacity + else if (allVehicles.get(j).getFreeCapacity() > 0) { + availableTaxis.add(allVehicles.get(j)); + } + } + + if (availableTaxis.size() > 0) { + for (PeopleFreightVehicle currentTaxi : availableTaxis) { + // find best schedule and measure the computation time + Benchmark benchmark = new Benchmark(); + benchmark.measureTime(() -> findBestScheduleInsertion(allVehicles.indexOf(currentTaxi), currentRequest)); + peopleFreightHeuristicTime += benchmark.getDurationMsInt(); + } + + // set the bestPlan to + if (bestPlanTaxiIndex != -1 ) { + taxiSchedules.set(bestPlanTaxiIndex, bestPlan.schedule); + } + } + + } + + + Map returnMap = new HashMap<>(); + + for (int i = 0; i < taxiSchedules.size(); i++) { + List actionsList = new ArrayList<>(taxiSchedules.get(i)); + actionsList.add(0, taxiCurrentPositionsActions.get(i)); + int planTime = planDurations.get(i); + double planCost = planCostProvider.calculatePlanCost(planDiscomfort, planTime); + + DriverPlan newPlan = new DriverPlan(actionsList, planTime, planCost); + returnMap.put(allVehicles.get(i), newPlan); + } + + logRidesharingStats(newRequestsAll); + + return returnMap; + } + + + // Inserts the newRequests' actions on specified indexes of plan of taxi[taxiIndex] + // Returns feasible plan or null + private ScheduleWithDuration insertIntoPlan(int taxiIndex, PlanComputationRequest newRequest, int pickupIndex, int dropoffIndex) { + int planDiscomfort = 0; + List newTaxiSchedule = new ArrayList<>(taxiSchedules.get(taxiIndex)); + + newTaxiSchedule.add(pickupIndex, newRequest.getPickUpAction()); + newTaxiSchedule.add(dropoffIndex, newRequest.getDropOffAction()); + + // pairs of EarlyTime and LateTime + List timeWindows = new ArrayList<>(); + + long currentTime = timeProvider.getCurrentSimTime(); + SimulationNode firstDemandPosition = newTaxiSchedule.get(0).getPosition(); + + long firstTravelTime = travelTimeProvider.getTravelTime(allVehicles.get(taxiIndex), firstDemandPosition); + long firstActionMaxTime = ((PlanRequestAction) newTaxiSchedule.get(0)).request.getMaxPickupTime() * 1000L; + long timeAtFirstAction = currentTime + firstTravelTime; + + // if the arrival time to the first action is higher than it's maxTime -> Terminate (not feasible) + if (timeAtFirstAction >= firstActionMaxTime) { + return null; + } + + // setup time windows + for (PlanAction planAction : newTaxiSchedule) { + timeWindows.add(new TimeWindow(timeAtFirstAction, ((PlanRequestAction) planAction).getMaxTime() * 1000L)); + } + + int freePassengersCapacity = allVehicles.get(taxiIndex).getFreeCapacity(); + int freeFreightCapacity = allVehicles.get(taxiIndex).getFreePackagesCapacity(); + + for (int i = 0; i < newTaxiSchedule.size() - 1; i++) { + PlanAction action = newTaxiSchedule.get(i); + if (action instanceof PlanActionPickup) { + PlanActionPickup pickAction = (PlanActionPickup) action; + PlanComputationRequest pickRequest = pickAction.request; + // if Package + if (pickRequest instanceof PlanComputationRequestFreight) { + // if not sufficient freight capacity, reject + if (freeFreightCapacity - ((PlanComputationRequestFreight) pickRequest).getWeight() < 0) { + return null; + } + // adding the package onBoard + freeFreightCapacity -= ((PlanComputationRequestFreight) pickRequest).getWeight(); + } + // if Agent + else { + // if not sufficient passenger capacity, reject + if (freePassengersCapacity == 0) { + return null; + } + // else add the person onBoard + freePassengersCapacity -= 1; + } + } + else if (action instanceof PlanActionDropoff) { + PlanActionDropoff dropAction = (PlanActionDropoff) action; + PlanComputationRequest dropRequest = dropAction.request; + + // if Agent + if (dropRequest instanceof PlanComputationRequestPeople) { + // remove the person from the taxi + freePassengersCapacity += 1; + } + // if Package + else { + freeFreightCapacity += ((PlanComputationRequestFreight) dropRequest).getWeight(); + } + } + else { + throw new NotImplementedException("PeopleFreightHeuristicSolver.trySchedule(): Action is neither pickup nor dropoff"); + } + + + TimeWindow currentTimeWindow = timeWindows.get(i); + long travelTime = travelTimeProvider.getExpectedTravelTime(newTaxiSchedule.get(i).getPosition(), + newTaxiSchedule.get(i + 1).getPosition()); + long earlyTime = currentTimeWindow.earlyTime + travelTime; + long lateTime = currentTimeWindow.lateTime + travelTime; + + // if taxi is getting to the next Node after maxTime of the Node + if (earlyTime > timeWindows.get(i + 1).lateTime) { + // not feasible -> terminate + return null; + } + timeWindows.set(i + 1, new TimeWindow(Math.max(earlyTime, timeWindows.get(i + 1).earlyTime), + Math.min(lateTime, timeWindows.get(i + 1).lateTime))); + } + + long planDuration = timeWindows.get(timeWindows.size() - 1).earlyTime - timeWindows.get(0).earlyTime; + double planCost = planCostProvider.calculatePlanCost(planDiscomfort, (int) planDuration / 1000); + + return new ScheduleWithDuration(newTaxiSchedule, planDuration, planCost); + } + + // Tries to insert the new request into all possible positions in the plan of taxi[taxiIndex] + // Updates the bestPlan, if better one was found + private void findBestScheduleInsertion(int taxiIndex, PlanComputationRequest newRequest) { + ScheduleWithDuration localBestSchedule = null; + double bestLocalPlanCost = Double.MAX_VALUE; + + List currentSchedule = taxiSchedules.get(taxiIndex); + + int freePassengerCapacity = allVehicles.get(taxiIndex).getFreeCapacity(); + int freePackagesCapacity = allVehicles.get(taxiIndex).getFreePackagesCapacity(); + + for (int pickupOptionIndex = 0; pickupOptionIndex <= currentSchedule.size(); pickupOptionIndex++) { + + if (newRequest instanceof PlanComputationRequestPeople && freePassengerCapacity == 0 || + newRequest instanceof PlanComputationRequestFreight && freePackagesCapacity < ((PlanComputationRequestFreight) newRequest).getWeight()) { + continue; + } + + for (int dropoffOptionIndex = pickupOptionIndex + 1; + dropoffOptionIndex <= currentSchedule.size() + 1; dropoffOptionIndex++) + { + // try to put the new request to specified positions in plan + ScheduleWithDuration potentialSchedule = insertIntoPlan(taxiIndex, newRequest, pickupOptionIndex, dropoffOptionIndex); + if (potentialSchedule != null) { + if (potentialSchedule.planCost < bestLocalPlanCost) { + bestLocalPlanCost = potentialSchedule.planCost; + localBestSchedule = potentialSchedule; + } + } + } + + // update free capacity for next index + if (pickupOptionIndex < currentSchedule.size()) + { + // PickUp + if (currentSchedule.get(pickupOptionIndex) instanceof PlanActionPickup) + { + PlanComputationRequest request = ((PlanActionPickup) currentSchedule.get(pickupOptionIndex)).request; + if (request instanceof PlanComputationRequestPeople) { + freePassengerCapacity--; + } + else { + freePackagesCapacity -= ((PlanComputationRequestFreight) request).getWeight(); + } + } + // Dropoff + else + { + PlanComputationRequest request = ((PlanRequestAction) currentSchedule.get(pickupOptionIndex)).request; + if (request instanceof PlanComputationRequestPeople) { + freePassengerCapacity++; + } + else { + freePackagesCapacity += ((PlanComputationRequestFreight) request).getWeight(); + } + } + } + } + + // update the bestSchedule, if better one was found + if (bestLocalPlanCost < bestPlan.planCost) { + bestPlan = localBestSchedule; + bestPlanTaxiIndex = taxiIndex; + } + } + + private void logRidesharingStats(List requests) + { + ridesharingStats.add(new RidesharingBatchStatsPFH(requests.size(), peopleFreightHeuristicTime, 0, 0)); + } + + private boolean canServeRequest(RideSharingOnDemandVehicle vehicle, PlanComputationRequest request) { + canServeRequestCallCount++; + + // do not mess with rebalancing + if (vehicle.getState() == OnDemandVehicleState.REBALANCING) { + return false; + } + + // node identity + if (vehicle.getPosition() == request.getFrom()) { + return true; + } + + // euclidean distance check + double dist_x = vehicle.getPosition().getLatitudeProjected() - request.getFrom().getLatitudeProjected(); + double dist_y = vehicle.getPosition().getLongitudeProjected() - request.getFrom().getLongitudeProjected(); + double distanceSquared = dist_x * dist_x + dist_y * dist_y; + if (distanceSquared > maxDistanceSquared) { + return false; + } + + // real feasibility check + boolean canServe = travelTimeProvider.getTravelTime(vehicle, request.getFrom()) + < maxDelayTime; + + + return canServe; + } + + @Override + public void handleEvent(Event event) { + + } + + @Override + public EventProcessor getEventProcessor() { + return eventProcessor; + } + + + private void setEventHandeling() { + List typesToHandle = new LinkedList<>(); + typesToHandle.add(OnDemandVehicleEvent.PICKUP); + eventProcessor.addEventHandler(this, typesToHandle); + } + + @Override + public Map solve(List newRequests, + List waitingRequests) { + throw new NotImplementedException("Not implemented in People Freight Heuristic Solver class."); + } + +} diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/PFSolverMultipass.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/PFSolverMultipass.java new file mode 100644 index 00000000..68ed9c3f --- /dev/null +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/PFSolverMultipass.java @@ -0,0 +1,451 @@ +package cz.cvut.fel.aic.simod.ridesharing.peoplefreightsheuristic; + +import com.google.inject.Inject; +import com.google.inject.Singleton; +import cz.cvut.fel.aic.agentpolis.config.AgentpolisConfig; +import cz.cvut.fel.aic.agentpolis.siminfrastructure.time.TimeProvider; +import cz.cvut.fel.aic.agentpolis.simmodel.entity.AgentPolisEntity; +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode; +import cz.cvut.fel.aic.agentpolis.utils.Benchmark; +import cz.cvut.fel.aic.agentpolis.utils.PositionUtil; +import cz.cvut.fel.aic.alite.common.event.Event; +import cz.cvut.fel.aic.alite.common.event.EventHandler; +import cz.cvut.fel.aic.alite.common.event.EventProcessor; +import cz.cvut.fel.aic.alite.common.event.typed.TypedSimulation; +import cz.cvut.fel.aic.simod.config.SimodConfig; +import cz.cvut.fel.aic.simod.entity.vehicle.OnDemandVehicle; +import cz.cvut.fel.aic.simod.event.OnDemandVehicleEvent; +import cz.cvut.fel.aic.simod.ridesharing.*; +import cz.cvut.fel.aic.simod.ridesharing.insertionheuristic.DriverPlan; +import cz.cvut.fel.aic.simod.ridesharing.model.*; +import cz.cvut.fel.aic.simod.storage.OnDemandVehicleStorage; +import cz.cvut.fel.aic.simod.traveltimecomputation.TravelTimeProvider; +import cz.cvut.fel.aic.simod.storage.OnDemandvehicleStationStorage; + +import java.lang.*; +import java.util.*; + +import org.apache.commons.lang.NotImplementedException; +import org.slf4j.LoggerFactory; +// +///** +// * comparator for sorting Requests +// */ +//class SortRequestsByOriginTime implements Comparator { +// public int compare(PlanComputationRequest a, PlanComputationRequest b) { +// return a.getOriginTime() - b.getOriginTime(); +// } +//} +// +//class SortActionsByMaxTime implements Comparator { +// public int compare(PlanAction a, PlanAction b) { +// return ((PlanRequestAction) a).getMaxTime() - ((PlanRequestAction) b).getMaxTime(); +// } +//} +// +//// structure to store a taxi schedule and it's duration +//class ScheduleWithDuration { +// protected final List schedule; +// protected final long duration; +// +// public ScheduleWithDuration(List schedule, long duration) { +// this.schedule = schedule; +// this.duration = duration; +// } +//} +// +//class TimeWindow { +// protected long earlyTime; +// protected long lateTime; +// +// public TimeWindow(long earlyTime, long lateTime) { +// this.earlyTime = earlyTime; +// this.lateTime = lateTime; +// } +//} + + +@Singleton +public class PFSolverMultipass extends DARPSolverPFShared implements EventHandler { + + private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(PFSolverMultipass.class); + + private static final int INFO_PERIOD = 1000; + + private final PositionUtil positionUtil; + + private final SimodConfig config; + + private final double maxDistance = 10; + + private final double maxDistanceSquared = 100; + + private final int maxDelayTime = 1000; + + private final TimeProvider timeProvider; + + private final TypedSimulation eventProcessor; + + private final DroppedDemandsAnalyzer droppedDemandsAnalyzer; + + private final OnDemandvehicleStationStorage onDemandvehicleStationStorage; + + + private long callCount = 0; + + private long totalTime = 0; + + private long iterationTime = 0; + + private long peopleFreightHeuristicTime; + + private volatile long canServeRequestCallCount = 0; + + private long vehiclePlanningAllCallCount = 0; + + private int failFastTime; + + private int debugFailTime; + + private double minCostIncrement; + + OnDemandVehicle vehicleFromNearestStation; + + private int[] usedVehiclesPerStation; + + long totalBenefit = 0; + + private List allVehicles; + + private List> taxiSchedules; + + List taxiCurrentPositions; + + List taxiCurrentPositionsActions; + + ScheduleWithDuration newSchedule; + + @Inject + public PFSolverMultipass( + TravelTimeProvider travelTimeProvider, + PlanCostProvider travelCostProvider, + OnDemandVehicleStorage vehicleStorage, + PositionUtil positionUtil, + SimodConfig config, + TimeProvider timeProvider, + DefaultPFPlanCompRequest.DefaultPFPlanComputationRequestFactory requestFactory, + TypedSimulation eventProcessor, + DroppedDemandsAnalyzer droppedDemandsAnalyzer, + OnDemandvehicleStationStorage onDemandvehicleStationStorage, + AgentpolisConfig agentpolisConfig) { + super(vehicleStorage, travelTimeProvider, travelCostProvider, requestFactory); + this.positionUtil = positionUtil; + this.config = config; + this.timeProvider = timeProvider; + this.eventProcessor = eventProcessor; + this.droppedDemandsAnalyzer = droppedDemandsAnalyzer; + this.onDemandvehicleStationStorage = onDemandvehicleStationStorage; + this.newSchedule = null; + + setEventHandeling(); + + +/* + // max distance in meters between vehicle and request for the vehicle to be considered to serve the request + maxDistance = (double) config.ridesharing.maxProlongationInSeconds + * agentpolisConfig.maxVehicleSpeedInMeters; + maxDistanceSquared = maxDistance * maxDistance; + + // the traveltime from vehicle to request cannot be greater than max prolongation in milliseconds for the + // vehicle to be considered to serve the request + maxDelayTime = config.ridesharing.maxProlongationInSeconds * 1000; +*/ + + + } + + + /** + * @param newRequestsPeople - people requests + * @param waitingRequestsPeople - not used + * @param newRequestsFreight - freight requests + * @param waitingRequestsFreight - not used + * @return list of plans for all vehicles + */ + @Override + public Map solve( + List newRequestsPeople, + List waitingRequestsPeople, + List newRequestsFreight, + List waitingRequestsFreight) { + +// --------------------------- INIT --------------------------------------- + allVehicles = new ArrayList<>(); + taxiSchedules = new ArrayList<>(); + taxiCurrentPositions = new ArrayList<>(); + taxiCurrentPositionsActions = new ArrayList<>(); + + // statistics + peopleFreightHeuristicTime = 0; + + // initializing the vehicles and plans + for (AgentPolisEntity taxiEntity : vehicleStorage.getEntitiesForIteration()) { + PeopleFreightVehicle newTaxi = (PeopleFreightVehicle) taxiEntity; + allVehicles.add(newTaxi); + List newTaxiCurrentPlan = newTaxi.getCurrentPlanNoUpdate().plan; + + taxiCurrentPositionsActions.add((PlanActionCurrentPosition) newTaxiCurrentPlan.remove(0)); // separate the PlanActionCurrentPosition from the plan + taxiCurrentPositions.add(newTaxi.getPosition()); + taxiSchedules.add(new ArrayList<>(newTaxiCurrentPlan)); + } +// --------------------------- END INIT ------------------------------------ + + // maybe in future: calculate plan discomfort + int planDiscomfort = 0; + + + // list of plan durations for each taxi + List planDurations = new ArrayList<>(Arrays.asList(new Integer[allVehicles.size()])); + Collections.fill(planDurations, 0); + + + List newRequestsAll = new ArrayList<>(); + if (newRequestsPeople != null) { + newRequestsAll.addAll(newRequestsPeople); + } + if (newRequestsFreight != null) { + newRequestsAll.addAll(newRequestsFreight); + } + + + // sort requests incrementally by time windows - maxPickupTime + newRequestsAll.sort(new SortRequestsByOriginTime()); + + List availableTaxis; + + for (int i = 0; i < newRequestsAll.size(); i++) { + DefaultPFPlanCompRequest currentRequest = (DefaultPFPlanCompRequest) newRequestsAll.get(i); + + // select vehicles available at the moment + availableTaxis = new ArrayList<>(); + for (int j = 0; j < allVehicles.size(); j++) { + // if currentRequest is a package: check if vehicle has enough space for the package + if (currentRequest instanceof PlanComputationRequestFreight) { + if (((PlanComputationRequestFreight) currentRequest).getWeight() <= allVehicles.get(j).getFreePackagesCapacity()) { + availableTaxis.add(allVehicles.get(j)); + } + } + // if currentRequest is a person + else { + if (allVehicles.get(j).getFreeCapacity() > 0) { + availableTaxis.add(allVehicles.get(j)); + } + } + } + + + double lowestCostIncrease; // f_i* - best total benefit, if request i is served + int bestTaxiIdx = -1; // k* - taxi to serve request i to get the best total benefit + + if (availableTaxis.size() > 0) { + lowestCostIncrease = Double.POSITIVE_INFINITY; + for (int k = 0; k < availableTaxis.size(); k++) { + PeopleFreightVehicle currentTaxi = availableTaxis.get(k); + // current plan cost + double currentPlanCost_k = planCostProvider.calculatePlanCost(planDiscomfort, (int) (currentTaxi.getCurrentPlanNoUpdate().totalTime / 1000)); + + + + // check if schedule is feasible + Benchmark benchmark = new Benchmark(); + benchmark.measureTime(() -> trySchedule(allVehicles.indexOf(currentTaxi), currentRequest)); + peopleFreightHeuristicTime += benchmark.getDurationMsInt(); + + // if not feasible, continue to next taxi + if (newSchedule == null) { + continue; + } + + // new plan cost if taxi k serves request i + double newCost_k_i = planCostProvider.calculatePlanCost(planDiscomfort, (int) (newSchedule.duration / 1000)); + double costIncrease_k_i = newCost_k_i - currentPlanCost_k; + if (costIncrease_k_i < lowestCostIncrease) { + lowestCostIncrease = costIncrease_k_i; + bestTaxiIdx = allVehicles.indexOf(currentTaxi); // updating the idx of best taxi so far + } + } + // if suitable taxi was found + if (bestTaxiIdx != -1) { + // Insert request i into route of taxi k∗ + trySchedule(bestTaxiIdx, currentRequest); + taxiSchedules.set(bestTaxiIdx, newSchedule.schedule); // NullPointerException won't happen, because this block happens only if at least 1 taxi was found + planDurations.set(bestTaxiIdx, (int) (newSchedule.duration / 1000)); + + // update total benefit + totalBenefit += lowestCostIncrease; + } + } + // else: reject request i => DO nothing + } + + + Map returnMap = new HashMap<>(); + + for (int i = 0; i < taxiSchedules.size(); i++) { + List actionsList = new ArrayList<>(taxiSchedules.get(i)); + actionsList.add(0, taxiCurrentPositionsActions.get(i)); + int planTime = planDurations.get(i); + double planCost = planCostProvider.calculatePlanCost(planDiscomfort, planTime); + + DriverPlan newPlan = new DriverPlan(actionsList, planTime, planCost); + returnMap.put(allVehicles.get(i), newPlan); + } + + logRidesharingStats(newRequestsAll); + + return returnMap; + } + + + /** + * returns sorted list of new taxi schedule (or null if the schedule is not feasible) and duration of this schedule + */ + private void trySchedule(int taxiIndex, PlanComputationRequest newRequest) { + + int planDiscomfort = 0; + newSchedule = null; + List possibleTaxiSchedule = new ArrayList<>(taxiSchedules.get(taxiIndex)); + + possibleTaxiSchedule.add(newRequest.getPickUpAction()); + possibleTaxiSchedule.add(newRequest.getDropOffAction()); + possibleTaxiSchedule.sort(new SortActionsByMaxTime()); + + // pairs of EarlyTime and LateTime + List timeWindows = new ArrayList<>(); + + long currentTime = timeProvider.getCurrentSimTime(); + SimulationNode firstDemandPosition = possibleTaxiSchedule.get(0).getPosition(); + + long firstTravelTime = travelTimeProvider.getTravelTime(allVehicles.get(taxiIndex), firstDemandPosition); + long firstActionMaxTime = ((PlanRequestAction) possibleTaxiSchedule.get(0)).request.getMaxPickupTime() * 1000L; + long timeAtFirstAction = currentTime + firstTravelTime; + + // if the arrival time to the first action is higher than it's maxTime -> Terminate (not feasible) + if (timeAtFirstAction >= firstActionMaxTime) { + return; + } + + // setup time windows + for (PlanAction planAction : possibleTaxiSchedule) { + timeWindows.add(new TimeWindow(timeAtFirstAction, ((PlanRequestAction) planAction).getMaxTime() * 1000L)); + } + + // for every Node: check if taxi is capable of carrying the passenger or package and whether it's possible to get to the next node +// boolean personOnBoard = allVehicles.get(taxiIndex).isPassengerOnboard(); +// String personOnBoardId = ""; +// if (personOnBoard) { +// personOnBoardId = ((DemandAgent) allVehicles.get(taxiIndex).getVehicle().getTransportedEntities().get(0)).getId(); +// } + int curNumPassengers = allVehicles.get(taxiIndex).getOnBoardCount(); + final int taxiMaxPassengers = allVehicles.get(taxiIndex).getCapacity(); + int curFreightWeight = allVehicles.get(taxiIndex).getCurrentPackagesWeight(); + final int taxiMaxFreightCapacity = allVehicles.get(taxiIndex).getMaxPackagesCapacity(); + + for (int i = 0; i < possibleTaxiSchedule.size() - 1; i++) // size-1 ... the last Node of taxi has no following Node to be checked + { + PlanAction action = possibleTaxiSchedule.get(i); + if (action instanceof PlanActionPickup) { + PlanActionPickup pickAction = (PlanActionPickup) action; + PlanComputationRequest pickRequest = pickAction.request; + // if Package + // checking sufficient freight capacity + if (pickRequest instanceof PlanComputationRequestFreight) { + // if not sufficient freight capacity, reject + if (((PlanComputationRequestFreight) pickRequest).getWeight() + curFreightWeight > taxiMaxFreightCapacity) { + return; + } + // adding the package onBoard + curFreightWeight += ((PlanComputationRequestFreight) pickRequest).getWeight(); + } + // if Agent + else { + if (curNumPassengers + 1 > taxiMaxPassengers) { + return; + } + else { + // adding the person onBoard + curNumPassengers += 1; + } + } + } + else if (action instanceof PlanActionDropoff) { + PlanActionDropoff dropAction = (PlanActionDropoff) action; + PlanComputationRequest dropRequest = dropAction.request; + + // if Agent + if (dropRequest instanceof PlanComputationRequestPeople) { + // remove the person from the taxi + curNumPassengers -= 1; + } + // if Package + else { + curFreightWeight -= ((PlanComputationRequestFreight) dropRequest).getWeight(); + } + } + else { + throw new NotImplementedException("PeopleFreightHeuristicSolver.trySchedule(): Action is neither pickup nor dropoff"); + } + + + TimeWindow currentTimeWindow = timeWindows.get(i); + long travelTime = travelTimeProvider.getExpectedTravelTime(possibleTaxiSchedule.get(i).getPosition(), + possibleTaxiSchedule.get(i + 1).getPosition()); + long earlyTime = currentTimeWindow.earlyTime + travelTime; + long lateTime = currentTimeWindow.lateTime + travelTime; + + // if taxi is getting to the next Node after maxTime of the Node + if (earlyTime > timeWindows.get(i + 1).lateTime) { + // not feasible -> terminate + return; + } + timeWindows.set(i + 1, new TimeWindow(Math.max(earlyTime, timeWindows.get(i + 1).earlyTime), + Math.min(lateTime, timeWindows.get(i + 1).lateTime))); + } + // planTime = earlyTime of last time window - earlyTime of first time window + long planDuration = timeWindows.get(timeWindows.size() - 1).earlyTime - timeWindows.get(0).earlyTime; + double planCost = planCostProvider.calculatePlanCost(planDiscomfort, (int) planDuration / 1000); + + newSchedule = new ScheduleWithDuration(possibleTaxiSchedule, planDuration, planCost); + } + + + private void logRidesharingStats(List requests) { + ridesharingStats.add(new RidesharingBatchStatsPFH(requests.size(), peopleFreightHeuristicTime, 0, 0)); + } + + @Override + public void handleEvent(Event event) { + + } + + @Override + public EventProcessor getEventProcessor() { + return eventProcessor; + } + + + private void setEventHandeling() { + List typesToHandle = new LinkedList<>(); + typesToHandle.add(OnDemandVehicleEvent.PICKUP); + eventProcessor.addEventHandler(this, typesToHandle); + } + + @Override + public Map solve(List newRequests, + List waitingRequests) { + throw new NotImplementedException("Not implemented in People Freight Heuristic Solver class."); + } + +} + +// MULTI PASSENGERS SOLVER diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/PackageContent.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/PackageContent.java new file mode 100644 index 00000000..19393f07 --- /dev/null +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/PackageContent.java @@ -0,0 +1,17 @@ +package cz.cvut.fel.aic.simod.ridesharing.peoplefreightsheuristic; + +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode; +import cz.cvut.fel.aic.simod.io.TimeTrip; + +// structure for content of package in Event +public class PackageContent { + + public final TimeTrip trip; + + public final int packageWeight; + + public PackageContent(TimeTrip trip, int packageWeight) { + this.trip = trip; + this.packageWeight = packageWeight; + } +} diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/PackageLayer.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/PackageLayer.java new file mode 100644 index 00000000..f3fe684f --- /dev/null +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/PackageLayer.java @@ -0,0 +1,134 @@ +package cz.cvut.fel.aic.simod.ridesharing.peoplefreightsheuristic; + + +import com.google.inject.Inject; +import com.google.inject.Singleton; +import cz.cvut.fel.aic.agentpolis.config.AgentpolisConfig; +import cz.cvut.fel.aic.agentpolis.simmodel.entity.vehicle.Vehicle; +import cz.cvut.fel.aic.agentpolis.simulator.visualization.visio.ClickableEntityLayer; +import cz.cvut.fel.aic.agentpolis.simulator.visualization.visio.VisioUtils; +import cz.cvut.fel.aic.alite.vis.Vis; +import cz.cvut.fel.aic.simod.entity.DemandAgent; +import cz.cvut.fel.aic.simod.entity.DemandAgentState; +import cz.cvut.fel.aic.simod.storage.DemandStorage; + +import javax.vecmath.Point2d; +import java.awt.*; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +@Singleton +public class PackageLayer extends ClickableEntityLayer { + + private static final Color DEMAND_COLOR = new Color(56, 227, 0); + + private static final Color DROPPED_COLOR = new Color(22, 136, 0); + + private static final int SIZE = 1; + + private static final int TRANSFORMABLE_SIZE = 4; + + private static final Double TEXT_MARGIN_BOTTOM = 5.0; + + private static final Color TEXT_BACKGROUND_COLOR = Color.WHITE; + + + protected final Set demandsWithPrintedInfo; + + + @Inject + public PackageLayer(DemandPackageStorage packageStorage, AgentpolisConfig agentpolisConfig) { + super(packageStorage, agentpolisConfig); + demandsWithPrintedInfo = new HashSet<>(); + } + + + @Override + public void init(Vis vis) { + super.init(vis); + vis.addMouseListener(this); + } + + protected Point2d getDrivingPackagePosition(DemandPackage demandPackage) { + return positionUtil.getCanvasPositionInterpolatedForVehicle(demandPackage.getTransportingEntity()); + } + + protected Point2d getDrivingPackagePositionInTime(DemandPackage demandPackage, long time) { + return positionUtil.getCanvasPositionInterpolatedForVehicleInTime(demandPackage.getTransportingEntity(), time); + } + + protected Point2d getWaitingPackagePosition(DemandPackage demandPackage) { + return positionUtil.getCanvasPosition(demandPackage.getPosition()); + } + + @Override + protected Point2d getEntityPosition(DemandPackage demandPackage) { + if (demandPackage.getState() == DemandAgentState.DRIVING) { + return getDrivingPackagePosition(demandPackage); + } + else { + return getWaitingPackagePosition(demandPackage); + } + } + + @Override + protected Point2d getEntityPositionInTime(DemandPackage demandPackage, long time) { + if (demandPackage.getState() == DemandAgentState.DRIVING) { + return getDrivingPackagePositionInTime(demandPackage, time); + } + else { + return getWaitingPackagePosition(demandPackage); + } + } + + @Override + protected Color getEntityDrawColor(DemandPackage demandPackage) { + if (demandPackage.isDropped()) { + return DROPPED_COLOR; + } + + return DEMAND_COLOR; + } + + @Override + protected int getEntityTransformableRadius(DemandPackage demandPackage) { + return SIZE; + } + + @Override + protected double getEntityStaticRadius(DemandPackage demandPackage) { + return SIZE; + } + + @Override + protected void processClick(DemandPackage nearestEntity) { +// if(demandsWithPrintedInfo.contains(nearestEntity)){ +// demandsWithPrintedInfo.remove(nearestEntity); +// } +// else{ +// demandsWithPrintedInfo.add(nearestEntity); +// } + } + + @Override + protected void drawEntities(List demandPackages, Point2d entityPosition, Graphics2D canvas, + Dimension dim) { + super.drawEntities(demandPackages, entityPosition, canvas, dim); + if (demandsWithPrintedInfo.contains(demandPackages.get(0))) { + double radius = getRadius(demandPackages.get(0)); + + int x1 = (int) (entityPosition.getX() - radius); + int y1 = (int) (entityPosition.getY() - radius); + int x2 = (int) (entityPosition.getX() + radius); + int y2 = (int) (entityPosition.getY() + radius); + if (x2 > 0 && x1 < dim.width && y2 > 0 && y1 < dim.height) { + + VisioUtils.printTextWithBackgroud(canvas, demandPackages.get(0).getId(), + new Point((int) (x1 + TEXT_MARGIN_BOTTOM), y1 + (y2 - y1) / 2), Color.BLACK, + TEXT_BACKGROUND_COLOR); + } + } + } + +} diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/PeopleFreightVehicle.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/PeopleFreightVehicle.java new file mode 100644 index 00000000..e3cffe66 --- /dev/null +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/PeopleFreightVehicle.java @@ -0,0 +1,253 @@ +package cz.cvut.fel.aic.simod.ridesharing.peoplefreightsheuristic; + +import com.google.inject.Inject; +import com.google.inject.assistedinject.Assisted; +import cz.cvut.fel.aic.agentpolis.config.AgentpolisConfig; +import cz.cvut.fel.aic.agentpolis.siminfrastructure.planner.TripsUtil; +import cz.cvut.fel.aic.agentpolis.siminfrastructure.time.StandardTimeProvider; +import cz.cvut.fel.aic.agentpolis.simmodel.IdGenerator; +import cz.cvut.fel.aic.agentpolis.simmodel.activity.activityFactory.PhysicalVehicleDriveFactory; +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode; +import cz.cvut.fel.aic.agentpolis.simulator.visualization.visio.VisioPositionUtil; +import cz.cvut.fel.aic.alite.common.event.EventProcessor; +import cz.cvut.fel.aic.simod.StationsDispatcher; +import cz.cvut.fel.aic.simod.config.SimodConfig; +import cz.cvut.fel.aic.simod.entity.DemandEntityType; +import cz.cvut.fel.aic.simod.entity.OnDemandVehicleState; +import cz.cvut.fel.aic.simod.event.OnDemandVehicleEvent; +import cz.cvut.fel.aic.simod.event.OnDemandVehicleEventContent; +import cz.cvut.fel.aic.simod.ridesharing.RideSharingOnDemandVehicle; +import cz.cvut.fel.aic.simod.ridesharing.model.PlanActionDropoff; +import cz.cvut.fel.aic.simod.ridesharing.model.PlanActionPickup; +import cz.cvut.fel.aic.simod.ridesharing.model.PlanRequestAction; +import cz.cvut.fel.aic.simod.storage.PhysicalTransportVehicleStorage; + +import java.util.HashSet; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class PeopleFreightVehicle extends RideSharingOnDemandVehicle { + + private boolean passengerOnboard; + + private int totalSharedRequestsCount; + + private int requestsOnboardCount; + + private HashSet alreadySharedEntitiesOnboard; + + @Inject + public PeopleFreightVehicle( + PhysicalTransportVehicleStorage vehicleStorage, + TripsUtil tripsUtil, + StationsDispatcher onDemandVehicleStationsCentral, + PhysicalVehicleDriveFactory driveActivityFactory, + VisioPositionUtil positionUtil, + IdGenerator tripIdGenerator, + EventProcessor eventProcessor, + StandardTimeProvider timeProvider, + IdGenerator rebalancingIdGenerator, + SimodConfig config, + IdGenerator idGenerator, + AgentpolisConfig agentpolisConfig, + String vehicleId, + SimulationNode startPosition, + int maxParcelsCapacity, + @Assisted PhysicalPFVehicle physVehicle) { + super( + vehicleStorage, + tripsUtil, + onDemandVehicleStationsCentral, + driveActivityFactory, + positionUtil, + tripIdGenerator, + eventProcessor, + timeProvider, + rebalancingIdGenerator, + config, + idGenerator, + agentpolisConfig, + vehicleId, + startPosition, + physVehicle); + + + this.passengerOnboard = false; + this.totalSharedRequestsCount = 0; + this.requestsOnboardCount = 0; + alreadySharedEntitiesOnboard = new HashSet<>(); + } + + + public int getMaxPackagesCapacity() { + return ((PhysicalPFVehicle) vehicle).getPackagesCapacity(); + } + + public int getCurrentPackagesWeight() { + return ((PhysicalPFVehicle) vehicle).getCurrentPackagesWeight(); + } + + public int getFreePackagesCapacity() { + return ((PhysicalPFVehicle) vehicle).getPackagesCapacity() - ((PhysicalPFVehicle) vehicle).getCurrentPackagesWeight(); + } + + public boolean isPassengerOnboard() { + return passengerOnboard; + } + + public void setPassengerOnboard(boolean passengerOnboard) { + this.passengerOnboard = passengerOnboard; + } + + public int getTotalSharedRequestsCount() { + return totalSharedRequestsCount; + } + + @Override + protected void leavingStationEvent() { + eventProcessor.addEvent(OnDemandVehicleEvent.LEAVE_STATION, null, null, + new OnDemandVehicleEventContent(timeProvider.getCurrentSimTime(), + (((PlanRequestAction) currentTask).getRequest()).getDemandEntity().getSimpleId(), getId())); + } + + @Override + protected void driveToDemandStartLocation() { + // safety check that prevents request from being picked up twice because of the delayed pickup event + if (((PlanActionPickup) currentTask).request.isOnboard()) { + currentPlan.taskCompleted(); + driveToNextTask(); + } + state = OnDemandVehicleState.DRIVING_TO_START_LOCATION; + if (getPosition().id == currentTask.getPosition().id) { + pickupAndContinue(); + } + else { + currentTrip = tripsUtil.createTrip(getPosition(), currentTask.getPosition(), vehicle); +// DemandAgent demandAgent = ((PlanActionPickup) currentTask).getRequest().getDemandAgent(); + driveFactory.runActivity(this, vehicle, currentTrip); + } + } + + @Override + protected void driveToTargetLocation() { + state = OnDemandVehicleState.DRIVING_TO_TARGET_LOCATION; + if (getPosition().id == currentTask.getPosition().id) { + dropOffAndContinue(); + } + else { + currentTrip = tripsUtil.createTrip(getPosition(), currentTask.getPosition(), vehicle); + driveFactory.runActivity(this, vehicle, currentTrip); + } + } + + // returns boolean whether the only entity onboard was already counted as shared, or not + private boolean isCurrentSingleRequestOnboardShared() { + return alreadySharedEntitiesOnboard.contains( getOnlyEntityOnboardId() ); + } + + // returns Id of the only entity onboard + private String getOnlyEntityOnboardId() { + if (vehicle.getTransportedEntities().size() == 1) { + return ((TransportableDemandEntity) vehicle.getTransportedEntities().get(0)).getId(); + } + else { + return ((TransportableDemandEntity) ((PhysicalPFVehicle) vehicle).getTransportedPackages().get(0)).getId(); + } + } + + @Override + protected void pickupAndContinue() { + try { + DefaultPFPlanCompRequest request = (DefaultPFPlanCompRequest) ((PlanActionPickup) currentTask).getRequest(); + TransportableDemandEntity demandEntity = request.getDemandEntity(); + if (config.ridesharing.method.equals("pf-base") && passengerOnboard) { + throw new Exception( + String.format("Demand entity %s cannot be picked up, because passenger is onboard! Current simulation " + + "time: %s", demandEntity, timeProvider.getCurrentSimTime())); + } + + if (demandEntity.isDropped()) { + long currentTime = timeProvider.getCurrentSimTime(); + long droppTime = demandEntity.getDemandTime() + config.ridesharing.maxProlongationInSeconds * 1000; + throw new Exception( + String.format("Demand entity %s cannot be picked up, it is already dropped! Current simulation " + + "time: %s, drop time: %s", demandEntity, currentTime, droppTime)); + } + + // Statistics + if (requestsOnboardCount == 1) { + if (isCurrentSingleRequestOnboardShared()) { + totalSharedRequestsCount++; + alreadySharedEntitiesOnboard.add(demandEntity.getId()); + } + else { + totalSharedRequestsCount += 2; + alreadySharedEntitiesOnboard.add(getOnlyEntityOnboardId()); + alreadySharedEntitiesOnboard.add(demandEntity.getId()); + } + } + else if (requestsOnboardCount >= 2) { + totalSharedRequestsCount++; + alreadySharedEntitiesOnboard.add(demandEntity.getId()); + } + + demandEntity.tripStarted(this); + vehicle.pickUp(demandEntity); + requestsOnboardCount += 1; + + + DemandEntityType demandType; + if (request instanceof PlanComputationRequestPeople) { + passengerOnboard = true; + demandType = DemandEntityType.AGENT; + } + else { + demandType = DemandEntityType.PACKAGE; + } + + + eventProcessor.addEvent(OnDemandVehicleEvent.PICKUP, null, null, + new PeopleFreightVehicleEventContent(timeProvider.getCurrentSimTime(), + demandEntity.getSimpleId(), getId(), + (int) Math.round(demandEntity.getMinDemandServiceDuration() / 1000), demandType)); + currentPlan.taskCompleted(); + driveToNextTask(); + } + catch (Exception ex) { + Logger.getLogger(PhysicalPFVehicle.class.getName()).log(Level.SEVERE, null, ex); + } + } + + @Override + protected void dropOffAndContinue() { + try { + DefaultPFPlanCompRequest request = (DefaultPFPlanCompRequest) ((PlanActionDropoff) currentTask).getRequest(); + TransportableDemandEntity demandEntity = request.getDemandEntity(); + + if (config.ridesharing.method.equals("pf-base") && passengerOnboard && request instanceof PlanComputationRequestFreight) { + throw new Exception( + String.format("Demand entity %s cannot be dropped off, because passenger is onboard! Current simulation " + + "time: %s", demandEntity, timeProvider.getCurrentSimTime())); + } + alreadySharedEntitiesOnboard.remove(demandEntity.getId()); + + demandEntity.tripEnded(); + vehicle.dropOff(demandEntity); + requestsOnboardCount -= 1; + + + if (request instanceof PlanComputationRequestPeople) { + passengerOnboard = false; + } + + eventProcessor.addEvent(OnDemandVehicleEvent.DROP_OFF, null, null, + new OnDemandVehicleEventContent(timeProvider.getCurrentSimTime(), + demandEntity.getSimpleId(), getId())); + currentPlan.taskCompleted(); + driveToNextTask(); + } + catch (Exception ex) { + Logger.getLogger(PhysicalPFVehicle.class.getName()).log(Level.SEVERE, null, ex); + } + } +} diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/PeopleFreightVehicleEventContent.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/PeopleFreightVehicleEventContent.java new file mode 100644 index 00000000..9d8f3e67 --- /dev/null +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/PeopleFreightVehicleEventContent.java @@ -0,0 +1,19 @@ +package cz.cvut.fel.aic.simod.ridesharing.peoplefreightsheuristic; + +import cz.cvut.fel.aic.simod.entity.DemandEntityType; +import cz.cvut.fel.aic.simod.event.OnDemandVehicleEventContent; +import cz.cvut.fel.aic.simod.statistics.PickupEventContent; + +public class PeopleFreightVehicleEventContent extends PickupEventContent { + + private final DemandEntityType type; + + public PeopleFreightVehicleEventContent(long time, int demandId, String onDemandVehicleId, int demandTripLength, DemandEntityType type) { + super(time, demandId, onDemandVehicleId, demandTripLength); + this.type = type; + } + + public DemandEntityType getType() { + return type; + } +} diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/PeopleFreightVehicleFactory.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/PeopleFreightVehicleFactory.java new file mode 100644 index 00000000..01234070 --- /dev/null +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/PeopleFreightVehicleFactory.java @@ -0,0 +1,105 @@ +package cz.cvut.fel.aic.simod.ridesharing.peoplefreightsheuristic; + +import com.google.inject.Inject; +import com.google.inject.Singleton; +import cz.cvut.fel.aic.agentpolis.config.AgentpolisConfig; +import cz.cvut.fel.aic.agentpolis.siminfrastructure.planner.TripsUtil; +import cz.cvut.fel.aic.agentpolis.siminfrastructure.time.StandardTimeProvider; +import cz.cvut.fel.aic.agentpolis.simmodel.IdGenerator; +import cz.cvut.fel.aic.agentpolis.simmodel.activity.activityFactory.PhysicalVehicleDriveFactory; +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.EGraphType; +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode; +import cz.cvut.fel.aic.agentpolis.simulator.visualization.visio.VisioPositionUtil; +import cz.cvut.fel.aic.alite.common.event.EventProcessor; +import cz.cvut.fel.aic.simod.DemandSimulationEntityType; +import cz.cvut.fel.aic.simod.StationsDispatcher; +import cz.cvut.fel.aic.simod.config.SimodConfig; +import cz.cvut.fel.aic.simod.entity.vehicle.OnDemandVehicle; +import cz.cvut.fel.aic.simod.storage.PhysicalTransportVehicleStorage; + +@Singleton +public class PeopleFreightVehicleFactory implements PeopleFreightVehicleFactorySpec { + + private static final int LENGTH = 4; + + protected final TripsUtil tripsUtil; + + protected final StationsDispatcher onDemandVehicleStationsCentral; + + @Inject(optional = true) + protected final PhysicalVehicleDriveFactory driveActivityFactory = null; + + protected final VisioPositionUtil positionUtil; + + protected final EventProcessor eventProcessor; + + protected final StandardTimeProvider timeProvider; + + protected final IdGenerator rebalancingIdGenerator; + + protected final PhysicalTransportVehicleStorage vehicleStorage; + + protected final SimodConfig config; + + protected final IdGenerator idGenerator; + + protected final AgentpolisConfig agentpolisConfig; + + @Inject + public PeopleFreightVehicleFactory( + PhysicalTransportVehicleStorage vehicleStorage, + TripsUtil tripsUtil, + StationsDispatcher onDemandVehicleStationsCentral, + VisioPositionUtil positionUtil, + EventProcessor eventProcessor, + StandardTimeProvider timeProvider, + IdGenerator rebalancingIdGenerator, + SimodConfig config, + IdGenerator idGenerator, + AgentpolisConfig agentpolisConfig) { + this.tripsUtil = tripsUtil; + this.onDemandVehicleStationsCentral = onDemandVehicleStationsCentral; + this.positionUtil = positionUtil; + this.eventProcessor = eventProcessor; + this.timeProvider = timeProvider; + this.rebalancingIdGenerator = rebalancingIdGenerator; + this.vehicleStorage = vehicleStorage; + this.config = config; + this.idGenerator = idGenerator; + this.agentpolisConfig = agentpolisConfig; + } + + public OnDemandVehicle create(String vehicleId, SimulationNode startPosition, int packagesCapacity) { + return new PeopleFreightVehicle( + vehicleStorage, + tripsUtil, + onDemandVehicleStationsCentral, + driveActivityFactory, + positionUtil, + rebalancingIdGenerator, + eventProcessor, + timeProvider, + rebalancingIdGenerator, + config, + idGenerator, + agentpolisConfig, + vehicleId, + startPosition, + packagesCapacity, + new PhysicalPFVehicle( + vehicleId, + DemandSimulationEntityType.VEHICLE, + LENGTH, + packagesCapacity, + EGraphType.HIGHWAY, + startPosition, + agentpolisConfig.maxVehicleSpeedInMeters)); + } + + @Override + public OnDemandVehicle create(String vehicleId, SimulationNode startPosition) { + return null; + } +} + + diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/PeopleFreightVehicleFactorySpec.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/PeopleFreightVehicleFactorySpec.java new file mode 100644 index 00000000..aec28f51 --- /dev/null +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/PeopleFreightVehicleFactorySpec.java @@ -0,0 +1,9 @@ +package cz.cvut.fel.aic.simod.ridesharing.peoplefreightsheuristic; + +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode; +import cz.cvut.fel.aic.simod.entity.vehicle.OnDemandVehicle; +import cz.cvut.fel.aic.simod.entity.vehicle.OnDemandVehicleFactorySpec; + +public interface PeopleFreightVehicleFactorySpec extends OnDemandVehicleFactorySpec { + public OnDemandVehicle create(String vehicleId, SimulationNode startPosition, int packagesCapacity); +} diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/PhysicalPFVehicle.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/PhysicalPFVehicle.java new file mode 100644 index 00000000..dadb88d9 --- /dev/null +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/PhysicalPFVehicle.java @@ -0,0 +1,144 @@ +package cz.cvut.fel.aic.simod.ridesharing.peoplefreightsheuristic; + +import com.google.inject.Inject; +import cz.cvut.fel.aic.agentpolis.simmodel.agent.TransportEntity; +import cz.cvut.fel.aic.agentpolis.simmodel.entity.EntityType; + +import cz.cvut.fel.aic.agentpolis.simmodel.entity.TransportableEntity; +import cz.cvut.fel.aic.agentpolis.simmodel.entity.vehicle.PhysicalTransportVehicle; +import cz.cvut.fel.aic.agentpolis.simmodel.entity.vehicle.PickUp; +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.GraphType; +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode; +import cz.cvut.fel.aic.simod.entity.DemandAgent; + +import java.util.*; + +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; + + +public class PhysicalPFVehicle extends PhysicalTransportVehicle implements TransportEntity +{ + // the vehiclePassengerCapacity is always 1 for PF vehicles + private static final int vehiclePassengerCapacity = 4; + + protected final List transportedPackages; + private final int vehiclePackagesCapacity; + private int currentPackagesWeight; + + + public PhysicalPFVehicle( + String vehicleId, + EntityType type, + float lengthInMeters, + int vehiclePackagesCapacity, + GraphType usingGraphTypeForMoving, + SimulationNode position, + int maxVelocity) + { + super(vehicleId, type, lengthInMeters, vehiclePassengerCapacity, usingGraphTypeForMoving, position, maxVelocity); + + transportedPackages = new ArrayList<>(); + this.vehiclePackagesCapacity = vehiclePackagesCapacity; + } + + // implements pickUp() for both Agents and Packages + public void pickUp(TransportableEntity entity) { + if (entity instanceof DemandAgent) { + PickUp.pickUp(entity, this.transportedEntities.size() == vehiclePassengerCapacity, this , this.transportedEntities); + } + else { + int newParcelsWeight = getCurrentPackagesWeight() + ((DemandPackage) entity).getWeight(); + if (newParcelsWeight > vehiclePackagesCapacity) { + + } + + PickUp.pickUp(entity, newParcelsWeight > vehiclePackagesCapacity, this, this.transportedPackages); + + updateCurrentPackagesWeight(newParcelsWeight); + } + } + + @Override + public void dropOff(TransportableEntity entityToDropOff) { + boolean success; + // if entity is Agent + if (entityToDropOff instanceof DemandAgent) { + success = this.transportedEntities.remove(entityToDropOff); + } + // if entity is Package + else { + success = this.transportedPackages.remove(entityToDropOff); + } + + if (!success) { + try { + throw new Exception(String.format("Cannot drop off entity, it is not transported! [%s]", entityToDropOff)); + } catch (Exception var4) { + Logger.getLogger(PhysicalTransportVehicle.class.getName()).log(Level.SEVERE, null, var4); + } + } + + entityToDropOff.setTransportingEntity(null); + if (entityToDropOff instanceof DemandPackage) { + int newParcelsWeight = getCurrentPackagesWeight() - ((DemandPackage) entityToDropOff).getWeight(); + updateCurrentPackagesWeight(newParcelsWeight); + } + } + + + public List getTransportedPackages(){ + return this.transportedPackages; + } + + public int getPassengerCapacity() + { + // the vehiclePassengerCapacity is always 1 for PF vehicles + return vehiclePassengerCapacity; + } + + public int getPackagesCapacity() + { + return this.vehiclePackagesCapacity; + } + + public int getCurrentPackagesWeight() { + return currentPackagesWeight; + } + + // TODO maybe the exception is not necessary + private void updateCurrentPackagesWeight(int newPackagesWeight) { + try { + if (newPackagesWeight > vehiclePackagesCapacity) { + throw new Exception( + String.format("Vehicle %s cannot carry packages of weight %d - vehicle capacity is %d", + this, newPackagesWeight, vehiclePackagesCapacity)); + } + else { + this.currentPackagesWeight = newPackagesWeight; + } + } + catch (Exception ex) { + Logger.getLogger(PhysicalPFVehicle.class.getName()).log(Level.SEVERE, null, ex); + } + } + + public boolean isHighlited() + { + return super.isHighlited(); + } + + public void setHighlited(boolean highlited) + { + super.setHighlited(highlited); + } + + @Override + public void setPosition(SimulationNode position) { + super.setPosition(position); + for (TransportableEntity transportedPackage : transportedPackages) { + transportedPackage.setPosition(position); + } + } +} diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/PlanComputationRequestFreight.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/PlanComputationRequestFreight.java new file mode 100644 index 00000000..6cac272d --- /dev/null +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/PlanComputationRequestFreight.java @@ -0,0 +1,33 @@ +package cz.cvut.fel.aic.simod.ridesharing.peoplefreightsheuristic; + +import com.google.inject.Inject; +import com.google.inject.assistedinject.Assisted; +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode; +import cz.cvut.fel.aic.simod.config.SimodConfig; +import cz.cvut.fel.aic.simod.traveltimecomputation.TravelTimeProvider; + +public class PlanComputationRequestFreight extends DefaultPFPlanCompRequest +{ + private final int weight; + + @Inject + public PlanComputationRequestFreight(TravelTimeProvider travelTimeProvider, @Assisted("id") int id, + SimodConfig SimodConfig, @Assisted("origin") SimulationNode origin, + @Assisted("destination") SimulationNode destination, @Assisted TransportableDemandEntity demandEntity, + @Assisted("weight") int weight) + { + super(travelTimeProvider, id, SimodConfig, origin, destination, demandEntity); + this.weight = weight; + } + + public int getWeight() + { + return weight; + } + + public interface PlanComputationRequestFreightFactory { + public PlanComputationRequestFreight create(@Assisted("id") int id, @Assisted("origin") SimulationNode origin, + @Assisted("destination") SimulationNode destination, + @Assisted TransportableDemandEntity demandEntity, @Assisted("weight") int weight); + } +} \ No newline at end of file diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/PlanComputationRequestPeople.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/PlanComputationRequestPeople.java new file mode 100644 index 00000000..d7cdf017 --- /dev/null +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/PlanComputationRequestPeople.java @@ -0,0 +1,25 @@ + +package cz.cvut.fel.aic.simod.ridesharing.peoplefreightsheuristic; + +import com.google.inject.Inject; +import com.google.inject.assistedinject.Assisted; +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode; +import cz.cvut.fel.aic.simod.config.SimodConfig; +import cz.cvut.fel.aic.simod.traveltimecomputation.TravelTimeProvider; + +public class PlanComputationRequestPeople extends DefaultPFPlanCompRequest +{ + @Inject + public PlanComputationRequestPeople(TravelTimeProvider travelTimeProvider, @Assisted("id") int id, + SimodConfig SimodConfig, @Assisted("origin") SimulationNode origin, + @Assisted("destination") SimulationNode destination, @Assisted TransportableDemandEntity demandEntity) + { + super(travelTimeProvider, id, SimodConfig, origin, destination, demandEntity); + } + + public interface PlanComputationRequestPeopleFactory { + public PlanComputationRequestPeople create (@Assisted("id") int id, @Assisted("origin") SimulationNode origin, + @Assisted("destination") SimulationNode destination, + @Assisted TransportableDemandEntity demandEntity); + } +} diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/ResultPF.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/ResultPF.java new file mode 100644 index 00000000..20aa7fc3 --- /dev/null +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/ResultPF.java @@ -0,0 +1,40 @@ +package cz.cvut.fel.aic.simod.ridesharing.peoplefreightsheuristic; + +import cz.cvut.fel.aic.simod.statistics.Result; + +public class ResultPF extends Result { + + private final int totalSharedRequests; + + private final int numberPassengersDropped; + + private final int numberPackagesDropped; + + public int getTotalSharedRequests() { + return totalSharedRequests; + } + + public int getNumberPassengersDropped() { + return numberPassengersDropped; + } + + public int getNumberPackagesDropped() { + return numberPackagesDropped; + } + + + public ResultPF(long tickCount, double averageLoadTotal, int maxLoad, double averageKmWithPassenger, + double averageKmToStartLocation, double averageKmToStation, double averageKmRebalancing, + int numberOfDemandsNotServedFromNearestStation, int numberPassengersDropped, int numberPackagesDropped, int demandsCount, + int numberOfVehicles, int numberOfRebalancingDropped, long totalDistanceWithPassenger, + long totalDistanceToStartLocation, long totalDistanceToStation, long totalDistanceRebalancing, + int totalSharedRequests) { + super(tickCount, averageLoadTotal, maxLoad, averageKmWithPassenger, averageKmToStartLocation, averageKmToStation, + averageKmRebalancing, numberOfDemandsNotServedFromNearestStation, numberPassengersDropped + numberPassengersDropped, + demandsCount, numberOfVehicles, numberOfRebalancingDropped, totalDistanceWithPassenger, + totalDistanceToStartLocation, totalDistanceToStation, totalDistanceRebalancing); + this.totalSharedRequests = totalSharedRequests; + this.numberPassengersDropped = numberPassengersDropped; + this.numberPackagesDropped = numberPackagesDropped; + } +} diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/RidesharingBatchStatsPFH.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/RidesharingBatchStatsPFH.java new file mode 100644 index 00000000..cec29e2f --- /dev/null +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/RidesharingBatchStatsPFH.java @@ -0,0 +1,18 @@ +package cz.cvut.fel.aic.simod.ridesharing.peoplefreightsheuristic; + +import cz.cvut.fel.aic.simod.statistics.content.RidesharingBatchStats; + +public class RidesharingBatchStatsPFH extends RidesharingBatchStats { + public final int failFastTime; + + public final long pfhTime; + + public final int logFailTime; + + public RidesharingBatchStatsPFH(int newRequestCount, long pfhTime, int failFastTime, int logFailTime) { + super(newRequestCount); + this.pfhTime = pfhTime; + this.failFastTime = failFastTime; + this.logFailTime = logFailTime; + } +} diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/RidesharingPFDispatcher.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/RidesharingPFDispatcher.java new file mode 100644 index 00000000..022bf949 --- /dev/null +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/RidesharingPFDispatcher.java @@ -0,0 +1,284 @@ +package cz.cvut.fel.aic.simod.ridesharing.peoplefreightsheuristic; + +import com.google.inject.Inject; +import com.google.inject.Singleton; +import cz.cvut.fel.aic.agentpolis.siminfrastructure.ticker.PeriodicTicker; +import cz.cvut.fel.aic.agentpolis.siminfrastructure.time.TimeProvider; +import cz.cvut.fel.aic.agentpolis.simmodel.IdGenerator; +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode; +import cz.cvut.fel.aic.agentpolis.utils.PositionUtil; +import cz.cvut.fel.aic.alite.common.event.Event; +import cz.cvut.fel.aic.alite.common.event.typed.TypedSimulation; +import cz.cvut.fel.aic.simod.DemandData; +import cz.cvut.fel.aic.simod.config.SimodConfig; +import cz.cvut.fel.aic.simod.entity.DemandEntityType; +import cz.cvut.fel.aic.simod.event.DemandEvent; +import cz.cvut.fel.aic.simod.event.OnDemandVehicleEvent; +import cz.cvut.fel.aic.simod.event.OnDemandVehicleStationsCentralEvent; +import cz.cvut.fel.aic.simod.ridesharing.RideSharingOnDemandVehicle; +import cz.cvut.fel.aic.simod.ridesharing.RidesharingDispatcher; +import cz.cvut.fel.aic.simod.ridesharing.insertionheuristic.DriverPlan; +import cz.cvut.fel.aic.simod.ridesharing.model.PlanAction; +import cz.cvut.fel.aic.simod.ridesharing.model.PlanActionDropoff; +import cz.cvut.fel.aic.simod.ridesharing.model.PlanActionPickup; +import cz.cvut.fel.aic.simod.ridesharing.model.PlanComputationRequest; +import cz.cvut.fel.aic.simod.ridesharing.vga.VehicleGroupAssignmentSolver; +import cz.cvut.fel.aic.simod.storage.OnDemandvehicleStationStorage; + +import java.util.*; +import java.util.logging.Level; +import java.util.logging.Logger; + +@Singleton +public class RidesharingPFDispatcher extends RidesharingDispatcher { + + protected final PlanComputationRequestPeople.PlanComputationRequestPeopleFactory peopleRequestFactory; + + protected final PlanComputationRequestFreight.PlanComputationRequestFreightFactory freightRequestFactory; + + private List newRequestsPackages; + + private final LinkedHashSet waitingRequestsPackages; + + private final Map requestsMapByDemandPackages; + + private int totalSharedRequestsCount; + + @Inject + public RidesharingPFDispatcher(OnDemandvehicleStationStorage onDemandvehicleStationStorage, + TypedSimulation eventProcessor, + SimodConfig config, + DARPSolverPFShared solver, + PeriodicTicker ticker, + PlanComputationRequestPeople.PlanComputationRequestPeopleFactory peopleRequestFactory, + PlanComputationRequestFreight.PlanComputationRequestFreightFactory freightRequestFactory, + TimeProvider timeProvider, + PositionUtil positionUtil, + IdGenerator tripIdGenerator) { + super(onDemandvehicleStationStorage, eventProcessor, config, solver, ticker, null, timeProvider, positionUtil, tripIdGenerator); + + this.peopleRequestFactory = peopleRequestFactory; + this.freightRequestFactory = freightRequestFactory; + this.tripIdGenerator = tripIdGenerator; + newRequestsPackages = new ArrayList<>(); + waitingRequestsPackages = new LinkedHashSet<>(); + requestsMapByDemandPackages = new HashMap<>(); + totalSharedRequestsCount = 0; + + setEventHandeling(); + solver.setDispatcher(this); + } + + + @Override + public int getNumberOfDemandsDropped() { + return numberOfPassangersDropped + numberOfPackagesDropped; + } + + public int getNumberOfPassengersDropped() { + return numberOfPassangersDropped; + } + + public int getNumberOfPackagesDropped() { + return numberOfPackagesDropped; + } + + @Override + protected void serveDemand(SimulationNode startNode, DemandData demandData) { + SimulationNode requestStartPosition = demandData.locations[0]; + DefaultPFPlanCompRequest newRequest; + // if request is Agent + if (demandData.demandAgent != null) { + newRequest = this.peopleRequestFactory.create(requestCounter++, requestStartPosition, + demandData.locations[1], demandData.demandAgent); + waitingRequests.add(newRequest); + newRequests.add(newRequest); + requestsMapByDemandAgents.put(newRequest.getDemandEntity().getSimpleId(), newRequest); + } + // if request is Package + else { + newRequest = this.freightRequestFactory.create(requestCounter++, requestStartPosition, + demandData.locations[1], demandData.demandPackage, demandData.demandPackage.getWeight()); + waitingRequestsPackages.add(newRequest); + newRequestsPackages.add(newRequest); + requestsMapByDemandPackages.put(newRequest.getDemandEntity().getSimpleId(), newRequest); + } + } + + + @Override + protected void replan() { + int droppedDemandsThisBatch = 0; + int droppedPackageDemandsThisBatch = 0; + totalSharedRequestsCount = 0; + + // logger info + int currentTimeSec = (int) Math.round(timeProvider.getCurrentSimTime() / 1000.0); + LOGGER.info("Current sim time is: {} seconds", currentTimeSec); + LOGGER.info("No. of new requests: {}", newRequests.size() + newRequestsPackages.size()); + LOGGER.info("No. of waiting requests: {}", waitingRequests.size() + waitingRequestsPackages.size()); + + + // dropping demands that waits too long + Iterator waitingRequestIterator = waitingRequests.iterator(); + while (waitingRequestIterator.hasNext()) { + PlanComputationRequest request = waitingRequestIterator.next(); + if (request.getMaxPickupTime() + 5 < currentTimeSec) { + request.getDemandEntity().setDropped(true); + numberOfPassangersDropped++; + droppedDemandsThisBatch++; + waitingRequestIterator.remove(); + eventProcessor.addEvent(DemandEvent.LEFT, null, null, request); + LOGGER.info("Demand {} dropped", request.getId()); + } + } + LOGGER.info("Passengers dropped in this batch: {}", droppedDemandsThisBatch); + + // dropping package-demands that waits too long + Iterator waitingPackageRequestIterator = waitingRequestsPackages.iterator(); + while (waitingPackageRequestIterator.hasNext()) { + PlanComputationRequest request = waitingPackageRequestIterator.next(); + if (request.getMaxPickupTime() + 5 < currentTimeSec) { + request.getDemandEntity().setDropped(true); + numberOfPackagesDropped++; + droppedPackageDemandsThisBatch++; + waitingPackageRequestIterator.remove(); + eventProcessor.addEvent(DemandEvent.LEFT, null, null, request); + LOGGER.info("Demand {} dropped", request.getId()); + } + } + LOGGER.info("Packages dropped in this batch: {}", droppedPackageDemandsThisBatch); + + LOGGER.info("Total dropped passengers count: {}", numberOfPassangersDropped); + LOGGER.info("Total dropped packages count: {}", numberOfPackagesDropped); + + // DARP solving + DARPSolverPFShared pfSolver = (DARPSolverPFShared) solver; + long startTime = System.nanoTime(); + Map newPlans + = pfSolver.solve( + newRequests, + new ArrayList<>(waitingRequests), + newRequestsPackages, + new ArrayList<>(waitingRequestsPackages)); + long totalTime = System.nanoTime() - startTime; + darpSolverComputationalTimes.add(totalTime); + + // executing new plans + for (Map.Entry entry : newPlans.entrySet()) { + PeopleFreightVehicle vehicle = entry.getKey(); + DriverPlan plan = entry.getValue(); + if (plan.getLength() > 0) { + vehicle.replan(plan); + } + // adding shared requests count + totalSharedRequestsCount += vehicle.getTotalSharedRequestsCount(); + } + LOGGER.info("Number of shared requests: {}", totalSharedRequestsCount); + + // printing nice plans + if (false) { + for (Map.Entry entry : newPlans.entrySet()) { + RideSharingOnDemandVehicle vehicle = entry.getKey(); + DriverPlan plan = entry.getValue(); + + int pickupCount = 0; + int dropoffCount = 0; + Set positions = new HashSet<>(); + boolean positionOverlaps = false; + + for (PlanAction planAction : plan) { + if (positions.contains(planAction.getPosition())) { + positionOverlaps = true; + break; + } + positions.add(planAction.getPosition()); + if (planAction instanceof PlanActionPickup) { + pickupCount++; + } + else if (planAction instanceof PlanActionDropoff) { + dropoffCount++; + } + } + + if (!positionOverlaps && pickupCount > 1 && dropoffCount > 1) { + boolean nearby = false; + + for (SimulationNode node : positions) { + for (SimulationNode node2 : positions) { + if (node != node2) { + int distance = (int) Math.round(positionUtil.getPosition(node).distance( + positionUtil.getPosition(node2))); + if (distance < 500) { + nearby = true; + break; + } + } + if (nearby) { + break; + } + } + } + if (!nearby) { + LOGGER.info(vehicle.getId() + ": " + plan.toString()); + } + } + } + } + + // reseting new request for next iteration + newRequests = new LinkedList<>(); + newRequestsPackages = new LinkedList<>(); + } + + @Override + public void handleEvent(Event event) { + // dispatcher common events + if (event.getType() instanceof OnDemandVehicleStationsCentralEvent) { + super.handleEvent(event); + } + // pickup event + else { + OnDemandVehicleEvent eventType = (OnDemandVehicleEvent) event.getType(); + if (eventType == OnDemandVehicleEvent.PICKUP) { + PeopleFreightVehicleEventContent eventContent = (PeopleFreightVehicleEventContent) event.getContent(); + + if (eventContent.getType() == DemandEntityType.AGENT) { + PlanComputationRequest request = requestsMapByDemandAgents.get(eventContent.getDemandId()); + if (!waitingRequests.remove(request)) { + try { + throw new cz.cvut.fel.aic.amodsim.SimodException("Request picked up but it is not present in the waiting request queue!"); + } + catch (Exception ex) { + Logger.getLogger(VehicleGroupAssignmentSolver.class.getName()).log(Level.SEVERE, null, ex); + } + } + request.setOnboard(true); + } + else { + PlanComputationRequest packageRequest = requestsMapByDemandPackages.get(eventContent.getDemandId()); + if (!waitingRequestsPackages.remove(packageRequest)) { + try { + throw new cz.cvut.fel.aic.amodsim.SimodException("PackageRequest picked up but it is not present in the waiting request queue!"); + } + catch (Exception ex) { + Logger.getLogger(VehicleGroupAssignmentSolver.class.getName()).log(Level.SEVERE, null, ex); + } + } + packageRequest.setOnboard(true); + } + } + } + } + + + public PlanComputationRequest getRequest(int demandId) { // TODO mozna bude potreba upravit na PFPlanComputationRequest + return requestsMapByDemandPackages.get(demandId); + } + + protected void setEventHandeling() { + List typesToHandle = new LinkedList<>(); + typesToHandle.add(OnDemandVehicleEvent.PICKUP); + eventProcessor.addEventHandler(this, typesToHandle); + } +} diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/TransportableDemandEntity.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/TransportableDemandEntity.java new file mode 100644 index 00000000..34f0d0cd --- /dev/null +++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/peoplefreightsheuristic/TransportableDemandEntity.java @@ -0,0 +1,25 @@ +package cz.cvut.fel.aic.simod.ridesharing.peoplefreightsheuristic; + +import cz.cvut.fel.aic.agentpolis.simmodel.entity.TransportableEntity; +import cz.cvut.fel.aic.simod.entity.vehicle.OnDemandVehicleInterface; + +// interface for PeopleFreightVehicle to handle Agents and Packages +public interface TransportableDemandEntity extends TransportableEntity { + void tripStarted(OnDemandVehicleInterface vehicle); + + void tripEnded(); + + boolean isDropped(); + + void setDropped(boolean dropped); + + long getDemandTime(); + + int getSimpleId(); + + String getId(); + + String toString(); + + long getMinDemandServiceDuration(); +} diff --git a/src/main/java/cz/cvut/fel/aic/simod/statistics/Result.java b/src/main/java/cz/cvut/fel/aic/simod/statistics/Result.java index 37765757..c3f78119 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/statistics/Result.java +++ b/src/main/java/cz/cvut/fel/aic/simod/statistics/Result.java @@ -52,10 +52,8 @@ public class Result { private final long totalDistanceToStartLocation; private final long totalDistanceToStation; - - private final long totalDistanceRebalancing; - + private final long totalDistanceRebalancing; @@ -122,19 +120,14 @@ public long getTotalDistanceToStation() { public long getTotalDistanceRebalancing() { return totalDistanceRebalancing; } - - - - - - - - public Result(long tickCount, double averageLoadTotal, int maxLoad, double averageKmWithPassenger, - double averageKmToStartLocation, double averageKmToStation, double averageKmRebalancing, - int numberOfDemandsNotServedFromNearestStation, int numberOfDemandsDropped, int demandsCount, - int numberOfVehicles, int numberOfRebalancingDropped, long totalDistanceWithPassenger, - long totalDistanceToStartLocation, long totalDistanceToStation, long totalDistanceRebalancing) { + + + public Result(long tickCount, double averageLoadTotal, int maxLoad, double averageKmWithPassenger, + double averageKmToStartLocation, double averageKmToStation, double averageKmRebalancing, + int numberOfDemandsNotServedFromNearestStation, int numberOfDemandsDropped, int demandsCount, + int numberOfVehicles, int numberOfRebalancingDropped, long totalDistanceWithPassenger, + long totalDistanceToStartLocation, long totalDistanceToStation, long totalDistanceRebalancing) { this.tickCount = tickCount; this.averageLoadTotal = averageLoadTotal; this.maxLoad = maxLoad; diff --git a/src/main/java/cz/cvut/fel/aic/simod/statistics/Statistics.java b/src/main/java/cz/cvut/fel/aic/simod/statistics/Statistics.java index 1a562e7a..39063f07 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/statistics/Statistics.java +++ b/src/main/java/cz/cvut/fel/aic/simod/statistics/Statistics.java @@ -39,8 +39,8 @@ import cz.cvut.fel.aic.simod.io.Common; import cz.cvut.fel.aic.simod.ridesharing.DARPSolver; import cz.cvut.fel.aic.simod.ridesharing.RidesharingDispatcher; +import cz.cvut.fel.aic.simod.ridesharing.peoplefreightsheuristic.*; import cz.cvut.fel.aic.simod.statistics.content.RidesharingBatchStats; -import cz.cvut.fel.aic.simod.statistics.content.RidesharingBatchStatsIH; import cz.cvut.fel.aic.simod.statistics.content.RidesharingBatchStatsVGA; import cz.cvut.fel.aic.simod.storage.OnDemandVehicleStorage; import java.io.File; @@ -60,77 +60,88 @@ */ @Singleton public class Statistics extends AliteEntity implements EventHandler{ - + private static final int TRANSIT_OUTPUT_BATCH_SIZE = 1000000; - + private static final int MILLION = 1000000; - + private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(Statistics.class); - + private final EventProcessor eventProcessor; - + private final LinkedList averageEdgeLoad; - + private final Provider allEdgesLoadProvider; - + private final OnDemandVehicleStorage onDemandVehicleStorage; - + private final StationsDispatcher onDemandVehicleStationsCentral; - + private final LinkedList> allEdgesLoadHistory; - + private final HashMap>> allEdgesLoadHistoryPerState; - + private final SimodConfig config; - + private final LinkedList vehicleLeftStationToServeDemandTimes; - + private final LinkedList demandServiceStatistics; - + private LinkedList allTransit; - + private final CsvWriter transitWriter; - + private final HashMap> onDemandVehicleEvents; - + private final LinkedList tripDistances; - + private final List> vehicleOccupancy; - + + private final List> vehiclePackageOccupancy; + + private final List>> combinedPeoplePackageOccupancy; + +// private final List> noPeopleVehicleOccupancy; + +// private final List> peopleOnboardVehicleOccupancy; + private final List darpSolverComputationalTimes; - + private final DARPSolver dARPSolver; - - + + private long tickCount; - + private int maxLoad; - + private double averageKmWithPassenger; - + private double averageKmToStartLocation; - + private double averageKmToStation; - + private double averageKmRebalancing; - + private int numberOfVehicles; - + private long totalDistanceWithPassenger; - + private long totalDistanceToStartLocation; - + private long totalDistanceToStation; - + private long totalDistanceRebalancing; - - - - + + + + @Inject - public Statistics(TypedSimulation eventProcessor, Provider allEdgesLoadProvider, - OnDemandVehicleStorage onDemandVehicleStorage, - StationsDispatcher onDemandVehicleStationsCentral, SimodConfig config, DARPSolver dARPSolver) throws IOException { + public Statistics(TypedSimulation eventProcessor, + Provider allEdgesLoadProvider, + OnDemandVehicleStorage onDemandVehicleStorage, + StationsDispatcher onDemandVehicleStationsCentral, + SimodConfig config, + DARPSolver dARPSolver) throws IOException { this.eventProcessor = eventProcessor; this.allEdgesLoadProvider = allEdgesLoadProvider; this.onDemandVehicleStorage = onDemandVehicleStorage; @@ -145,6 +156,10 @@ public Statistics(TypedSimulation eventProcessor, Provider all onDemandVehicleEvents = new HashMap<>(); tripDistances = new LinkedList<>(); vehicleOccupancy = new LinkedList<>(); + vehiclePackageOccupancy = new LinkedList<>(); + combinedPeoplePackageOccupancy = new LinkedList<>(); +// noPeopleVehicleOccupancy = new LinkedList<>(); +// peopleOnboardVehicleOccupancy = new LinkedList<>(); transitWriter = new CsvWriter( Common.getFileWriter(config.statistics.transitStatisticFilePath)); darpSolverComputationalTimes = new ArrayList<>(); @@ -154,17 +169,17 @@ public Statistics(TypedSimulation eventProcessor, Provider all for(OnDemandVehicleEvent onDemandVehicleEvent : OnDemandVehicleEvent.values()){ onDemandVehicleEvents.put(onDemandVehicleEvent, new LinkedList<>()); } - + tickCount = 0; averageEdgeLoad = new LinkedList<>(); maxLoad = 0; - + eventProcessor.addEventHandler(this); init(eventProcessor); } - - - + + + public int getNumberOfVehiclsLeftStationToServeDemand(){ return onDemandVehicleEvents.get(OnDemandVehicleEvent.LEAVE_STATION).size(); } @@ -197,13 +212,13 @@ else if(event.getType() instanceof DriveEvent){ saveTransit(); } } - + } public void addDarpSolverComputationalTime(long totalTimeNano){ darpSolverComputationalTimes.add(totalTimeNano); } - + private void handleTick() { tickCount++; measure(); @@ -215,24 +230,50 @@ private void measure() { countEdgeLoadForInterval(); countVehicleOccupancyForInterval(); } - - - private void saveResult(){ + + + private int countTotalSharedRequests() { + int sharedRequestsCount = 0; + for (OnDemandVehicle vehicle : onDemandVehicleStorage) { + sharedRequestsCount += ((PeopleFreightVehicle) vehicle).getTotalSharedRequestsCount(); + } + return sharedRequestsCount; + } + + + private void saveResult() { double averageLoadTotal = countAverageEdgeLoad(); - - Result result = new Result(tickCount, averageLoadTotal, maxLoad, averageKmWithPassenger, - averageKmToStartLocation, averageKmToStation, averageKmRebalancing, - onDemandVehicleStationsCentral.getNumberOfDemandsNotServedFromNearestStation(), - onDemandVehicleStationsCentral.getNumberOfDemandsDropped(), - onDemandVehicleStationsCentral.getDemandsCount(), numberOfVehicles, - onDemandVehicleStationsCentral.getNumberOfRebalancingDropped(), totalDistanceWithPassenger, - totalDistanceToStartLocation, totalDistanceToStation, totalDistanceRebalancing); - - ObjectMapper mapper = new ObjectMapper(); - + + Result result; + if (config.packagesOn) { + int totalSharedRequests = countTotalSharedRequests(); + result = new ResultPF(tickCount, averageLoadTotal, maxLoad, averageKmWithPassenger, + averageKmToStartLocation, averageKmToStation, averageKmRebalancing, + onDemandVehicleStationsCentral.getNumberOfDemandsNotServedFromNearestStation(), + ((RidesharingPFDispatcher) onDemandVehicleStationsCentral).getNumberOfPassengersDropped(), + ((RidesharingPFDispatcher) onDemandVehicleStationsCentral).getNumberOfPackagesDropped(), + onDemandVehicleStationsCentral.getDemandsCount(), numberOfVehicles, + onDemandVehicleStationsCentral.getNumberOfRebalancingDropped(), totalDistanceWithPassenger, + totalDistanceToStartLocation, totalDistanceToStation, totalDistanceRebalancing, totalSharedRequests); + } + else { + result = new Result(tickCount, averageLoadTotal, maxLoad, averageKmWithPassenger, + averageKmToStartLocation, averageKmToStation, averageKmRebalancing, + onDemandVehicleStationsCentral.getNumberOfDemandsNotServedFromNearestStation(), + onDemandVehicleStationsCentral.getNumberOfDemandsDropped(), + onDemandVehicleStationsCentral.getDemandsCount(), numberOfVehicles, + onDemandVehicleStationsCentral.getNumberOfRebalancingDropped(), totalDistanceWithPassenger, + totalDistanceToStartLocation, totalDistanceToStation, totalDistanceRebalancing); + } + + + + ObjectMapper mapper = new ObjectMapper(); + try { mapper.writeValue(new File(config.statistics.resultFilePath), result); - } catch (IOException ex) { + } + catch (IOException ex) { LOGGER.error(null, ex); } } @@ -273,29 +314,29 @@ protected List getEventTypesToHandle() { typesToHandle.add(StatisticEvent.DEMAND_DROPPED_OFF); return typesToHandle; } - - + + @Inject private void countEdgeLoadForInterval() { EdgesLoadByState allEdgesLoad = allEdgesLoadProvider.get(); - - if(tickCount % (config.statistics.allEdgesLoadIntervalMilis + + if(tickCount % (config.statistics.allEdgesLoadIntervalMilis / config.statistics.statisticIntervalMilis) == 0){ allEdgesLoadHistory.add(allEdgesLoad.getLoadPerEdge()); - for (Map.Entry> stateEntry + for (Map.Entry> stateEntry : allEdgesLoad.getEdgeLoadsPerState().entrySet()) { OnDemandVehicleState onDemandVehicleState = stateEntry.getKey(); HashMap loadPerState = stateEntry.getValue(); allEdgesLoadHistoryPerState.get(onDemandVehicleState).add(loadPerState); } - + } - + int edgeLoadTotal = 0; - + // ArrayList test = allEdgesLoad.test; - + for (Integer edgeLoad : (Iterable) allEdgesLoad.loadsIterable) { edgeLoadTotal += edgeLoad; if(edgeLoad > maxLoad){ @@ -318,17 +359,17 @@ private void countAveragesFromAgents() { totalDistanceToStartLocation = 0; totalDistanceToStation = 0; totalDistanceRebalancing = 0; - - + + for (OnDemandVehicle onDemandVehicle : onDemandVehicleStorage) { totalDistanceWithPassenger += onDemandVehicle.getMetersWithPassenger(); totalDistanceToStartLocation += onDemandVehicle.getMetersToStartLocation(); totalDistanceToStation += onDemandVehicle.getMetersToStation(); totalDistanceRebalancing += onDemandVehicle.getMetersRebalancing(); } - + numberOfVehicles = onDemandVehicleStorage.getEntities().size(); - + averageKmWithPassenger = (double) totalDistanceWithPassenger / numberOfVehicles / 1000; averageKmToStartLocation = (double) totalDistanceToStartLocation / numberOfVehicles / 1000; averageKmToStation = (double) totalDistanceToStation / numberOfVehicles / 1000; @@ -337,25 +378,25 @@ private void countAveragesFromAgents() { private void saveAllEdgesLoadHistory() { ObjectMapper mapper = new ObjectMapper(); - + Map outputMap = new HashMap<>(); outputMap.put("ALL", allEdgesLoadHistory); - for (Map.Entry>> stateEntry + for (Map.Entry>> stateEntry : allEdgesLoadHistoryPerState.entrySet()) { outputMap.put(stateEntry.getKey().name(), stateEntry.getValue()); } - + try { mapper.writeValue(new File(config.statistics.allEdgesLoadHistoryFilePath), outputMap); } catch (IOException ex) { LOGGER.error(null, ex); } } - + private void saveTransit() { try { for (TransitRecord transit : allTransit) { - transitWriter.writeLine(Long.toString(transit.time), transit.staticId.toString(), + transitWriter.writeLine(Long.toString(transit.time), transit.staticId.toString(), Integer.toString(transit.vehicleState.ordinal())); } transitWriter.flush(); @@ -364,7 +405,7 @@ private void saveTransit() { LOGGER.error(null, ex); } } - + private void saveDistances() { try { CsvWriter writer = new CsvWriter( @@ -377,24 +418,78 @@ private void saveDistances() { LOGGER.error(null, ex); } } - + private void saveOccupancies() { try { CsvWriter writer = new CsvWriter( Common.getFileWriter(config.statistics.occupanciesFilePath)); int period = 0; - for (Map occupanciesInPeriod: vehicleOccupancy) { - for(Map.Entry entry: occupanciesInPeriod.entrySet()){ + for (Map occupanciesInPeriod : vehicleOccupancy) { + for(Map.Entry entry : occupanciesInPeriod.entrySet()){ writer.writeLine(Integer.toString(period), entry.getKey(), Integer.toString(entry.getValue())); } period++; } writer.close(); + + if (config.packagesOn) + { + // this is for overall packages occupancies + writer = new CsvWriter( + Common.getFileWriter(config.statistics.packagesOccupanciesFilePath)); + period = 0; + for (Map occupanciesInPeriod : vehiclePackageOccupancy) { + for (Map.Entry entry : occupanciesInPeriod.entrySet()) { + writer.writeLine(Integer.toString(period), entry.getKey(), Integer.toString(entry.getValue())); + } + period++; + } + writer.close(); + + // this is for combined people and packages occupancies + writer = new CsvWriter( + Common.getFileWriter(config.statistics.combinedOccupanciesFilePath)); + period = 0; + for (Map> occupanciesInPeriod : combinedPeoplePackageOccupancy) { + for (Map.Entry> entry : occupanciesInPeriod.entrySet()) { + writer.writeLine(Integer.toString(period), entry.getKey(), Integer.toString(entry.getValue().get(0)), Integer.toString(entry.getValue().get(1))); + } + period++; + } + writer.close(); + + + // this is for 0/1 person onboard packages occupancies +// writer = new CsvWriter( +// Common.getFileWriter(config.statistics.noPeopleOccupanciesFilePath)); +// period = 0; +// for (Map noPeopleOccupanciesInPeriod : noPeopleVehicleOccupancy) { +// for (Map.Entry entry : noPeopleOccupanciesInPeriod.entrySet()) { +// writer.writeLine(Integer.toString(period), entry.getKey(), Integer.toString(entry.getValue())); +// } +// period++; +// } +// writer.close(); +// +// writer = new CsvWriter( +// Common.getFileWriter(config.statistics.peopleOnboardOccupanciesFilePath)); +// period = 0; +// for (Map peopleOnboardOccupanciesInPeriod : peopleOnboardVehicleOccupancy) { +// for (Map.Entry entry : peopleOnboardOccupanciesInPeriod.entrySet()) { +// writer.writeLine(Integer.toString(period), entry.getKey(), Integer.toString(entry.getValue())); +// } +// period++; +// } +// writer.close(); + } + + + } catch (IOException ex) { LOGGER.error(null, ex); } } - + private void saveDarpSolverComputationalTimes() { List times = ((RidesharingDispatcher) onDemandVehicleStationsCentral).getDarpSolverComputationalTimes(); try { @@ -409,16 +504,16 @@ private void saveDarpSolverComputationalTimes() { LOGGER.error(null, ex); } } - + private void saveServiceStatistics() { try { CsvWriter writer = new CsvWriter( Common.getFileWriter(config.statistics.serviceFilePath)); for (DemandServiceStatistic demandServiceStatistic: demandServiceStatistics) { - writer.writeLine(Long.toString(demandServiceStatistic.getDemandTime()), - demandServiceStatistic.getDemandId(), demandServiceStatistic.getVehicleId(), - Long.toString(demandServiceStatistic.getPickupTime()), - Long.toString(demandServiceStatistic.getDropoffTime()), + writer.writeLine(Long.toString(demandServiceStatistic.getDemandTime()), + demandServiceStatistic.getDemandId(), demandServiceStatistic.getVehicleId(), + Long.toString(demandServiceStatistic.getPickupTime()), + Long.toString(demandServiceStatistic.getDropoffTime()), Long.toString(demandServiceStatistic.getMinPossibleServiceDelay())); } writer.close(); @@ -426,7 +521,7 @@ private void saveServiceStatistics() { LOGGER.error(null, ex); } } - + private void saveRidesharingStatistics() { int highestGroup = 0; if(dARPSolver.getRidesharingStats().size() < 1){ @@ -435,11 +530,11 @@ private void saveRidesharingStatistics() { try { CsvWriter writer = new CsvWriter( Common.getFileWriter(config.statistics.ridesharingFilePath)); - + // header line if(config.ridesharing.method.equals("vga")){ - - RidesharingBatchStatsVGA longestGroupStat + + RidesharingBatchStatsVGA longestGroupStat = (RidesharingBatchStatsVGA) dARPSolver.getRidesharingStats().get(0); for(RidesharingBatchStats stat: dARPSolver.getRidesharingStats()){ RidesharingBatchStatsVGA statVga = (RidesharingBatchStatsVGA) stat; @@ -447,12 +542,12 @@ private void saveRidesharingStatistics() { longestGroupStat = statVga; } } - + highestGroup = longestGroupStat.groupSizeData.length; - - List writerLine = new ArrayList(Arrays.asList("Batch", "New Request Count", "Active Request Count", + + List writerLine = new ArrayList(Arrays.asList("Batch", "New Request Count", "Active Request Count", "Group Generation Time", "Solver Time", "Solver gap")); - + for(int i = 0; i < longestGroupStat.groupSizeData.length; i++){ writerLine.add(String.format("%s Groups Count", i + 1)); writerLine.add(String.format("%s Groups Total Time", i + 1)); @@ -463,16 +558,16 @@ private void saveRidesharingStatistics() { } writer.writeLine(writerLine.toArray(new String[0])); } - else{ - writer.writeLine("Batch", "New Request Count", "Fail Fast Time", "Insertion Heuristic Time", + else{ + writer.writeLine("Batch", "New Request Count", "Fail Fast Time", "PeopleFreight Heuristic Time", "Log Fail Time"); } - + int batch = 0; for (RidesharingBatchStats ridesharingStat: dARPSolver.getRidesharingStats()) { - if(config.ridesharing.method.equals("vga")){ + if(config.ridesharing.method.equals("vga")){ RidesharingBatchStatsVGA vgaStat = (RidesharingBatchStatsVGA) ridesharingStat; - + List writerLine = new ArrayList<>(); writerLine.add(Integer.toString(batch)); writerLine.add(Integer.toString(vgaStat.newRequestCount)); @@ -480,7 +575,7 @@ private void saveRidesharingStatistics() { writerLine.add(Integer.toString(vgaStat.groupGenerationTime)); writerLine.add(Integer.toString(vgaStat.solverTime)); writerLine.add(Double.toString(vgaStat.gap)); - + for(int i = 0; i < highestGroup; i++){ if(i < vgaStat.groupSizeDataPlanExists.length){ writerLine.add(Integer.toString(vgaStat.groupSizeData[i].groupCount)); @@ -491,7 +586,7 @@ private void saveRidesharingStatistics() { writerLine.add(Integer.toString(0)); } } - + for(int i = 0; i < highestGroup; i++){ if(i < vgaStat.groupSizeDataPlanExists.length){ writerLine.add(Integer.toString(vgaStat.groupSizeDataPlanExists[i].groupCount)); @@ -502,14 +597,14 @@ private void saveRidesharingStatistics() { writerLine.add(Integer.toString(0)); } } - + writer.writeLine(writerLine.toArray(new String[writerLine.size()])); } else{ - RidesharingBatchStatsIH vgaStat = (RidesharingBatchStatsIH) ridesharingStat; - - writer.writeLine(Integer.toString(batch), Integer.toString(vgaStat.newRequestCount), - Integer.toString(vgaStat.failFastTime), Integer.toString(vgaStat.ihTime), + RidesharingBatchStatsPFH vgaStat = (RidesharingBatchStatsPFH) ridesharingStat; + + writer.writeLine(Integer.toString(batch), Integer.toString(vgaStat.newRequestCount), + Integer.toString(vgaStat.failFastTime), Long.toString(vgaStat.pfhTime), Integer.toString(vgaStat.logFailTime)); } batch++; @@ -549,7 +644,7 @@ private void saveOnDemandVehicleEvents() { filepath = config.statistics.onDemandVehicleStatistic.finishRebalancingFilePath; break; } - + try { CsvWriter writer = new CsvWriter(Common.getFileWriter(filepath)); for (OnDemandVehicleEventContent event : events) { @@ -564,13 +659,26 @@ private void saveOnDemandVehicleEvents() { private void countVehicleOccupancyForInterval() { Map occupancies = new HashMap<>(); + Map packageOccupancies = new HashMap<>(); + Map> combinedOccupancies = new HashMap<>(); + for(OnDemandVehicle onDemandVehicle: onDemandVehicleStorage){ - if(onDemandVehicle.getState() != OnDemandVehicleState.WAITING + if(onDemandVehicle.getState() != OnDemandVehicleState.WAITING && onDemandVehicle.getState() != OnDemandVehicleState.REBALANCING){ occupancies.put(onDemandVehicle.getId(), onDemandVehicle.getVehicle().getTransportedEntities().size()); + if (config.packagesOn) { + packageOccupancies.put(onDemandVehicle.getId(), ((PhysicalPFVehicle) onDemandVehicle.getVehicle()).getTransportedPackages().size()); + + List occupancyPair = new ArrayList<>(); + occupancyPair.add(onDemandVehicle.getVehicle().getTransportedEntities().size()); + occupancyPair.add( ((PhysicalPFVehicle) onDemandVehicle.getVehicle()).getTransportedPackages().size() ); + combinedOccupancies.put(onDemandVehicle.getId(), occupancyPair); + } } } vehicleOccupancy.add(occupancies); + vehiclePackageOccupancy.add(packageOccupancies); + combinedPeoplePackageOccupancy.add(combinedOccupancies); } private void handleDemandDropoff(DemandServiceStatistic demandServiceStatistic) { diff --git a/src/main/java/cz/cvut/fel/aic/simod/storage/DemandStorage.java b/src/main/java/cz/cvut/fel/aic/simod/storage/DemandStorage.java index 44d6ac14..0c0c643d 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/storage/DemandStorage.java +++ b/src/main/java/cz/cvut/fel/aic/simod/storage/DemandStorage.java @@ -19,6 +19,8 @@ package cz.cvut.fel.aic.simod.storage; import com.google.inject.Singleton; +import cz.cvut.fel.aic.agentpolis.simmodel.entity.TransportableEntity; +import cz.cvut.fel.aic.agentpolis.simmodel.entity.vehicle.PhysicalTransportVehicle; import cz.cvut.fel.aic.agentpolis.simmodel.environment.EntityStorage; import cz.cvut.fel.aic.simod.entity.DemandAgent; diff --git a/src/main/java/cz/cvut/fel/aic/simod/storage/PhysicalTransportVehicleStorage.java b/src/main/java/cz/cvut/fel/aic/simod/storage/PhysicalTransportVehicleStorage.java index 0763bbdd..9ecba25a 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/storage/PhysicalTransportVehicleStorage.java +++ b/src/main/java/cz/cvut/fel/aic/simod/storage/PhysicalTransportVehicleStorage.java @@ -21,6 +21,7 @@ import com.google.inject.Inject; import com.google.inject.Singleton; import cz.cvut.fel.aic.agentpolis.simmodel.entity.vehicle.PhysicalTransportVehicle; +import cz.cvut.fel.aic.agentpolis.simmodel.entity.vehicle.PhysicalVehicle; import cz.cvut.fel.aic.agentpolis.simmodel.environment.EntityStorage; /** @@ -28,6 +29,7 @@ * @author fido */ @Singleton + public class PhysicalTransportVehicleStorage extends EntityStorage{ @Inject diff --git a/src/main/java/cz/cvut/fel/aic/simod/traveltimecomputation/AstarTravelTimeProvider.java b/src/main/java/cz/cvut/fel/aic/simod/traveltimecomputation/AstarTravelTimeProvider.java index 80e738a5..60e7423f 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/traveltimecomputation/AstarTravelTimeProvider.java +++ b/src/main/java/cz/cvut/fel/aic/simod/traveltimecomputation/AstarTravelTimeProvider.java @@ -26,11 +26,13 @@ import cz.cvut.fel.aic.agentpolis.simmodel.MoveUtil; import cz.cvut.fel.aic.agentpolis.simmodel.entity.MovingEntity; import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.EGraphType; +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.Utils; import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationEdge; import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode; import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.networks.TransportNetworks; import cz.cvut.fel.aic.geographtools.Graph; import cz.cvut.fel.aic.geographtools.Node; +import cz.cvut.fel.aic.geographtools.util.Transformer; import java.util.Arrays; import java.util.Iterator; @@ -60,6 +62,18 @@ public AstarTravelTimeProvider( this.moveUtil = moveUtil; this.graph = transportNetworks.getGraph(EGraphType.HIGHWAY); } + + + public AstarTravelTimeProvider( + TimeProvider timeProvider, + TripsUtil tripsUtil, + Graph graph, + MoveUtil moveUtil) { + super(timeProvider); + this.tripsUtil = tripsUtil; + this.moveUtil = moveUtil; + this.graph = graph; + } @Override diff --git a/src/main/java/cz/cvut/fel/aic/simod/visio/AmodsimVisioInItializer.java b/src/main/java/cz/cvut/fel/aic/simod/visio/AmodsimVisioInItializer.java index 11020cc6..406159be 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/visio/AmodsimVisioInItializer.java +++ b/src/main/java/cz/cvut/fel/aic/simod/visio/AmodsimVisioInItializer.java @@ -36,6 +36,8 @@ import cz.cvut.fel.aic.alite.vis.VisManager; import cz.cvut.fel.aic.alite.vis.layer.VisLayer; import cz.cvut.fel.aic.alite.vis.layer.common.ColorLayer; +import cz.cvut.fel.aic.simod.ridesharing.peoplefreightsheuristic.PackageLayer; + import java.awt.Color; /** @@ -52,6 +54,8 @@ public class AmodsimVisioInItializer extends DefaultVisioInitializer{ protected final NodeIdLayer nodeIdLayer; private final DemandLayer demandLayer; + + private final PackageLayer packageLayer; private final OnDemandVehicleStationsLayer onDemandVehicleStationsLayer; @@ -91,13 +95,15 @@ public AmodsimVisioInItializer(Simulation simulation, PedestrianNetwork pedestri TrafficDensityByDirectionLayer trafficDensityByDirectionLayer, GridLayer gridLayer, MapTilesLayer mapTilesLayer, AgentpolisConfig config, LayerManagementLayer layerManagementLayer, VehicleHighlightingLayer vehicleHighlightingLayer, ScreenRecordingLayer screenRecordingLayer, - ScreenCaputreLayer screenCaputreLayer, SimpleBackgroundLayer simpleBackgroundLayer) { + ScreenCaputreLayer screenCaputreLayer, SimpleBackgroundLayer simpleBackgroundLayer, + PackageLayer packageLayer) { super(simulation, highwayNetwork, simulationControlLayer, gridLayer); this.onDemandVehicleLayer = onDemandVehicleLayer; this.trafficDensityLayer = trafficDensityLayer; this.nodeIdLayer = nodeIdLayer; this.onDemandVehicleStationsLayer = onDemandVehicleStationsLayer; this.demandLayer = demandLayer; + this.packageLayer = packageLayer; this.onDemandVehiclePlanLayer = onDemandVehiclePlanLayer; this.highwayLayer = highwayLayer; this.bufferedHighwayLayer = bufferedHighwayLayer; @@ -116,6 +122,7 @@ protected void initEntityLayers(Simulation simulation) { VisManager.registerLayer(layerManagementLayer.createManageableLayer("Stations", onDemandVehicleStationsLayer)); VisManager.registerLayer(layerManagementLayer.createManageableLayer("Vehicles", onDemandVehicleLayer)); VisManager.registerLayer(layerManagementLayer.createManageableLayer("Passangers", demandLayer)); + VisManager.registerLayer(layerManagementLayer.createManageableLayer("Packages", packageLayer)); VisManager.registerLayer(layerManagementLayer.createManageableLayer("Vehicle Plan", onDemandVehiclePlanLayer)); } diff --git a/src/main/java/cz/cvut/fel/aic/simod/visio/DemandLayer.java b/src/main/java/cz/cvut/fel/aic/simod/visio/DemandLayer.java index 0d7fc482..7fb9e518 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/visio/DemandLayer.java +++ b/src/main/java/cz/cvut/fel/aic/simod/visio/DemandLayer.java @@ -21,12 +21,17 @@ import com.google.inject.Inject; import com.google.inject.Singleton; import cz.cvut.fel.aic.agentpolis.config.AgentpolisConfig; +import cz.cvut.fel.aic.agentpolis.simmodel.agent.TransportEntity; +import cz.cvut.fel.aic.agentpolis.simmodel.entity.TransportableEntity; +import cz.cvut.fel.aic.agentpolis.simmodel.entity.vehicle.PhysicalTransportVehicle; +import cz.cvut.fel.aic.agentpolis.simmodel.entity.vehicle.Vehicle; import cz.cvut.fel.aic.agentpolis.simulator.visualization.visio.ClickableEntityLayer; import cz.cvut.fel.aic.agentpolis.simulator.visualization.visio.VisioUtils; import cz.cvut.fel.aic.alite.vis.Vis; import cz.cvut.fel.aic.simod.entity.DemandAgent; import cz.cvut.fel.aic.simod.entity.DemandAgentState; import cz.cvut.fel.aic.simod.storage.DemandStorage; + import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; @@ -37,15 +42,14 @@ import javax.vecmath.Point2d; /** - * * @author fido */ @Singleton -public class DemandLayer extends ClickableEntityLayer { +public class DemandLayer extends ClickableEntityLayer { - private static final Color DEMAND_COLOR = new Color(194, 66, 74); + private static final Color DEMAND_COLOR = new Color(222, 0, 0); - private static final Color DROPPED_COLOR = Color.MAGENTA; + private static final Color DROPPED_COLOR = new Color(82, 20, 190); private static final int SIZE = 1; @@ -56,14 +60,9 @@ public class DemandLayer extends ClickableEntityLayer { private static final Color TEXT_BACKGROUND_COLOR = Color.WHITE; - - protected final Set demandsWithPrintedInfo; - - - @Inject public DemandLayer(DemandStorage demandStorage, AgentpolisConfig agentpolisConfig) { super(demandStorage, agentpolisConfig); @@ -78,42 +77,42 @@ public void init(Vis vis) { } - protected Point2d getDrivingAgentPosition(DemandAgent demandAgent){ - return positionUtil.getCanvasPositionInterpolatedForVehicle(demandAgent.getTransportingEntity()); + protected Point2d getDrivingAgentPosition(DemandAgent demandAgent) { + return positionUtil.getCanvasPositionInterpolatedForVehicle((Vehicle) demandAgent.getTransportingEntity()); } - protected Point2d getDrivingAgentPositionInTime(DemandAgent demandAgent, long time){ - return positionUtil.getCanvasPositionInterpolatedForVehicleInTime(demandAgent.getTransportingEntity(), time); + protected Point2d getDrivingAgentPositionInTime(DemandAgent demandAgent, long time) { + return positionUtil.getCanvasPositionInterpolatedForVehicleInTime((Vehicle) demandAgent.getTransportingEntity(), time); } - protected Point2d getWaitingAgentPosition(DemandAgent demandAgent){ + protected Point2d getWaitingAgentPosition(DemandAgent demandAgent) { return positionUtil.getCanvasPosition(demandAgent.getPosition()); } @Override protected Point2d getEntityPosition(DemandAgent demandAgent) { - if(demandAgent.getState() == DemandAgentState.DRIVING){ + if (demandAgent.getState() == DemandAgentState.DRIVING) { return getDrivingAgentPosition(demandAgent); } - else{ + else { return getWaitingAgentPosition(demandAgent); } } @Override protected Point2d getEntityPositionInTime(DemandAgent demandAgent, long time) { - if(demandAgent.getState() == DemandAgentState.DRIVING){ + if (demandAgent.getState() == DemandAgentState.DRIVING) { return getDrivingAgentPositionInTime(demandAgent, time); } - else{ + else { return getWaitingAgentPosition(demandAgent); } } @Override protected Color getEntityDrawColor(DemandAgent demandAgent) { - if(demandAgent.isDropped()){ + if (demandAgent.isDropped()) { return DROPPED_COLOR; } @@ -144,7 +143,7 @@ protected void processClick(DemandAgent nearestEntity) { protected void drawEntities(List demandAgents, Point2d entityPosition, Graphics2D canvas, Dimension dim) { super.drawEntities(demandAgents, entityPosition, canvas, dim); - if(demandsWithPrintedInfo.contains(demandAgents.get(0))){ + if (demandsWithPrintedInfo.contains(demandAgents.get(0))) { double radius = getRadius(demandAgents.get(0)); int x1 = (int) (entityPosition.getX() - radius); diff --git a/src/main/java/cz/cvut/fel/aic/simod/visio/RidesharingOnDemandVehiclePlanLayer.java b/src/main/java/cz/cvut/fel/aic/simod/visio/RidesharingOnDemandVehiclePlanLayer.java index 4ff69024..4aab1d27 100644 --- a/src/main/java/cz/cvut/fel/aic/simod/visio/RidesharingOnDemandVehiclePlanLayer.java +++ b/src/main/java/cz/cvut/fel/aic/simod/visio/RidesharingOnDemandVehiclePlanLayer.java @@ -175,14 +175,13 @@ private void drawAction(Graphics2D canvas, Rectangle2D drawingRectangle, PlanReq canvas.fillOval(x1, y1, ACTION_MARKER_SIZE, ACTION_MARKER_SIZE); String textIn = task instanceof PlanActionPickup ? "P" : "D"; - String title = String.format("%s %s", textIn, task.getRequest().getDemandAgent().getSimpleId()); +// if () + String title = String.format("%s %s", textIn, task.getRequest().getDemandEntity().getSimpleId()); VisioUtils.printTextWithBackgroud(canvas, title, new Point(x1 + 15, y1 - 5), Color.BLACK, Color.WHITE); } } - - - + } diff --git a/src/main/resources/cz/cvut/fel/aic/simod/config/config.cfg b/src/main/resources/cz/cvut/fel/aic/simod/config/config.cfg index 43dd59f6..a195308b 100644 --- a/src/main/resources/cz/cvut/fel/aic/simod/config/config.cfg +++ b/src/main/resources/cz/cvut/fel/aic/simod/config/config.cfg @@ -12,8 +12,14 @@ simod_experiment_dir: $simod_data_dir: + 'experiments/' + $experiment_name + '/' map_dir: $simod_data_dir + 'maps/' +packages_on: false trips_filename: 'trips' +packages_filename: 'packages' +packages_max_delay: 0 +packages_capacity: 0 + trips_path: $simod_data_dir + $trips_filename + '.txt' +packages_path: $simod_data_dir + $packages_filename + '.txt' trips_multiplier: 3.433 #~ trips_multiplier: 1.0 @@ -38,8 +44,8 @@ vehicles_per_station: 1000 # Determines which Travel Time Provider will be used for the shortest distance computation. # Valid options are: astar, dm (Distance Matrix), euclidean, ch, tnr, tnraf. -travel_time_provider: 'astar' -#travel_time_provider: 'dm' +# travel_time_provider: 'astar' +travel_time_provider: 'dm' #travel_time_provider: 'euclidean' #travel_time_provider: 'ch' #travel_time_provider: 'tnr' @@ -161,8 +167,19 @@ statistics: finish_rebalancing_file_path: $statistics.on_demand_vehicle_statistic.dir_path + 'finish_rebalancing.csv' } trip_distances_file_path: $simod_experiment_dir + 'demand_trip_lengths.csv' + occupancies_file_name: 'vehicle_occupancy.csv' occupancies_file_path: $simod_experiment_dir + $statistics.occupancies_file_name + packages_occupancies_file_name: 'packages_occupancy.csv' + packages_occupancies_file_path: $simod_experiment_dir + $statistics.packages_occupancies_file_name + combined_occupancies_file_name: 'combined_occupancy.csv' + combined_occupancies_file_path: $simod_experiment_dir + $statistics.combined_occupancies_file_name + + no_people_occupancies_file_name: 'no_people_occupancies_file_name.csv' + no_people_occupancies_file_path: $simod_experiment_dir + $statistics.no_people_occupancies_file_name + people_onboard_occupancies_file_name: 'people_onboard_occupancies_file_name.csv' + people_onboard_occupancies_file_path: $simod_experiment_dir + $statistics.people_onboard_occupancies_file_name + darp_solver_computational_times_file_path: $simod_experiment_dir + 'darp_times.csv' ridesharing_file_name: 'ridesharing.csv' diff --git a/src/main/resources/cz/cvut/fel/aic/simod/config/config_copy.cfg b/src/main/resources/cz/cvut/fel/aic/simod/config/config_copy.cfg new file mode 100644 index 00000000..f36209c9 --- /dev/null +++ b/src/main/resources/cz/cvut/fel/aic/simod/config/config_copy.cfg @@ -0,0 +1,204 @@ +# This is master config. If you want to modify any value, use your custom config by calling the app with a path to +# the config as a first parameter. + +# change this for each experiment! +experiment_name: 'test01' + +# common data for all experiments +simod_data_dir: 'experiment_data/' + +# experiment specific data (cache, results,...) +simod_experiment_dir: $simod_data_dir: + 'experiments/' + $experiment_name + '/' + +map_dir: $simod_data_dir + 'maps/' + +trips_filename: 'trips' +packages_filename: 'packages' +packages_on: true +trips_path: $simod_data_dir + $trips_filename + '.txt' +packages_path: $simod_data_dir + $packages_filename + '.txt' +trips_multiplier: 3.433 +#~ trips_multiplier: 1.0 + + + +# 7:00 +#start_time: 25200000 +#start_time: 0 + +# 6:30 +start_time: 23400000 + +use_trip_cache: true +trip_cache_file: $simod_experiment_dir + 'trip_cache' +edges_file_path: $simod_data_dir + 'edges' +edge_pairs_file_path: $simod_data_dir + 'edge_pairs' +simplify_graph: true +distance_matrix_filepath: $simod_data_dir + 'dm.csv' +station_position_filepath: $simod_data_dir + 'station_positions.csv' +vehicles_per_station: 1000 + +# Determines which Travel Time Provider will be used for the shortest distance computation. +# Valid options are: astar, dm (Distance Matrix), euclidean, ch, tnr, tnraf. + +travel_time_provider: 'astar' +#travel_time_provider: 'dm' +#travel_time_provider: 'euclidean' +#travel_time_provider: 'ch' +#travel_time_provider: 'tnr' +#travel_time_provider: 'tnraf' + +rebalancing: +{ + on: true + + # 1 minute + period: 60 + + buffer_excess: 0.05 + buffer_shortage: 0.15 + #buffer: 0.0 +} + +ridesharing: +{ + on: true + + method: 'people-freight-heuristic' + #method: 'vga' + + discomfort_constraint: 'absolute' + #discomfort_constraint: 'relative' + + # 10 min + #max_prolongation_in_seconds: 600 + + # 4 min + max_prolongation_in_seconds: 240 + + maximum_relative_discomfort: 0.2 + + vehicle_capacity: 5 + weight_parameter: 0.0 + batch_period: 30 + + vga: + { + group_generator_log_filepath: $simod_experiment_dir + 'group_generation_log.csv' + log_plan_computational_time: true + + # group size is not limited + max_group_size: 0 + + # 10 ms limit for group generation for one vehicle + group_generation_time_limit: 10000 + + # Maximum number of trips (vehicles) that are considered in vehicle-group assignment for each request + solver_max_trips_per_request: 0 + + # 60s limit for the VGA solver + solver_time_limit: 60 + + # note that if the time limit is not used, then Gurobi will use the default mip gap which is 0.0001 + solver_min_gap: 0.0 + + export_group_data: false + + model_export_file_path: $simod_experiment_dir + 'passenger_vehicle_assignment_model.lp' + + max_optimal_group_size: 0 + + max_vehicles_per_request: 0 + + optimize_parked_vehicles: true + } + + insertion_heuristic: + { + recompute_waiting_requests: false + } +} + +# Following values need to be set correctly if you want to use the shortestpaths library to use Transit Node Routing +# or Contraction Hierarchies travel time providers. You only need to set names for the files you are going to use. +# For example if you want to use Transit Node Routing with Arc Flags, you have to set tnraf_file_name +# and mapping_file_name but you do not need to set ch_file_name and tnr_file_name. +shortestpaths: +{ + shortestpaths_data_dir: $simod_data_dir: + 'shortestpathslib/' + + # The name of the binary file containing the Contraction Hierarchy + ch_file_name: 'Prague.ch' + # The name of the binary file containing the Transit Node Routing data + tnr_file_name: 'Prague2000tnodes.tnrg' + # The name of the binary file containing the Transit Node Routing with Arc Flags data + tnraf_file_name: 'Prague2000tnodes.tgaf' + # The name of the binary file containing the mapping from the IDs used in amod to the IDs used by the library. + mapping_file_name: 'PragueMapping.xeni' + + ch_file_path: $shortestpaths.shortestpaths_data_dir + $shortestpaths.ch_file_name + tnr_file_path: $shortestpaths.shortestpaths_data_dir + $shortestpaths.tnr_file_name + tnraf_file_path: $shortestpaths.shortestpaths_data_dir + $shortestpaths.tnraf_file_name + mapping_file_path: $shortestpaths.shortestpaths_data_dir + $shortestpaths.mapping_file_name +} + +statistics: +{ + statistic_interval_milis: 60000 + result_file_name: 'result.json' + result_file_path: $simod_experiment_dir + $statistics.result_file_name + all_edges_load_interval_milis: 600000 + all_edges_load_history_file_name: 'allEdgesLoadHistory.json' + all_edges_load_history_file_path: $simod_experiment_dir + $statistics.all_edges_load_history_file_name + transit_statistic_file_path: $simod_experiment_dir + 'transit.csv' + service_file_name: 'service.csv' + service_file_path: $simod_experiment_dir + $statistics.service_file_name + on_demand_vehicle_statistic: + { + dir_path: $simod_experiment_dir + 'on_demand_vehicle_statistic/' + leave_station_file_path: $statistics.on_demand_vehicle_statistic.dir_path + 'leave_station.csv' + pickup_file_path: $statistics.on_demand_vehicle_statistic.dir_path + 'pickup.csv' + drop_off_file_path: $statistics.on_demand_vehicle_statistic.dir_path + 'drop_off.csv' + reach_nearest_station_file_path: $statistics.on_demand_vehicle_statistic.dir_path + 'reach_nearest_station.csv' + start_rebalancing_file_path: $statistics.on_demand_vehicle_statistic.dir_path + 'start_rebalancing.csv' + finish_rebalancing_file_path: $statistics.on_demand_vehicle_statistic.dir_path + 'finish_rebalancing.csv' + } + trip_distances_file_path: $simod_experiment_dir + 'demand_trip_lengths.csv' + occupancies_file_name: 'vehicle_occupancy.csv' + occupancies_file_path: $simod_experiment_dir + $statistics.occupancies_file_name + darp_solver_computational_times_file_path: $simod_experiment_dir + 'darp_times.csv' + + ridesharing_file_name: 'ridesharing.csv' + ridesharing_file_path: $simod_experiment_dir + $statistics.ridesharing_file_name + + group_data_filename: 'group_data.csv' + group_data_file_path: $simod_experiment_dir + $statistics.group_data_filename +} + +!parent +agentpolis: +{ + show_stacked_entities: true + + visio: + { + show_visio: true + } + + map_nodes_filepath: $map_dir + 'nodes.geojson' + map_edges_filepath: $map_dir + 'edges.geojson' + + # 90 min + simulation_duration: + { + days: 0 + hours: 1 + minutes: 30 + seconds: 0 + } +} + +stations: +{ + on: true +} diff --git a/src/test/java/cz/cvut/fel/aic/simod/system/TestOnDemandVehicle.java b/src/test/java/cz/cvut/fel/aic/simod/system/TestOnDemandVehicle.java index e8494980..1741313a 100644 --- a/src/test/java/cz/cvut/fel/aic/simod/system/TestOnDemandVehicle.java +++ b/src/test/java/cz/cvut/fel/aic/simod/system/TestOnDemandVehicle.java @@ -25,6 +25,7 @@ import cz.cvut.fel.aic.agentpolis.siminfrastructure.time.StandardTimeProvider; import cz.cvut.fel.aic.agentpolis.simmodel.IdGenerator; import cz.cvut.fel.aic.agentpolis.simmodel.activity.activityFactory.StandardDriveFactory; +import cz.cvut.fel.aic.agentpolis.simmodel.entity.vehicle.PhysicalTransportVehicle; import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode; import cz.cvut.fel.aic.agentpolis.simulator.visualization.visio.VisioPositionUtil; import cz.cvut.fel.aic.alite.common.event.EventProcessor; @@ -37,7 +38,7 @@ * * @author fido */ -public class TestOnDemandVehicle extends OnDemandVehicle{ +public class TestOnDemandVehicle extends OnDemandVehicle{ @Inject public TestOnDemandVehicle( @@ -54,7 +55,8 @@ public TestOnDemandVehicle( IdGenerator idGenerator, AgentpolisConfig agentpolisConfig, @Assisted String vehicleId, - @Assisted SimulationNode startPosition) { + @Assisted SimulationNode startPosition, + @Assisted V physVehicle) { super(vehicleStorage, tripsUtil, onDemandVehicleStationsCentral, @@ -67,7 +69,8 @@ public TestOnDemandVehicle( idGenerator, agentpolisConfig, vehicleId, - startPosition); + startPosition, + physVehicle); } diff --git a/src/test/java/cz/cvut/fel/aic/simod/visual/ridesharing/peoplefreightheuristic/InitTest.java b/src/test/java/cz/cvut/fel/aic/simod/visual/ridesharing/peoplefreightheuristic/InitTest.java new file mode 100644 index 00000000..52a9b7b0 --- /dev/null +++ b/src/test/java/cz/cvut/fel/aic/simod/visual/ridesharing/peoplefreightheuristic/InitTest.java @@ -0,0 +1,73 @@ +package cz.cvut.fel.aic.simod.visual.ridesharing.peoplefreightheuristic; + +import cz.cvut.fel.aic.agentpolis.config.AgentpolisConfig; +import cz.cvut.fel.aic.agentpolis.siminfrastructure.planner.TripsUtil; +import cz.cvut.fel.aic.agentpolis.siminfrastructure.time.TimeProvider; +import cz.cvut.fel.aic.agentpolis.simmodel.MoveUtil; +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.GraphType; +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.Utils; +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationEdge; +import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode; +import cz.cvut.fel.aic.agentpolis.utils.PositionUtil; +import cz.cvut.fel.aic.alite.common.event.typed.TypedSimulation; +import cz.cvut.fel.aic.geographtools.Graph; +import cz.cvut.fel.aic.geographtools.util.Transformer; +import cz.cvut.fel.aic.simod.config.SimodConfig; +import cz.cvut.fel.aic.simod.ridesharing.DroppedDemandsAnalyzer; +import cz.cvut.fel.aic.simod.ridesharing.peoplefreightsheuristic.PFSolverMultiInsertion; +import cz.cvut.fel.aic.simod.storage.*; +import cz.cvut.fel.aic.simod.traveltimecomputation.AstarTravelTimeProvider; +import org.junit.Test; + +import java.util.Map; + +public class InitTest +{ + @Test + public void run() throws Throwable + { + OnDemandVehicleStorage vehicleStorage = new OnDemandVehicleStorage(); + +// TravelTimeProvider travelTimeProvider = null; +// TimeProvider timeProvider = null; +// PlanCostProvider travelCostProvider = null; +// DefaultPlanComputationRequest.DefaultPlanComputationRequestFactory requestFactory = null; + TypedSimulation eventProcessor = new TypedSimulation(120); + SimodConfig config = new SimodConfig(); + TimeProvider timeProvider1 = new TimeProvider() { + @Override + public long getCurrentSimTime() { + return 0; + } + }; + PositionUtil positionUtil = new PositionUtil(); + TripsUtil tripsUtil = null; + Map> map = null; + int citySRID = 32618; + Transformer transformer = new Transformer(citySRID); + Graph graph = Utils.getCompleteGraph(4, transformer); + AgentpolisConfig agentpolisConfig = new AgentpolisConfig(); + MoveUtil moveUtil = new MoveUtil(agentpolisConfig); + AstarTravelTimeProvider astarTravelTimeProvider = new AstarTravelTimeProvider(timeProvider1, null, graph, moveUtil); + OnDemandvehicleStationStorage onDemandvehicleStationStorage = new OnDemandvehicleStationStorage(transformer); + DroppedDemandsAnalyzer droppedDemandsAnalyzer = null; // new DroppedDemandsAnalyzer( vehicleStorage, positionUtil, astarTravelTimeProvider, config, onDemandvehicleStationStorage, agentpolisConfig); + + + + + + PFSolverMultiInsertion solver = new PFSolverMultiInsertion( + astarTravelTimeProvider, + null, + vehicleStorage, + positionUtil, + config, + timeProvider1, + null, + eventProcessor, + droppedDemandsAnalyzer, + onDemandvehicleStationStorage, + agentpolisConfig + ); + } +} diff --git a/src/test/java/cz/cvut/fel/aic/simod/visual/ridesharing/vga/mock/TestPlanRequest.java b/src/test/java/cz/cvut/fel/aic/simod/visual/ridesharing/vga/mock/TestPlanRequest.java index 6d915189..1d3ec06a 100644 --- a/src/test/java/cz/cvut/fel/aic/simod/visual/ridesharing/vga/mock/TestPlanRequest.java +++ b/src/test/java/cz/cvut/fel/aic/simod/visual/ridesharing/vga/mock/TestPlanRequest.java @@ -24,6 +24,7 @@ import cz.cvut.fel.aic.simod.ridesharing.model.PlanActionDropoff; import cz.cvut.fel.aic.simod.ridesharing.model.PlanActionPickup; import cz.cvut.fel.aic.simod.ridesharing.model.PlanComputationRequest; +import cz.cvut.fel.aic.simod.ridesharing.peoplefreightsheuristic.TransportableDemandEntity; import cz.cvut.fel.aic.simod.traveltimecomputation.TravelTimeProvider; /** @@ -115,7 +116,7 @@ public PlanActionDropoff getDropOffAction() { } @Override - public DemandAgent getDemandAgent() { + public TransportableDemandEntity getDemandEntity() { return null; }