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