diff --git a/python/simod/demand_sample.py b/python/simod/demand_sample.py
index a4c30b06..e34bdfd8 100644
--- a/python/simod/demand_sample.py
+++ b/python/simod/demand_sample.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 math
import pandas as pd
import numpy as np
diff --git a/python/simod/resources/config.cfg b/python/simod/resources/config.cfg
index 98fa811e..6de3bca0 100644
--- a/python/simod/resources/config.cfg
+++ b/python/simod/resources/config.cfg
@@ -1,9 +1,9 @@
# common data for all experiments
-data_dir: 'C:/AIC Experiment data/VGA/'
+data_dir: '/Users/adela/Documents/bakalarka/randomdemand/'
map_dir: $data_dir + 'maps/'
-experiments_dir: 'HERE FILL THE PROJECT EXPERIMENT DIR PATH/'
+experiments_dir: '/Users/adela/Documents/bakalarka/randomdemand/experiments/test/'
rci_experiments_dir: 'HERE FILL THE PROJECT RCI EXPERIMENT DIR PATH/'
# change this for each experiment!
diff --git a/python/simod/station_positions_map.py b/python/simod/station_positions_map.py
index 2f79556a..634b3216 100644
--- a/python/simod/station_positions_map.py
+++ b/python/simod/station_positions_map.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 matplotlib
@@ -26,7 +26,7 @@
import roadmaptools.utm
import matplotlib
import matplotlib.font_manager as fm
-import amodsim.demand
+import simod.demand
from mpl_toolkits.axes_grid1.anchored_artists import AnchoredSizeBar
from matplotlib.colors import LogNorm
@@ -69,7 +69,7 @@
# map = np.random.rand(len(lon_range), len(lat_range))
# - fill heatmap
-demand_data = amodsim.demand.load(config.trips_path)
+demand_data = simod.demand.load(config.trips_path)
xlist, ylist = roadmaptools.plotting.export_nodes_for_matplotlib(demand_data[["from_lat", "from_lon"]].to_numpy())
for i, x in enumerate(xlist):
y = ylist[i]
diff --git a/python/simod/statistics/comparisons/comparison_table.py b/python/simod/statistics/comparisons/comparison_table.py
index 4568693a..6a43c153 100644
--- a/python/simod/statistics/comparisons/comparison_table.py
+++ b/python/simod/statistics/comparisons/comparison_table.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 roadmaptools.inout
@@ -25,7 +25,7 @@
from typing import List
# from scripts.printer import print_table
# from statistics.model.traffic_load import VehiclePhase
-from amodsim.statistics.traffic_density_histogram import TrafficDensityHistogram
+from simod.statistics.traffic_density_histogram import TrafficDensityHistogram
def compute_stats(result: List, histogram: TrafficDensityHistogram, load) -> List:
diff --git a/python/simod/statistics/comparisons/density_histogram_scenario_comparion.py b/python/simod/statistics/comparisons/density_histogram_scenario_comparion.py
index 811c7199..3e7d8668 100644
--- a/python/simod/statistics/comparisons/density_histogram_scenario_comparion.py
+++ b/python/simod/statistics/comparisons/density_histogram_scenario_comparion.py
@@ -17,14 +17,14 @@
# 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
import statistics.model.traffic_load as traffic_load
from matplotlib.axes import Axes
-from amodsim.statistics.traffic_density_histogram import TrafficDensityHistogram, HIGH_THRESHOLD, HISTOGRAM_SAMPLES
+from simod.statistics.traffic_density_histogram import TrafficDensityHistogram, HIGH_THRESHOLD, HISTOGRAM_SAMPLES
from statistics.model.traffic_load import VehiclePhase
diff --git a/python/simod/statistics/comparisons/occupancy_histogram_comparison.py b/python/simod/statistics/comparisons/occupancy_histogram_comparison.py
index 453a98d7..a219fbde 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
diff --git a/python/simod/statistics/comparisons/performance_comparison.py b/python/simod/statistics/comparisons/performance_comparison.py
index 9907a504..7e31a657 100644
--- a/python/simod/statistics/comparisons/performance_comparison.py
+++ b/python/simod/statistics/comparisons/performance_comparison.py
@@ -16,10 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see .
#
-from init import config
+from simod.init import config
import matplotlib.pyplot as plt
-import amodsim.statistics.model.ridesharing as ridesharing
+import simod.statistics.model.ridesharing as ridesharing
ih_capacity1_stats = ridesharing.load(config.comparison.experiment_1_dir)
diff --git a/python/simod/statistics/comparisons/sensitivity_analysis.py b/python/simod/statistics/comparisons/sensitivity_analysis.py
index 1bca887f..d407957c 100644
--- a/python/simod/statistics/comparisons/sensitivity_analysis.py
+++ b/python/simod/statistics/comparisons/sensitivity_analysis.py
@@ -16,14 +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
from typing import List, Tuple
import roadmaptools.inout
-import amodsim.statistics.model.edges as edges
-import amodsim.statistics.model.transit as transit
-import amodsim.statistics.model.ridesharing as ridesharing
-import amodsim.statistics.model.service as service
+import simod.statistics.model.edges as edges
+import simod.statistics.model.transit as transit
+import simod.statistics.model.ridesharing as ridesharing
+import simod.statistics.model.service as service
import matplotlib.pyplot as plt
delay_experiments = ["sw-vga-max_delay_3_min", "sw-vga", "sw-vga-max_delay_5_min", "sw-vga-max_delay_6_min"]
diff --git a/python/simod/statistics/comparisons/transfer_ridesharing_comparison_table.py b/python/simod/statistics/comparisons/transfer_ridesharing_comparison_table.py
new file mode 100644
index 00000000..69c6c71e
--- /dev/null
+++ b/python/simod/statistics/comparisons/transfer_ridesharing_comparison_table.py
@@ -0,0 +1,100 @@
+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(result: Dict, histogram: TrafficDensityHistogram, load, experiment_dir: str,
+ edge_data: DataFrame) -> List:
+ # km total
+ transit_data = transit.load(experiment_dir)
+ km_total_window = int(round(transit.get_total_distance(transit_data, edge_data, True) / 1000 / 100))
+ km_per_served_demand = round(km_total_window / (result["demandsCount"] - result["numberOfDemandsDropped"]), 3)
+
+ dropped_demand_count = result["numberOfDemandsDropped"]
+ demand_count_served = result["demandsCount"] - result["numberOfDemandsDropped"]
+
+ occupancies = occupancy.load(experiment_dir)
+ occupancies_in_window = occupancy.filter_window(occupancies)
+ used_cars_count = len(occupancies_in_window.vehicle_id.unique())
+
+ # 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))
+
+ transfers_count = result['transfersDone']
+
+ return [km_total_window, dropped_demand_count, used_cars_count, mean_delay, demand_count_served,
+ km_per_served_demand, transfers_count]
+
+exp_dir_1 = '/Users/adela/Documents/bakalarka/vysledky2/InsertionHeuristic/Archiv/experiments/test/'
+# exp_dir_2 = '/Users/adela/Documents/bakalarka/vysledky2/transferInsertionHeuristic/Archiv/experiments/test/'
+exp_dir_2 = '/Users/adela/Documents/bakalarka/randomdemand/experiments/test/'
+
+exp_dir_3 = '/Users/adela/Documents/bakalarka/vysledky2/taset/Archiv/experiments/test/'
+
+edges_path = '/Users/adela/Documents/bakalarka/randomdemand/maps/edges.geojson'
+loaded_edges = roadmaptools.inout.load_geojson(edges_path)
+edge_data = edges.make_data_frame(loaded_edges)
+edge_object_data = edges.load_edges_mapped_by_id(loaded_edges)
+
+results_insertion_heuristic \
+ = roadmaptools.inout.load_json(exp_dir_1 + config.statistics.result_file_name)
+results_insertion_heuristic_transfer \
+ = roadmaptools.inout.load_json(exp_dir_2 + config.statistics.result_file_name)
+results_taset \
+ = roadmaptools.inout.load_json(exp_dir_3 + config.statistics.result_file_name)
+
+loads_insertion_heuristic = traffic_load.load_all_edges_load_history(
+ exp_dir_1 + config.statistics.all_edges_load_history_file_name)
+loads_insertion_heuristic_transfer = traffic_load.load_all_edges_load_history(
+ exp_dir_2 + config.statistics.all_edges_load_history_file_name)
+loads_taset = traffic_load.load_all_edges_load_history(
+ exp_dir_3 + config.statistics.all_edges_load_history_file_name)
+
+histogram = TrafficDensityHistogram(edge_object_data)
+
+insertion_heuristic_data = compute_stats(results_insertion_heuristic, histogram, loads_insertion_heuristic["ALL"],
+ exp_dir_1, edge_data)
+insertion_heuristic_transfer_data = compute_stats(results_insertion_heuristic_transfer, histogram,
+ loads_insertion_heuristic_transfer["ALL"], exp_dir_2,
+ edge_data)
+taset_data = compute_stats(results_taset, histogram, loads_taset["ALL"],
+ exp_dir_3, edge_data)
+
+output_table = np.array([[" ", "INSERTION HEURISTIC", "INSERTION HEURISTIC TRANSFER", "GREEDY HEURISTIC TRANSFER"],
+ ["Dropped demands", insertion_heuristic_data[1], insertion_heuristic_transfer_data[1],
+ taset_data[1]],
+ ["Demands served", insertion_heuristic_data[4], insertion_heuristic_transfer_data[4],
+ taset_data[4]],
+ ["Total transfers", insertion_heuristic_data[6], insertion_heuristic_transfer_data[6],
+ taset_data[6]],
+ ["Total veh. dist. traveled (km)", insertion_heuristic_data[0],
+ insertion_heuristic_transfer_data[0], taset_data[0]],
+ ["Total veh. dist. traveled per demand served (km)", insertion_heuristic_data[5],
+ insertion_heuristic_transfer_data[5], taset_data[5]],
+ ["Used car count", insertion_heuristic_data[2], insertion_heuristic_transfer_data[2],
+ taset_data[2]],
+ ["Average delay (s)", insertion_heuristic_data[3], insertion_heuristic_transfer_data[3],
+ taset_data[3]],
+
+ ])
+
+# console results
+print("COMPARISON:")
+print()
+print_table(output_table)
\ No newline at end of file
diff --git a/python/simod/statistics/delay_percentage.py b/python/simod/statistics/delay_percentage.py
new file mode 100644
index 00000000..d6df6365
--- /dev/null
+++ b/python/simod/statistics/delay_percentage.py
@@ -0,0 +1,65 @@
+import numpy as np
+import pandas as pd
+import matplotlib.pyplot as plt
+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
+
+
+exp_dir_1 = '/Users/adela/Documents/bakalarka/vysledky2/InsertionHeuristic/Archiv/experiments/test/'
+exp_dir_2 = '/Users/adela/Documents/bakalarka/vysledky2/transferInsertionHeuristic/Archiv/experiments/test/'
+exp_dir_3 = '/Users/adela/Documents/bakalarka/vysledky2/taset/Archiv/experiments/test/'
+
+save_dir_1 = '/Users/adela/Documents/bakalarka/vysledky2/InsertionHeuristic/Archiv/img/'
+save_dir_2 = '/Users/adela/Documents/bakalarka/vysledky2/transferInsertionHeuristic/Archiv/img/'
+save_dir_3 = '/Users/adela/Documents/bakalarka/vysledky2/taset/Archiv/img/'
+
+
+# delays dataframe
+# TODO change dir
+service_stat = service.load_dataframe(exp_dir_3)
+# TODO change dir
+save_results_to = save_dir_3
+
+delays = service.get_delays(service_stat, True, False).to_frame()
+service_stat['percentage_delay'] = (service_stat['dropoff_time'] - service_stat['demand_time']) / service_stat['min_possible_delay'] - 1
+maximum = service_stat['percentage_delay'].max()
+service_stat['percentage_delay_norm'] = service_stat['percentage_delay'] / maximum
+
+new_df = service_stat.where(service_stat['percentage_delay'] > 0.0)
+new_df = new_df.dropna()
+
+bins = [0.0, 0.1, 0.2, 0.3, 0.4, 0.6, 0.8, 1 * maximum]
+
+
+bins_df = pd.cut(new_df['percentage_delay'], bins)
+print(bins_df.value_counts())
+
+t = bins_df.value_counts(sort=False)
+labels = ['< 10 %', '< 20 %', '< 30 %', '< 40 %', '< 60 %', '< 80 %', '81 % +']
+
+
+counts = t
+plt.axis('equal')
+explode = bins
+colors = ['#191970','#0038E2','#0071C6','#329A82', '#46C3A6', '#93DCCB', '#E0F5F0']
+colors2 = ['#E6F7FF', '#BAE7FF', '#91D5FF', '#69C0FF', '#1890FF', '#096DD9', '#0050B3', '#002766']
+cc = list(reversed(colors))
+counts.plot(kind='pie', fontsize=15, colors=cc, labels=t,
+ wedgeprops={"edgecolor": "black",
+ 'linewidth': 0.2,
+ 'antialiased': True}
+ )
+plt.legend(labels=labels, loc="best")
+plt.ylabel('')
+
+
+plt.savefig(save_results_to + 'delay_percentages', bbox_inches='tight', transparent=True)
+
+
+plt.show()
\ No newline at end of file
diff --git a/python/simod/statistics/demand_service.py b/python/simod/statistics/demand_service.py
index 838ce18f..482496eb 100644
--- a/python/simod/statistics/demand_service.py
+++ b/python/simod/statistics/demand_service.py
@@ -17,7 +17,8 @@
# along with this program. If not, see .
#
-from simod.init import config, roadmaptools_config
+from simod.init import config
+from roadmaptools.config import roadmaptools_config
from tqdm import tqdm
import numpy as np
diff --git a/python/simod/statistics/demand_trip_duration_histogram.py b/python/simod/statistics/demand_trip_duration_histogram.py
index 32f42f2e..eac110c7 100644
--- a/python/simod/statistics/demand_trip_duration_histogram.py
+++ b/python/simod/statistics/demand_trip_duration_histogram.py
@@ -16,12 +16,12 @@
# 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 matplotlib.pyplot as plt
from matplotlib.ticker import FuncFormatter
-from amodsim.statistics.model import demand_trips
+from simod.statistics.model import demand_trips
trips_data = demand_trips.load()
diff --git a/python/simod/statistics/fleet_utilization.py b/python/simod/statistics/fleet_utilization.py
new file mode 100644
index 00000000..ddb1c4d5
--- /dev/null
+++ b/python/simod/statistics/fleet_utilization.py
@@ -0,0 +1,85 @@
+
+from simod.init import config
+
+from tqdm import tqdm
+import numpy as np
+import pandas as pd
+import matplotlib.pyplot as plt
+import matplotlib
+import roadmaptools.inout
+import simod.utils
+
+from matplotlib.ticker import FuncFormatter
+from pandas import DataFrame
+
+
+def to_percent_x(x, position):
+ # Ignore the passed in position. This has the effect of scaling the default
+ # tick locations.
+ s = str(int(round(100 * x)))
+
+ # The percent symbol needs escaping in latex
+ if matplotlib.rcParams['text.usetex'] is True:
+ return s + r'$\%$'
+ else:
+ return s + '%'
+
+def to_percent_y(y, position):
+ # Ignore the passed in position. This has the effect of scaling the default
+ # tick locations.
+ s = str(int(round(10 * y)))
+
+ # The percent symbol needs escaping in latex
+ if matplotlib.rcParams['text.usetex'] is True:
+ return s + r'$\%$'
+ else:
+ return s + '%'
+
+
+data_dir_1 = '/Users/adela/Documents/bakalarka/vysledky2/InsertionHeuristic/Archiv/experiments/test/inactive_vehicles.csv'
+data_dir_2 = '/Users/adela/Documents/bakalarka/vysledky2/transferInsertionHeuristic/Archiv/experiments/test/inactive_vehicles.csv'
+data_dir_3 = '/Users/adela/Documents/bakalarka/vysledky2/taset/Archiv/experiments/test/inactive_vehicles.csv'
+
+save_dir_1 = '/Users/adela/Documents/bakalarka/vysledky2/InsertionHeuristic/Archiv/img/'
+save_dir_2 = '/Users/adela/Documents/bakalarka/vysledky2/transferInsertionHeuristic/Archiv/img/'
+save_dir_3 = '/Users/adela/Documents/bakalarka/vysledky2/taset/Archiv/img/'
+
+# TODO change dir
+df = pd.read_csv(data_dir_3)
+
+# vehicles = df['id'].values
+
+occur = df.groupby(['id']).size()
+
+occur_df = occur.to_frame()
+occur_df = occur_df.reset_index()
+occur_df.columns=['id','occurance_inactive']
+occur_df['time_inactive'] = occur_df['occurance_inactive'] * 30
+
+simulation_duration = 5 * 60 * 60 + 600 # in seconds
+
+occur_df['percentage_active'] = (simulation_duration - occur_df['time_inactive']) / simulation_duration
+
+df_short = occur_df[['id', 'percentage_active']]
+
+fig, axis = plt.subplots(1, 1, subplot_kw={"adjustable": 'box'}, figsize=(4, 3))
+
+plt.gca().xaxis.set_major_formatter(FuncFormatter(to_percent_x))
+
+bins = np.arange(0, 1, 0.1)
+axis.set_xticks(bins)
+plt.xticks(fontsize=9, rotation=0)
+
+axis.hist(occur_df['percentage_active'], bins, density=False, stacked=False, edgecolor='black', linewidth=0.4)
+
+# plt.title("Vehicle utilization")
+
+# TODO change dir
+save_results_to = save_dir_3
+plt.savefig(save_results_to + 'vehicle-utilization', bbox_inches='tight', transparent=True)
+
+plt.show()
+
+
+
+print('done')
\ No newline at end of file
diff --git a/python/simod/statistics/map_from_edges.py b/python/simod/statistics/map_from_edges.py
new file mode 100644
index 00000000..c8a2ad23
--- /dev/null
+++ b/python/simod/statistics/map_from_edges.py
@@ -0,0 +1,90 @@
+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')
+
+# data = gpd.read_file('/Users/adela/Documents/bakalarka/randomdemand/maps/edges.geojson')
+save_dir = '/Users/adela/Documents/bakalarka/vysledky2/'
+
+data = pd.read_csv('/Users/adela/Documents/bakalarka/randomdemand/trips.txt', sep=" ", header=None)
+data.columns = ["time", "y", "x", "y2", "x2"]
+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=(10, 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=300,
+ levels=10,
+ ax=ax,
+ legend=False)
+
+# 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.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/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..9f585f78 100644
--- a/python/simod/statistics/model/occupancy.py
+++ b/python/simod/statistics/model/occupancy.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/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/model/trips.py b/python/simod/statistics/model/trips.py
index 1d8d1d30..4c21aad1 100644
--- a/python/simod/statistics/model/trips.py
+++ b/python/simod/statistics/model/trips.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/occupancy.py b/python/simod/statistics/occupancy.py
index d0802939..a3248f47 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
@@ -42,8 +42,25 @@ def to_percent(y, position):
return s + '%'
-results = roadmaptools.inout.load_json(config.statistics.result_file_path)
-data = np.genfromtxt(config.statistics.occupancies_file_path, delimiter=',')
+exp_dir_1 = '/Users/adela/Documents/bakalarka/vysledky2/InsertionHeuristic/Archiv/experiments/test/result.json'
+exp_dir_2 = '/Users/adela/Documents/bakalarka/vysledky2/transferInsertionHeuristic/Archiv/experiments/test/result.json'
+exp_dir_3 = '/Users/adela/Documents/bakalarka/vysledky2/taset/Archiv/experiments/test/result.json'
+
+# results = roadmaptools.inout.load_json(config.statistics.result_file_path)
+# TODO change dir
+results = roadmaptools.inout.load_json(exp_dir_3)
+
+occ_dir_1 = '/Users/adela/Documents/bakalarka/vysledky2/InsertionHeuristic/Archiv/experiments/test/vehicle_occupancy.csv'
+occ_dir_2 = '/Users/adela/Documents/bakalarka/vysledky2/transferInsertionHeuristic/Archiv/experiments/test/vehicle_occupancy.csv'
+occ_dir_3 = '/Users/adela/Documents/bakalarka/vysledky2/taset/Archiv/experiments/test/vehicle_occupancy.csv'
+# TODO change dir
+data = np.genfromtxt(occ_dir_3, delimiter=',')
+
+save_dir_1 = '/Users/adela/Documents/bakalarka/vysledky2/InsertionHeuristic/Archiv/img/'
+save_dir_2 = '/Users/adela/Documents/bakalarka/vysledky2/transferInsertionHeuristic/Archiv/img/'
+save_dir_3 = '/Users/adela/Documents/bakalarka/vysledky2/taset/Archiv/img/'
+# TODO change dir
+save_results_to = save_dir_3
occupancy_col = data[:,2]
@@ -60,9 +77,11 @@ def to_percent(y, position):
bins = np.arange(-0.5, 6.5, 1)
-axis.hist(occupancy_col, bins, normed=True)
+# axis.hist(occupancy_col, bins, normed=True)
+axis.hist(occupancy_col, bins, density=True, stacked=True)
+# plt.title('Vehicle occupancy')
-# plt.savefig(config.images.occupancy_histogram, bbox_inches='tight', transparent=True)
+plt.savefig(save_results_to + 'occupancy', bbox_inches='tight', transparent=True)
# in window
@@ -82,9 +101,12 @@ def to_percent(y, position):
# axis.set_xlabel("Vehicle occupancy [persons]")
# axis.set_ylabel("Share of vehicles")
-axis.hist(occupancy_in_window, bins, normed=True)
+# axis.hist(occupancy_in_window, bins, normed=True)
+axis.hist(occupancy_in_window, bins, density=True, stacked=True)
+
+# plt.savefig(config.images.occupancy_histogram_window, bbox_inches='tight', transparent=True)
+plt.savefig(save_results_to + 'occupancy-window', bbox_inches='tight', transparent=True)
-plt.savefig(config.images.occupancy_histogram_window, bbox_inches='tight', transparent=True)
# occupancy in time
df = DataFrame(data, columns=["period", "id", "occupancy"])
@@ -95,5 +117,7 @@ def to_percent(y, position):
fig, axis = plt.subplots(1, 1, subplot_kw={"adjustable": 'box'}, figsize=(4, 3))
axis.plot(avg_occupancies_per_period)
+# plt.title("Average vehicle occupancy over time")
+plt.savefig(save_results_to + 'occupancy-in-time', bbox_inches='tight', transparent=True)
plt.show()
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/python/simod/statistics/trip_statistics.py b/python/simod/statistics/trip_statistics.py
index 2f578d01..1f0d73ca 100644
--- a/python/simod/statistics/trip_statistics.py
+++ b/python/simod/statistics/trip_statistics.py
@@ -23,11 +23,11 @@
from matplotlib.ticker import FuncFormatter
from simod.statistics.model import trips
-HOURS_IN_DAY = 24
+HOURS_IN_DAY = 5
MINUTES_IN_HOUR = 60
-HISTOGRAM_SAMPLES = 96
+HISTOGRAM_SAMPLES = 5
def format_timestamps(tick, tick_index):
@@ -43,7 +43,8 @@ def format_timestamps(tick, tick_index):
counts, bins, patches = axis.hist(trips_data["start_time"], HISTOGRAM_SAMPLES)
-tick_interval = int(HISTOGRAM_SAMPLES / 16)
+tick_interval = 5
+tick_interval = int(HISTOGRAM_SAMPLES / 20)
axis.set_xticks(bins[0::tick_interval])
axis.xaxis.set_major_formatter(FuncFormatter(format_timestamps))
@@ -52,8 +53,8 @@ def format_timestamps(tick, tick_index):
plt.subplots_adjust(bottom=0.2)
axis.get_xaxis().set_tick_params(direction='out')
-
-# plt.savefig(config.images.trip_start_histogram, bbox_inches='tight', transparent=True, pad_inches=0)
+save_dir_1 = '/Users/adela/Documents/bakalarka/vysledky/'
+plt.savefig(save_dir_1 + 'demands_in_time', bbox_inches='tight', transparent=True, pad_inches=0)
# fig, axis = plt.subplots(figsize=(6, 4))
#
diff --git a/python/simod/statistics/waiting_time_histogram.py b/python/simod/statistics/waiting_time_histogram.py
new file mode 100644
index 00000000..cba8bfd0
--- /dev/null
+++ b/python/simod/statistics/waiting_time_histogram.py
@@ -0,0 +1,66 @@
+import matplotlib.pyplot as plt
+import pandas.errors
+import pandas as pd
+import numpy as np
+import matplotlib
+import roadmaptools.inout
+from matplotlib.ticker import FuncFormatter
+
+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
+
+def to_percent_x(x, position):
+ # Ignore the passed in position. This has the effect of scaling the default
+ # tick locations.
+ s = str(int(round(100 * x)))
+
+ # The percent symbol needs escaping in latex
+ if matplotlib.rcParams['text.usetex'] is True:
+ return s + r'$\%$'
+ else:
+ return s + '%'
+
+def to_percent_y(y, position):
+ # Ignore the passed in position. This has the effect of scaling the default
+ # tick locations.
+ s = str(int(round(10 * y)))
+
+ # The percent symbol needs escaping in latex
+ if matplotlib.rcParams['text.usetex'] is True:
+ return s + r'$\%$'
+ else:
+ return s + '%'
+
+
+exp_dir_2 = '/Users/adela/Documents/bakalarka/vysledky2/transferInsertionHeuristic/Archiv/experiments/test/waiting_times.csv'
+save_dir_2 = '/Users/adela/Documents/bakalarka/vysledky2/transferInsertionHeuristic/Archiv/img/'
+exp_dir_3 = '/Users/adela/Documents/bakalarka/vysledky2/taset/Archiv/experiments/test/waiting_times.csv'
+save_dir_3 = '/Users/adela/Documents/bakalarka/vysledky2/taset/Archiv/img/'
+
+
+# delays dataframe
+# TODO change dir
+df = pd.read_csv(exp_dir_2)
+# TODO change dir
+save_results_to = save_dir_2
+
+fig, axis = plt.subplots(1, 1, subplot_kw={"adjustable": 'box'}, figsize=(4, 3))
+
+maximum = df['waiting_time'].max()
+
+bins = np.arange(0, maximum+20, 10)
+labels = bins[0::2]
+axis.set_xticks(labels)
+plt.xticks(fontsize=8, rotation=0)
+
+axis.hist(df['waiting_time'], bins, density=False, stacked=False, edgecolor='black', linewidth=0.4)
+
+# plt.title("Waiting times")
+
+plt.savefig(save_results_to + 'waiting_times', bbox_inches='tight', transparent=True)
+
+plt.show()
\ No newline at end of file
diff --git a/src/main/java/cz/cvut/fel/aic/simod/DriveToTransferStation.java b/src/main/java/cz/cvut/fel/aic/simod/DriveToTransferStation.java
new file mode 100644
index 00000000..7754ab7c
--- /dev/null
+++ b/src/main/java/cz/cvut/fel/aic/simod/DriveToTransferStation.java
@@ -0,0 +1,103 @@
+package cz.cvut.fel.aic.simod;
+
+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.Activity;
+import cz.cvut.fel.aic.agentpolis.simmodel.ActivityInitializer;
+import cz.cvut.fel.aic.agentpolis.simmodel.Agent;
+import cz.cvut.fel.aic.agentpolis.simmodel.activity.PhysicalVehicleDrive;
+import cz.cvut.fel.aic.agentpolis.simmodel.activity.activityFactory.VehicleMoveActivityFactory;
+import cz.cvut.fel.aic.agentpolis.simmodel.agent.Driver;
+import cz.cvut.fel.aic.agentpolis.simmodel.entity.vehicle.Vehicle;
+import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.EGraphType;
+import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationEdge;
+import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode;
+import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.networks.TransportNetworks;
+import cz.cvut.fel.aic.agentpolis.simmodel.eventType.DriveEvent;
+import cz.cvut.fel.aic.agentpolis.simmodel.eventType.Transit;
+import cz.cvut.fel.aic.alite.common.event.EventProcessor;
+import cz.cvut.fel.aic.alite.common.event.typed.TypedSimulation;
+import cz.cvut.fel.aic.geographtools.Graph;
+import cz.cvut.fel.aic.simod.ridesharing.RideSharingOnDemandVehicle;
+
+
+/**
+ * @param
+ * @author fido
+ */
+public class DriveToTransferStation extends PhysicalVehicleDrive {
+
+ private final Vehicle vehicle;
+
+ public final Trip trip;
+
+ private final VehicleMoveActivityFactory moveActivityFactory;
+
+ private final Graph graph;
+
+ private final EventProcessor eventProcessor;
+
+ private final StandardTimeProvider timeProvider;
+
+
+ private SimulationNode from;
+
+ public SimulationNode to;
+
+
+
+
+ public DriveToTransferStation(ActivityInitializer activityInitializer, TransportNetworks transportNetworks,
+ VehicleMoveActivityFactory moveActivityFactory, TypedSimulation eventProcessor,
+ StandardTimeProvider timeProvider,
+ A agent, Vehicle vehicle, Trip trip) {
+ super(activityInitializer, agent);
+ this.vehicle = vehicle;
+ this.trip = trip;
+ this.moveActivityFactory = moveActivityFactory;
+ this.eventProcessor = eventProcessor;
+ this.timeProvider = timeProvider;
+ graph = transportNetworks.getGraph(EGraphType.HIGHWAY);
+ }
+
+ @Override
+ protected void performAction() {
+ agent.startDriving(vehicle);
+ from = trip.removeFirstLocation();
+ move();
+ }
+
+ @Override
+ protected void onChildActivityFinish(Activity activity) {
+ if (trip.isEmpty() || stoped) {
+ agent.endDriving();
+ if (agent instanceof RideSharingOnDemandVehicle) {
+ ((RideSharingOnDemandVehicle) agent).tripAlreadyPlanned = false;
+ }
+ vehicle.setLastFromPosition(from);
+ finish();
+ } else {
+ from = to;
+ move();
+ }
+ }
+
+
+ private void move() {
+ to = trip.removeFirstLocation();
+ SimulationEdge edge = graph.getEdge(from, to);
+
+ runChildActivity(moveActivityFactory.create(agent, edge, from, to));
+ triggerVehicleEnteredEdgeEvent();
+ }
+
+ private void triggerVehicleEnteredEdgeEvent() {
+ SimulationEdge edge = graph.getEdge(from, to);
+ Transit transit = new Transit(timeProvider.getCurrentSimTime(), edge.getStaticId(),trip.getTripId(), agent);
+ eventProcessor.addEvent(DriveEvent.VEHICLE_ENTERED_EDGE, null, null, transit);
+ }
+
+ public Trip getTrip() {
+ return trip;
+ }
+}
diff --git a/src/main/java/cz/cvut/fel/aic/simod/DriveToTransferStationActivityFactory.java b/src/main/java/cz/cvut/fel/aic/simod/DriveToTransferStationActivityFactory.java
new file mode 100644
index 00000000..0b4d7e26
--- /dev/null
+++ b/src/main/java/cz/cvut/fel/aic/simod/DriveToTransferStationActivityFactory.java
@@ -0,0 +1,66 @@
+package cz.cvut.fel.aic.simod;
+
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+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.ActivityFactory;
+import cz.cvut.fel.aic.agentpolis.simmodel.Agent;
+import cz.cvut.fel.aic.agentpolis.simmodel.activity.Drive;
+import cz.cvut.fel.aic.agentpolis.simmodel.activity.activityFactory.PhysicalVehicleDriveFactory;
+import cz.cvut.fel.aic.agentpolis.simmodel.activity.activityFactory.VehicleMoveActivityFactory;
+import cz.cvut.fel.aic.agentpolis.simmodel.agent.Driver;
+import cz.cvut.fel.aic.agentpolis.simmodel.entity.vehicle.PhysicalVehicle;
+import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode;
+import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.networks.TransportNetworks;
+import cz.cvut.fel.aic.alite.common.event.typed.TypedSimulation;
+
+/**
+ * @author fido
+ */
+@Singleton
+public class DriveToTransferStationActivityFactory extends ActivityFactory implements PhysicalVehicleDriveFactory {
+
+ private final TransportNetworks transportNetworks;
+
+ private final VehicleMoveActivityFactory moveActivityFactory;
+
+ private final TypedSimulation eventProcessor;
+
+ private final StandardTimeProvider timeProvider;
+
+ private final TripsUtil tripsUtil;
+
+
+ @Inject
+ public DriveToTransferStationActivityFactory(TransportNetworks transportNetworks, VehicleMoveActivityFactory moveActivityFactory,
+ TypedSimulation eventProcessor, StandardTimeProvider timeProvider,TripsUtil tripsUtil) {
+ this.transportNetworks = transportNetworks;
+ this.moveActivityFactory = moveActivityFactory;
+ this.eventProcessor = eventProcessor;
+ this.timeProvider = timeProvider;
+ this.tripsUtil = tripsUtil;
+ }
+
+
+ @Override
+ public void runActivity(A agent, PhysicalVehicle vehicle, Trip trip) {
+ create(agent, vehicle, trip).run();
+ }
+
+
+ public DriveToTransferStation create(A agent, PhysicalVehicle vehicle, Trip trip) {
+ return new DriveToTransferStation<>(activityInitializer, transportNetworks, moveActivityFactory, eventProcessor,
+ timeProvider, agent, vehicle, trip);
+ }
+
+ @Override
+ public DriveToTransferStation create(A agent, PhysicalVehicle vehicle, SimulationNode target) {
+ Trip trip = tripsUtil.createTrip(agent.getPosition(), target);
+
+ return new DriveToTransferStation<>(activityInitializer, transportNetworks, moveActivityFactory, eventProcessor, timeProvider,
+ agent, vehicle, trip);
+ }
+
+}
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..3a9fc356 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,9 @@
*/
package cz.cvut.fel.aic.simod;
+import cz.cvut.fel.aic.simod.ridesharing.greedyTASeT.GreedyTASeTNoFreezeSolver;
+import cz.cvut.fel.aic.simod.ridesharing.greedyTASeT.GreedyTASeTSolver;
+import cz.cvut.fel.aic.simod.ridesharing.transferinsertion.TransferInsertionSolver;
import cz.cvut.fel.aic.simod.traveltimecomputation.DistanceMatrixTravelTimeProvider;
import cz.cvut.fel.aic.simod.traveltimecomputation.TNRTravelTimeProvider;
import cz.cvut.fel.aic.simod.traveltimecomputation.TNRAFTravelTimeProvider;
@@ -146,6 +149,16 @@ protected void configureNext() {
bind(SingleVehicleDARPSolver.class).to(ArrayOptimalVehiclePlanFinder.class);
// bind(OptimalVehiclePlanFinder.class).to(PlanBuilderOptimalVehiclePlanFinder.class);
break;
+ case "greedy-taset":
+ bind(DARPSolver.class).to(GreedyTASeTSolver.class);
+ // nabindovat i nove tridy
+ break;
+ case "greedy-taset-no-freeze":
+ bind(DARPSolver.class).to(GreedyTASeTNoFreezeSolver.class);
+ break;
+ case "transfer-insertion":
+ bind(DARPSolver.class).to(TransferInsertionSolver.class);
+ break;
}
}
else{
diff --git a/src/main/java/cz/cvut/fel/aic/simod/MapVisualizer.java b/src/main/java/cz/cvut/fel/aic/simod/MapVisualizer.java
index ad7c7820..900a1c7a 100644
--- a/src/main/java/cz/cvut/fel/aic/simod/MapVisualizer.java
+++ b/src/main/java/cz/cvut/fel/aic/simod/MapVisualizer.java
@@ -25,6 +25,7 @@
import cz.cvut.fel.aic.agentpolis.system.AgentPolisInitializer;
import cz.cvut.fel.aic.simod.config.SimodConfig;
import cz.cvut.fel.aic.simod.init.StationsInitializer;
+import cz.cvut.fel.aic.simod.init.TransferPointsInitializer;
import cz.cvut.fel.aic.simod.mapVisualization.MapVisualiserModule;
import cz.cvut.fel.aic.simod.mapVisualization.MapVisualizationCreator;
import java.io.File;
@@ -60,6 +61,9 @@ public void run(String[] args) {
// load stations
injector.getInstance(StationsInitializer.class).loadStations();
+ // load transfer points
+ injector.getInstance(TransferPointsInitializer.class).loadTransferPoints();
+
creator.startSimulation();
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..b32a90ef 100644
--- a/src/main/java/cz/cvut/fel/aic/simod/OnDemandVehiclesSimulation.java
+++ b/src/main/java/cz/cvut/fel/aic/simod/OnDemandVehiclesSimulation.java
@@ -20,20 +20,34 @@
import com.google.inject.Injector;
import cz.cvut.fel.aic.agentpolis.config.AgentpolisConfig;
+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.simmodel.environment.transportnetwork.elements.SimulationNode;
import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.init.MapInitializer;
import cz.cvut.fel.aic.agentpolis.simulator.creator.SimulationCreator;
+import cz.cvut.fel.aic.agentpolis.simulator.visualization.visio.VisioPositionUtil;
import cz.cvut.fel.aic.agentpolis.system.AgentPolisInitializer;
import cz.cvut.fel.aic.simod.config.SimodConfig;
+import cz.cvut.fel.aic.simod.config.TransferInsertion;
import cz.cvut.fel.aic.simod.init.EventInitializer;
import cz.cvut.fel.aic.simod.init.StationsInitializer;
import cz.cvut.fel.aic.simod.init.StatisticInitializer;
+import cz.cvut.fel.aic.simod.init.TransferPointsInitializer;
+import cz.cvut.fel.aic.simod.io.TimeTrip;
import cz.cvut.fel.aic.simod.io.TripTransform;
import cz.cvut.fel.aic.simod.rebalancing.ReactiveRebalancing;
+import cz.cvut.fel.aic.simod.ridesharing.greedyTASeT.GreedyTASeTSolver;
+import cz.cvut.fel.aic.simod.ridesharing.greedyTASeT.GreedyTASeTNoFreezeSolver;
+import cz.cvut.fel.aic.simod.ridesharing.transferinsertion.TransferInsertionSolver;
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 java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+
import org.slf4j.LoggerFactory;
/**
@@ -51,6 +65,7 @@ public static void checkPaths(SimodConfig config, AgentpolisConfig agentpolisCon
String[] pathsForRead = {
config.tripsPath,
config.stationPositionFilepath,
+ config.transferPointsFilepath,
agentpolisConfig.mapNodesFilepath,
agentpolisConfig.mapEdgesFilepath
};
@@ -109,6 +124,14 @@ public void run(String[] args) {
// load stations
injector.getInstance(StationsInitializer.class).loadStations();
+ // load transfer points
+// injector.getInstance(TransferPointsInitializer.class).loadTransferPoints();
+ injector.getInstance(GreedyTASeTSolver.class).setTransferPoints(injector.getInstance(TransferPointsInitializer.class).loadTransferPoints());
+
+ injector.getInstance(GreedyTASeTNoFreezeSolver.class).setTransferPoints(injector.getInstance(TransferPointsInitializer.class).loadTransferPoints());
+
+ injector.getInstance(TransferInsertionSolver.class).setTransferPoints(injector.getInstance(TransferPointsInitializer.class).loadTransferPoints());
+
if(config.rebalancing.on){
// start rebalancing
@@ -121,6 +144,29 @@ public void run(String[] args) {
injector.getInstance(EventInitializer.class).initialize(
tripTransform.loadTripsFromTxt(new File(config.tripsPath)), null);
+// USED TO COMPUTE STATISTICS OF DEMAND
+// List lengths = new ArrayList<>();
+// List> trips = tripTransform.loadTripsFromTxt(new File(config.tripsPath));
+// for (TimeTrip trip : trips) {
+// SimulationNode origin = trip.getAllLocations()[0];
+// SimulationNode destination = trip.getAllLocations()[1];
+// Trip t = injector.getInstance(TripsUtil.class).createTrip(origin, destination);
+// long l = injector.getInstance(VisioPositionUtil.class).getTripLengthInMeters(t);
+// lengths.add(l);
+// }
+//
+//// get max, min and avg
+// lengths.stream() //
+// .max(Comparator.comparing(i -> i)) //
+// .ifPresent(max -> System.out.println("Maximum found is " + max));
+// lengths.stream() //
+// .min(Comparator.comparing(i -> i)) //
+// .ifPresent(min -> System.out.println("Minimum found is " + min));
+// lengths.stream() //
+// .mapToLong(i -> i) //
+// .average() //
+// .ifPresent(avg -> System.out.println("Average found is " + avg));
+
injector.getInstance(StatisticInitializer.class).initialize();
// start it up
diff --git a/src/main/java/cz/cvut/fel/aic/simod/TransferPickUp.java b/src/main/java/cz/cvut/fel/aic/simod/TransferPickUp.java
new file mode 100644
index 00000000..3241f980
--- /dev/null
+++ b/src/main/java/cz/cvut/fel/aic/simod/TransferPickUp.java
@@ -0,0 +1,41 @@
+package cz.cvut.fel.aic.simod;
+
+import cz.cvut.fel.aic.agentpolis.simmodel.agent.TransportEntity;
+import cz.cvut.fel.aic.agentpolis.simmodel.entity.TransportableEntity;
+import cz.cvut.fel.aic.agentpolis.simmodel.entity.vehicle.PhysicalTransportVehicle;
+
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+public final class TransferPickUp {
+
+ public static void pickUp(T entity,
+ boolean isVehicleFull, E transportingEntity, List transportedEntities) {
+ if (isVehicleFull) {
+ try {
+ throw new Exception(
+ String.format("Cannot pick up entity, the vehicle is full! [%s]", entity));
+ } catch (Exception ex) {
+ Logger.getLogger(PhysicalTransportVehicle.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+ if(entity.getTransportingEntity() != null) {
+ // auto se snazi zavolat pickup na demand, ktery jeste nedojel do cilove stanice
+ // ale nez by toto auto dojelo na stanici, demand uz by tam byl vylozeny
+ // proto podminka entity.getTransportingEntity() != null neni spravne
+
+// try {
+// throw new Exception(
+// String.format("Cannot pick up entity, it's already being transported! [%s]", entity));
+// } catch (Exception ex) {
+// Logger.getLogger(PhysicalTransportVehicle.class.getName()).log(Level.SEVERE, null, ex);
+// }
+ }
+ else{
+ transportedEntities.add(entity);
+ entity.setTransportingEntity(transportingEntity);
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/cz/cvut/fel/aic/simod/WaitTransfer.java b/src/main/java/cz/cvut/fel/aic/simod/WaitTransfer.java
new file mode 100644
index 00000000..41993da5
--- /dev/null
+++ b/src/main/java/cz/cvut/fel/aic/simod/WaitTransfer.java
@@ -0,0 +1,94 @@
+package cz.cvut.fel.aic.simod;
+
+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.Activity;
+import cz.cvut.fel.aic.agentpolis.simmodel.ActivityInitializer;
+import cz.cvut.fel.aic.agentpolis.simmodel.Agent;
+import cz.cvut.fel.aic.agentpolis.simmodel.TimeConsumingActivity;
+import cz.cvut.fel.aic.agentpolis.simmodel.activity.activityFactory.VehicleMoveActivityFactory;
+import cz.cvut.fel.aic.agentpolis.simmodel.activity.activityFactory.WaitActivityFactory;
+import cz.cvut.fel.aic.agentpolis.simmodel.agent.Driver;
+import cz.cvut.fel.aic.agentpolis.simmodel.entity.vehicle.Vehicle;
+import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.EGraphType;
+import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationEdge;
+import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode;
+import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.networks.TransportNetworks;
+import cz.cvut.fel.aic.agentpolis.simmodel.eventType.DriveEvent;
+import cz.cvut.fel.aic.agentpolis.simmodel.eventType.Transit;
+import cz.cvut.fel.aic.alite.common.event.EventProcessor;
+import cz.cvut.fel.aic.alite.common.event.typed.TypedSimulation;
+import cz.cvut.fel.aic.geographtools.Graph;
+
+public class WaitTransfer extends TimeConsumingActivity {
+
+ private final long waitTime;
+
+ private final WaitActivityFactory waitActivityFactory;
+
+// private final Trip trip;
+//
+// private final VehicleMoveActivityFactory moveActivityFactory;
+//
+// private final Vehicle vehicle;
+//
+// private final Graph graph;
+//
+// private final EventProcessor eventProcessor;
+//
+// private final StandardTimeProvider timeProvider;
+
+
+// private SimulationNode from;
+//
+// private SimulationNode to;
+
+ public WaitTransfer(ActivityInitializer activityInitializer, A agent, long waitTime, WaitActivityFactory waitActivityFactory
+// , VehicleMoveActivityFactory moveActivityFactory,
+// TypedSimulation eventProcessor, StandardTimeProvider timeProvider, Trip trip, Vehicle vehicle, TransportNetworks transportNetworks
+ ) {
+ super(activityInitializer, agent);
+ this.waitTime = waitTime;
+ this.waitActivityFactory = waitActivityFactory;
+// this.moveActivityFactory = moveActivityFactory;
+// this.timeProvider = timeProvider;
+// this.eventProcessor = eventProcessor;
+// this.trip = trip;
+// this.vehicle = vehicle;
+// graph = transportNetworks.getGraph(EGraphType.HIGHWAY);
+
+ }
+
+ @Override
+ protected long performPreDelayActions() {
+ return waitTime;
+ }
+
+ @Override
+ protected void performAction() {
+ waitTransfer();
+
+// finish();
+ }
+
+// @Override
+// protected void onChildActivityFinish(Activity activity) {
+//// if (trip.isEmpty()) {
+//// vehicle.setLastFromPosition(from);
+//// finish();
+//// } else {
+// from = to;
+// move();
+//// }
+// }
+
+// private void move() {
+//
+// }
+
+ private void waitTransfer() {
+ runChildActivity(waitActivityFactory.create(agent, waitTime));
+ }
+
+
+}
\ No newline at end of file
diff --git a/src/main/java/cz/cvut/fel/aic/simod/WaitTransferActivityFactory.java b/src/main/java/cz/cvut/fel/aic/simod/WaitTransferActivityFactory.java
new file mode 100644
index 00000000..464a6199
--- /dev/null
+++ b/src/main/java/cz/cvut/fel/aic/simod/WaitTransferActivityFactory.java
@@ -0,0 +1,20 @@
+package cz.cvut.fel.aic.simod;
+
+import com.google.inject.Singleton;
+import cz.cvut.fel.aic.agentpolis.simmodel.Activity;
+import cz.cvut.fel.aic.agentpolis.simmodel.ActivityFactory;
+import cz.cvut.fel.aic.agentpolis.simmodel.Agent;
+import cz.cvut.fel.aic.agentpolis.simmodel.activity.activityFactory.WaitActivityFactory;
+
+@Singleton
+public class WaitTransferActivityFactory extends ActivityFactory {
+
+
+ public void runActivity(A agent, long waitTime, WaitActivityFactory waitActivityFactory) {
+ create(agent, waitTime, waitActivityFactory).run();
+ }
+
+ public WaitTransfer create(A agent, long waitTime, WaitActivityFactory waitActivityFactory) {
+ return new WaitTransfer<>(activityInitializer, agent, waitTime, waitActivityFactory);
+ }
+}
diff --git a/src/main/java/cz/cvut/fel/aic/simod/WaitWithStop.java b/src/main/java/cz/cvut/fel/aic/simod/WaitWithStop.java
new file mode 100644
index 00000000..3c714afd
--- /dev/null
+++ b/src/main/java/cz/cvut/fel/aic/simod/WaitWithStop.java
@@ -0,0 +1,38 @@
+package cz.cvut.fel.aic.simod;
+
+import cz.cvut.fel.aic.agentpolis.simmodel.ActivityInitializer;
+import cz.cvut.fel.aic.agentpolis.simmodel.Agent;
+import cz.cvut.fel.aic.agentpolis.simmodel.TimeConsumingActivity;
+
+public class WaitWithStop extends TimeConsumingActivity{
+
+ private final long waitTime;
+
+ protected boolean stoped;
+
+
+ public WaitWithStop(ActivityInitializer activityInitializer, A agent, long waitTime) {
+ super(activityInitializer, agent);
+ this.waitTime = waitTime;
+ this.stoped = false;
+ }
+
+ public boolean isStoped() {
+ return stoped;
+ }
+
+ public void end(){
+ stoped = true;
+ }
+
+ @Override
+ protected long performPreDelayActions() {
+ return waitTime;
+ }
+
+ @Override
+ protected void performAction() {
+ finish();
+ }
+
+}
diff --git a/src/main/java/cz/cvut/fel/aic/simod/WaitWithStopActivityFactory.java b/src/main/java/cz/cvut/fel/aic/simod/WaitWithStopActivityFactory.java
new file mode 100644
index 00000000..ac33db49
--- /dev/null
+++ b/src/main/java/cz/cvut/fel/aic/simod/WaitWithStopActivityFactory.java
@@ -0,0 +1,19 @@
+package cz.cvut.fel.aic.simod;
+
+import com.google.inject.Singleton;
+import cz.cvut.fel.aic.agentpolis.simmodel.ActivityFactory;
+import cz.cvut.fel.aic.agentpolis.simmodel.Agent;
+import cz.cvut.fel.aic.agentpolis.simmodel.activity.Wait;
+
+@Singleton
+public class WaitWithStopActivityFactory extends ActivityFactory {
+
+
+ public void runActivity(A agent, long waitTime) {
+ create(agent, waitTime).run();
+ }
+
+ public WaitWithStop create(A agent, long waitTime) {
+ return new WaitWithStop<>(activityInitializer, agent, waitTime);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/cz/cvut/fel/aic/simod/config/GreedyTASeT.java b/src/main/java/cz/cvut/fel/aic/simod/config/GreedyTASeT.java
new file mode 100644
index 00000000..15cc7b14
--- /dev/null
+++ b/src/main/java/cz/cvut/fel/aic/simod/config/GreedyTASeT.java
@@ -0,0 +1,10 @@
+package cz.cvut.fel.aic.simod.config;
+
+import java.util.Map;
+
+public class GreedyTASeT {
+
+ public GreedyTASeT(Map greedytaset) {
+
+ }
+}
diff --git a/src/main/java/cz/cvut/fel/aic/simod/config/GreedyTASeTNoFreeze.java b/src/main/java/cz/cvut/fel/aic/simod/config/GreedyTASeTNoFreeze.java
new file mode 100644
index 00000000..e4d7058a
--- /dev/null
+++ b/src/main/java/cz/cvut/fel/aic/simod/config/GreedyTASeTNoFreeze.java
@@ -0,0 +1,10 @@
+package cz.cvut.fel.aic.simod.config;
+
+import java.util.Map;
+
+public class GreedyTASeTNoFreeze {
+
+ public GreedyTASeTNoFreeze(Map greedytaset) {
+
+ }
+}
diff --git a/src/main/java/cz/cvut/fel/aic/simod/config/OnDemandVehicleStatistic.java b/src/main/java/cz/cvut/fel/aic/simod/config/OnDemandVehicleStatistic.java
index 92759ce7..788b452f 100644
--- a/src/main/java/cz/cvut/fel/aic/simod/config/OnDemandVehicleStatistic.java
+++ b/src/main/java/cz/cvut/fel/aic/simod/config/OnDemandVehicleStatistic.java
@@ -14,6 +14,8 @@ public class OnDemandVehicleStatistic {
public String finishRebalancingFilePath;
+ public String waitFilePath;
+
public String dirPath;
public String startRebalancingFilePath;
@@ -26,5 +28,6 @@ public OnDemandVehicleStatistic(Map onDemandVehicleStatistic) {
this.finishRebalancingFilePath = (String) onDemandVehicleStatistic.get("finish_rebalancing_file_path");
this.dirPath = (String) onDemandVehicleStatistic.get("dir_path");
this.startRebalancingFilePath = (String) onDemandVehicleStatistic.get("start_rebalancing_file_path");
+ this.waitFilePath = (String) onDemandVehicleStatistic.get("wait_file_path");
}
}
diff --git a/src/main/java/cz/cvut/fel/aic/simod/config/Ridesharing.java b/src/main/java/cz/cvut/fel/aic/simod/config/Ridesharing.java
index a4408f2b..def4fd8c 100644
--- a/src/main/java/cz/cvut/fel/aic/simod/config/Ridesharing.java
+++ b/src/main/java/cz/cvut/fel/aic/simod/config/Ridesharing.java
@@ -1,5 +1,6 @@
package cz.cvut.fel.aic.simod.config;
+
import java.lang.Boolean;
import java.lang.Double;
import java.lang.Integer;
@@ -7,6 +8,12 @@
import java.util.Map;
public class Ridesharing {
+ public TransferInsertion transferInsertion;
+
+ public GreedyTASeTNoFreeze greedyTASeTNoFreeze;
+
+ public GreedyTASeT greedytaset;
+
public Vga vga;
public Integer batchPeriod;
@@ -28,6 +35,9 @@ public class Ridesharing {
public Boolean on;
public Ridesharing(Map ridesharing) {
+ this.transferInsertion = new TransferInsertion((Map) ridesharing.get("transfer-insertion"));
+ this.greedyTASeTNoFreeze = new GreedyTASeTNoFreeze((Map) ridesharing.get("greedy_taset_no_freeze"));
+ this.greedytaset = new GreedyTASeT((Map) ridesharing.get("greedy_taset"));
this.vga = new Vga((Map) ridesharing.get("vga"));
this.batchPeriod = (Integer) ridesharing.get("batch_period");
this.method = (String) ridesharing.get("method");
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..0521c112 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
@@ -48,6 +48,8 @@ public class SimodConfig implements GeneratedConfig {
public String stationPositionFilepath;
+ public String transferPointsFilepath;
+
public Rebalancing rebalancing;
public Statistics statistics;
@@ -76,6 +78,7 @@ public SimodConfig fill(Map simodConfig) {
this.simplifyGraph = (Boolean) simodConfig.get("simplify_graph");
this.ridesharing = new Ridesharing((Map) simodConfig.get("ridesharing"));
this.stationPositionFilepath = (String) simodConfig.get("station_position_filepath");
+ this.transferPointsFilepath = (String) simodConfig.get("transfer_points_filepath");
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..54a6b1f0 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
@@ -9,6 +9,10 @@ public class Statistics {
public String occupanciesFilePath;
+ public String inactiveVehiclesFilePath;
+
+ public String inactiveVehiclesFileName;
+
public String ridesharingFileName;
public Integer statisticIntervalMilis;
@@ -41,6 +45,10 @@ public class Statistics {
public String ridesharingFilePath;
+ public String waitingTimesFilePath;
+
+ public String waitingTimesFileName;
+
public Statistics(Map statistics) {
this.resultFilePath = (String) statistics.get("result_file_path");
this.occupanciesFilePath = (String) statistics.get("occupancies_file_path");
@@ -60,5 +68,9 @@ public Statistics(Map statistics) {
this.serviceFileName = (String) statistics.get("service_file_name");
this.serviceFilePath = (String) statistics.get("service_file_path");
this.ridesharingFilePath = (String) statistics.get("ridesharing_file_path");
+ this.inactiveVehiclesFileName = (String) statistics.get("inactive_vehicles_file_name");
+ this.inactiveVehiclesFilePath = (String) statistics.get("inactive_vehicles_file_path");
+ this.waitingTimesFileName = (String) statistics.get("waiting_times_file_name");
+ this.waitingTimesFilePath = (String) statistics.get("waiting_times_file_path");
}
}
diff --git a/src/main/java/cz/cvut/fel/aic/simod/config/TransferInsertion.java b/src/main/java/cz/cvut/fel/aic/simod/config/TransferInsertion.java
new file mode 100644
index 00000000..c64bf85a
--- /dev/null
+++ b/src/main/java/cz/cvut/fel/aic/simod/config/TransferInsertion.java
@@ -0,0 +1,10 @@
+package cz.cvut.fel.aic.simod.config;
+
+import java.util.Map;
+
+public class TransferInsertion {
+
+ public TransferInsertion(Map transferinsertion) {
+
+ }
+}
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..cb3f9592 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
@@ -205,6 +205,38 @@ public void tripEnded() {
die();
}
+ public void tripPaused() {
+ if (state == DemandAgentState.WAITING) {
+ try {
+ throw new Exception(String.format("Demand Agent %s already stopped", this));
+ } catch (Exception ex) {
+ Logger.getLogger(DemandAgent.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+ else{
+ state = DemandAgentState.TRANSFERING;
+// this.onDemandVehicle = null;
+ eventProcessor.addEvent(StatisticEvent.DEMAND_DROPPED_AT_TRANSFER, null, null,
+ null);
+
+ }
+ }
+
+ public void tripRePaused(OnDemandVehicle vehicle) {
+// if(state == DemandAgentState.DRIVING){
+// try {
+// throw new Exception(String.format("Demand Agent %s already repaused in vehicle %s, it cannot be picked up by"
+// + "another vehicle %s", this, onDemandVehicle, vehicle));
+// } catch (Exception ex) {
+// Logger.getLogger(DemandAgent.class.getName()).log(Level.SEVERE, null, ex);
+// }
+// }
+// else{
+ state = DemandAgentState.DRIVING;
+ this.onDemandVehicle = vehicle;
+// }
+ }
+
public void tripStarted(OnDemandVehicle vehicle) {
if(state == DemandAgentState.DRIVING){
try {
diff --git a/src/main/java/cz/cvut/fel/aic/simod/entity/DemandAgentState.java b/src/main/java/cz/cvut/fel/aic/simod/entity/DemandAgentState.java
index ee8c2f7b..687ee9ab 100644
--- a/src/main/java/cz/cvut/fel/aic/simod/entity/DemandAgentState.java
+++ b/src/main/java/cz/cvut/fel/aic/simod/entity/DemandAgentState.java
@@ -24,5 +24,6 @@
*/
public enum DemandAgentState {
WAITING,
- DRIVING
+ DRIVING,
+ TRANSFERING
}
diff --git a/src/main/java/cz/cvut/fel/aic/simod/entity/OnDemandVehicleState.java b/src/main/java/cz/cvut/fel/aic/simod/entity/OnDemandVehicleState.java
index 4e989e5d..1aaf3aa4 100644
--- a/src/main/java/cz/cvut/fel/aic/simod/entity/OnDemandVehicleState.java
+++ b/src/main/java/cz/cvut/fel/aic/simod/entity/OnDemandVehicleState.java
@@ -24,8 +24,10 @@
*/
public enum OnDemandVehicleState {
WAITING,
+ WAITINGFORTRANSFER,
DRIVING_TO_START_LOCATION,
DRIVING_TO_TARGET_LOCATION,
DRIVING_TO_STATION,
+ DRIVING_TO_TRANSFER_STATION_TO_WAIT,
REBALANCING;
}
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..0aea69b4 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
@@ -204,9 +204,11 @@ public int getIndex(){
}
private OnDemandVehicle getAndRemoveVehicle() {
- OnDemandVehicle nearestVehicle;
+ OnDemandVehicle nearestVehicle = null;
- nearestVehicle = parkedVehicles.remove(0);
+ if (parkedVehicles.size() > 0) {
+ nearestVehicle = parkedVehicles.remove(0);
+ }
return nearestVehicle;
}
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..037ecadd 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
@@ -28,7 +28,9 @@
import cz.cvut.fel.aic.agentpolis.simmodel.Agent;
import cz.cvut.fel.aic.agentpolis.simmodel.IdGenerator;
import cz.cvut.fel.aic.agentpolis.simmodel.activity.PhysicalVehicleDrive;
+import cz.cvut.fel.aic.agentpolis.simmodel.activity.Wait;
import cz.cvut.fel.aic.agentpolis.simmodel.activity.activityFactory.PhysicalVehicleDriveFactory;
+import cz.cvut.fel.aic.agentpolis.simmodel.activity.activityFactory.WaitActivityFactory;
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;
@@ -39,9 +41,7 @@
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.simod.DemandData;
-import cz.cvut.fel.aic.simod.DemandSimulationEntityType;
-import cz.cvut.fel.aic.simod.StationsDispatcher;
+import cz.cvut.fel.aic.simod.*;
import cz.cvut.fel.aic.simod.config.SimodConfig;
import cz.cvut.fel.aic.simod.entity.DemandAgent;
import cz.cvut.fel.aic.simod.entity.OnDemandVehicleState;
@@ -50,6 +50,8 @@
import cz.cvut.fel.aic.simod.event.OnDemandVehicleEvent;
import cz.cvut.fel.aic.simod.event.OnDemandVehicleEventContent;
import cz.cvut.fel.aic.simod.event.RebalancingEventContent;
+import cz.cvut.fel.aic.simod.ridesharing.RideSharingOnDemandVehicle;
+import cz.cvut.fel.aic.simod.ridesharing.model.PlanActionWait;
import cz.cvut.fel.aic.simod.statistics.PickupEventContent;
import cz.cvut.fel.aic.simod.storage.PhysicalTransportVehicleStorage;
import cz.cvut.fel.aic.geographtools.Node;
@@ -122,6 +124,10 @@ public class OnDemandVehicle extends Agent implements EventHandler, PlanningAgen
protected OnDemandVehicleStation parkedIn;
+ public WaitWithStopActivityFactory waitWithStopActivityFactory;
+
+ private WaitActivityFactory waitActivityFactory;
+
@@ -187,6 +193,8 @@ public OnDemandVehicle(
SimodConfig config,
IdGenerator idGenerator,
AgentpolisConfig agentpolisConfig,
+ WaitWithStopActivityFactory waitWithStopActivityFactory,
+ WaitActivityFactory waitActivityFactory,
@Assisted String vehicleId, @Assisted SimulationNode startPosition) {
super(vehicleId, startPosition);
this.tripsUtil = tripsUtil;
@@ -197,6 +205,8 @@ public OnDemandVehicle(
this.timeProvider = timeProvider;
this.rebalancingIdGenerator = rebalancingIdGenerator;
this.config = config;
+ this.waitWithStopActivityFactory = waitWithStopActivityFactory;
+ this.waitActivityFactory = waitActivityFactory;
index = idGenerator.getId();
@@ -252,6 +262,9 @@ public void finishedDriving(boolean wasStopped) {
case REBALANCING:
finishRebalancing();
break;
+// case WAITINGFORTRANSFER:
+// waitForTransfer();
+// break;
}
}
@@ -417,13 +430,48 @@ protected void dropOffDemand() {
currentlyServedDemmand.demandAgent.getSimpleId(), getId()));
}
+ public void startWaiting() {
+ // pokud je auto jinde nez ve stanici, tak chcu vytvorit trip ke stanici, spustit jizdu a az dojede,
+ // tak spustit cekani, ktere je kratsi o cas dojezdu na stanici
+// waitActivityFactory.runActivity(this, ((PlanActionWait) currentTask).getWaitTime());
+ state = OnDemandVehicleState.WAITINGFORTRANSFER;
+// currentPlan.taskCompleted();
+// currentTask = currentPlan.getNextTask();
+ }
+
@Override
protected void onActivityFinish(Activity activity) {
super.onActivityFinish(activity);
- PhysicalVehicleDrive drive = (PhysicalVehicleDrive) activity;
- finishedDriving(drive.isStoped());
+ if (activity instanceof DriveToTransferStation && ((DriveToTransferStation) activity).trip.isEmpty()) {
+ PhysicalVehicleDrive drive = (PhysicalVehicleDrive) activity;
+ if (drive.isStoped()) {
+ finishedDriving(drive.isStoped());
+ }
+ else {
+ startWaiting();
+ }
+ return;
+
+ // try to do nothing
+ }
+ if (activity instanceof PhysicalVehicleDrive) {
+ PhysicalVehicleDrive drive = (PhysicalVehicleDrive) activity;
+ finishedDriving(drive.isStoped());
+ }
+ else if (activity instanceof WaitWithStop) {
+ WaitWithStop wait = (WaitWithStop) activity;
+ finishedWaiting(wait.isStoped());
+ }
+
+ else {
+ finishedDriving(true);
+ }
}
+ public void finishedWaiting(boolean wasStopped) {
+
+ };
+
@Override
public EntityType getType() {
return DemandSimulationEntityType.ON_DEMAND_VEHICLE;
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..98b9fc59 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,10 +25,14 @@
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.activity.activityFactory.WaitActivityFactory;
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.WaitTransferActivityFactory;
+import cz.cvut.fel.aic.simod.WaitWithStop;
+import cz.cvut.fel.aic.simod.WaitWithStopActivityFactory;
import cz.cvut.fel.aic.simod.config.SimodConfig;
import cz.cvut.fel.aic.simod.storage.PhysicalTransportVehicleStorage;
@@ -62,6 +66,9 @@ public class OnDemandVehicleFactory implements OnDemandVehicleFactorySpec{
protected final AgentpolisConfig agentpolisConfig;
+ protected final WaitWithStopActivityFactory waitWithStopActivityFactory;
+
+ protected final WaitActivityFactory waitActivityFactory;
@@ -75,6 +82,8 @@ public OnDemandVehicleFactory(
StandardTimeProvider timeProvider,
IdGenerator rebalancingIdGenerator,
SimodConfig config,
+ WaitWithStopActivityFactory waitWithStopActivityFactory,
+ WaitActivityFactory waitActivityFactory,
IdGenerator idGenerator,
AgentpolisConfig agentpolisConfig) {
this.tripsUtil = tripsUtil;
@@ -87,6 +96,8 @@ public OnDemandVehicleFactory(
this.config = config;
this.idGenerator = idGenerator;
this.agentpolisConfig = agentpolisConfig;
+ this.waitWithStopActivityFactory = waitWithStopActivityFactory;
+ this.waitActivityFactory = waitActivityFactory;
}
@@ -105,6 +116,8 @@ public OnDemandVehicle create(String vehicleId, SimulationNode startPosition){
config,
idGenerator,
agentpolisConfig,
+ waitWithStopActivityFactory,
+ waitActivityFactory,
vehicleId,
startPosition);
}
diff --git a/src/main/java/cz/cvut/fel/aic/simod/event/OnDemandVehicleEvent.java b/src/main/java/cz/cvut/fel/aic/simod/event/OnDemandVehicleEvent.java
index d8ce076d..ddcf97ae 100644
--- a/src/main/java/cz/cvut/fel/aic/simod/event/OnDemandVehicleEvent.java
+++ b/src/main/java/cz/cvut/fel/aic/simod/event/OnDemandVehicleEvent.java
@@ -28,5 +28,6 @@ public enum OnDemandVehicleEvent{
DROP_OFF,
REACH_NEAREST_STATION,
START_REBALANCING,
- FINISH_REBALANCING
+ FINISH_REBALANCING,
+ WAIT
}
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..62ea4225 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
@@ -78,10 +78,11 @@ public void loadStations(){
discarded++;
}
else{
- int initCount = Integer.parseInt(row[1]) + 100;
- if(initCount < 500){
- initCount += 100;
- }
+ // tady vznika tech 200 aut v kazde stanici
+ int initCount = Integer.parseInt(row[1]);
+// if(initCount < 500){
+// initCount += 100;
+// }
createStation(node, initCount, counter++);
}
}
diff --git a/src/main/java/cz/cvut/fel/aic/simod/init/TransferPointsInitializer.java b/src/main/java/cz/cvut/fel/aic/simod/init/TransferPointsInitializer.java
new file mode 100644
index 00000000..a109cde4
--- /dev/null
+++ b/src/main/java/cz/cvut/fel/aic/simod/init/TransferPointsInitializer.java
@@ -0,0 +1,138 @@
+/*
+ * 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.init;
+
+import com.google.inject.Inject;
+import com.univocity.parsers.csv.CsvParser;
+import com.univocity.parsers.csv.CsvParserSettings;
+import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode;
+import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.networks.NodesMappedByIndex;
+import cz.cvut.fel.aic.simod.config.SimodConfig;
+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;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ * @author david
+ */
+public class TransferPointsInitializer {
+ 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 TransferPointsInitializer(OnDemandVehicleStationFactory onDemandVehicleStationFactory, NodesMappedByIndex
+ nodesMappedByIndex, SimodConfig config) {
+ this.onDemandVehicleStationFactory = onDemandVehicleStationFactory;
+ this.nodesMappedByIndex = nodesMappedByIndex;
+ this.config = config;
+ }
+
+
+ public List loadTransferPoints(){
+ List transferPoints = new ArrayList<>();
+ List stationRows = loadTransferPointsRows(config.transferPointsFilepath);
+ LOGGER.info("{} Stations indexes loaded from {}", stationRows.size(), config.transferPointsFilepath);
+
+ int counter = 0;
+ int discarded = 0;
+ for(String[] row: stationRows){
+ int index = Integer.parseInt(row[0]);
+ SimulationNode node = nodesMappedByIndex.getNodeByIndex(index);
+ 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;
+// }
+ transferPoints.add(node);
+ //createStation(node, initCount, counter++);
+ }
+ }
+
+ LOGGER.info("{} Stations Discarded", discarded);
+
+ return transferPoints;
+
+ }
+
+ private List loadTransferPointsRows(String filepath){
+ LOGGER.info("Loading station positions from: {}", filepath);
+
+ try {
+ Reader reader
+ = new BufferedReader(new InputStreamReader(new FileInputStream(filepath), "utf-8"));
+ CsvParserSettings settings = new CsvParserSettings();
+
+ settings.getFormat().setLineSeparator("\r\n");
+
+ //turning off features enabled by default
+ settings.setIgnoreLeadingWhitespaces(false);
+ 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()) {
+ row = it.next();
+ stationRows.add(row);
+ }
+ parser.stopParsing();
+ return stationRows;
+ }
+ catch (FileNotFoundException | UnsupportedEncodingException ex) {
+ Logger.getLogger(DistanceMatrixTravelTimeProvider.class.getName()).log(Level.SEVERE, null, ex);
+ return null;
+ }
+ }
+
+ // TODO: nahradit
+ 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/ridesharing/DroppedDemandsAnalyzer.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/DroppedDemandsAnalyzer.java
index 5a341943..a554bc2f 100644
--- a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/DroppedDemandsAnalyzer.java
+++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/DroppedDemandsAnalyzer.java
@@ -54,15 +54,15 @@ public class DroppedDemandsAnalyzer {
private final OnDemandvehicleStationStorage onDemandvehicleStationStorage;
-
-
-
+
+
+
@Inject
public DroppedDemandsAnalyzer(
- OnDemandVehicleStorage vehicleStorage,
- PositionUtil positionUtil,
- TravelTimeProvider travelTimeProvider,
- SimodConfig config,
+ OnDemandVehicleStorage vehicleStorage,
+ PositionUtil positionUtil,
+ TravelTimeProvider travelTimeProvider,
+ SimodConfig config,
OnDemandvehicleStationStorage onDemandvehicleStationStorage,
AgentpolisConfig agentpolisConfig) {
this.vehicleStorage = vehicleStorage;
@@ -70,20 +70,17 @@ public DroppedDemandsAnalyzer(
this.travelTimeProvider = travelTimeProvider;
this.onDemandvehicleStationStorage = onDemandvehicleStationStorage;
this.config = config;
-
+
// 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;
-
+
// 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;
}
-
-
-
public void debugFail(PlanComputationRequest request, int[] usedVehiclesPerStation) {
boolean freeVehicle = false;
double bestEuclideanDistance = Double.MAX_VALUE;
diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/RideSharingOnDemandVehicle.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/RideSharingOnDemandVehicle.java
index 3b385a7f..27238f62 100644
--- a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/RideSharingOnDemandVehicle.java
+++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/RideSharingOnDemandVehicle.java
@@ -22,31 +22,42 @@
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.planner.trip.Trip;
import cz.cvut.fel.aic.agentpolis.siminfrastructure.planner.trip.VehicleTrip;
import cz.cvut.fel.aic.agentpolis.siminfrastructure.time.StandardTimeProvider;
+import cz.cvut.fel.aic.agentpolis.simmodel.Activity;
import cz.cvut.fel.aic.agentpolis.simmodel.IdGenerator;
import cz.cvut.fel.aic.agentpolis.simmodel.activity.PhysicalVehicleDrive;
+import cz.cvut.fel.aic.agentpolis.simmodel.activity.Wait;
+import cz.cvut.fel.aic.agentpolis.simmodel.activity.activityFactory.CongestedDriveFactory;
import cz.cvut.fel.aic.agentpolis.simmodel.activity.activityFactory.PhysicalVehicleDriveFactory;
+
+import cz.cvut.fel.aic.agentpolis.simmodel.activity.activityFactory.WaitActivityFactory;
+import cz.cvut.fel.aic.agentpolis.simmodel.entity.vehicle.PickUp;
import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.elements.SimulationNode;
+import cz.cvut.fel.aic.agentpolis.simmodel.environment.transportnetwork.init.SimpleMapInitializer;
+import cz.cvut.fel.aic.agentpolis.simulator.creator.SimulationCreator;
import cz.cvut.fel.aic.agentpolis.simulator.visualization.visio.VisioPositionUtil;
+import cz.cvut.fel.aic.agentpolis.system.AgentPolisInitializer;
import cz.cvut.fel.aic.alite.common.event.Event;
import cz.cvut.fel.aic.alite.common.event.EventProcessor;
-import cz.cvut.fel.aic.simod.StationsDispatcher;
+import cz.cvut.fel.aic.simod.*;
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.event.OnDemandVehicleEventContent;
+import cz.cvut.fel.aic.simod.mapVisualization.MapVisualiserModule;
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.PlanActionCurrentPosition;
-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.ridesharing.model.*;
import cz.cvut.fel.aic.simod.statistics.PickupEventContent;
import cz.cvut.fel.aic.simod.storage.PhysicalTransportVehicleStorage;
+import cz.cvut.fel.aic.simod.traveltimecomputation.TravelTimeProvider;
import cz.cvut.fel.aic.simod.visio.PlanLayerTrip;
+import org.opengis.filter.PropertyIsGreaterThanOrEqualTo;
+
+import java.io.File;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
@@ -67,10 +78,30 @@ public class RideSharingOnDemandVehicle extends OnDemandVehicle{
private IdGenerator tripIdGenerator;
+ private WaitActivityFactory waitActivityFactory;
+
+ private TravelTimeProvider travelTimeProvider;
+
+ private DriveToTransferStationActivityFactory driveToTransferStationActivityFactory;
+
+ public boolean tripAlreadyPlanned = false;
+
public DriverPlan getCurrentPlan() {
currentPlan.updateCurrentPosition(getPosition());
return currentPlan;
}
+
+ public DriverPlan getCurrentPlanNoUpdate() {
+ return currentPlan;
+ }
+
+ public void setCurrentPlan(DriverPlan driverPlan) {
+ List newPlan = new ArrayList<>();
+ newPlan.add(currentPlan.plan.get(0));
+ currentPlan.plan = newPlan;
+ currentPlan.updateCurrentPosition(getPosition());
+ currentPlan.plan.addAll(driverPlan.plan);
+ }
@@ -89,6 +120,9 @@ public RideSharingOnDemandVehicle(
SimodConfig config,
IdGenerator idGenerator,
AgentpolisConfig agentpolisConfig,
+ WaitWithStopActivityFactory waitWithStopActivityFactory,
+ WaitActivityFactory waitActivityFactory,
+ DriveToTransferStationActivityFactory driveToTransferStationActivityFactory,
@Assisted String vehicleId, @Assisted SimulationNode startPosition) {
super(
vehicleStorage,
@@ -102,10 +136,16 @@ public RideSharingOnDemandVehicle(
config,
idGenerator,
agentpolisConfig,
+ waitWithStopActivityFactory,
+ waitActivityFactory,
vehicleId,
startPosition);
this.positionUtil = positionUtil;
this.tripIdGenerator = tripIdGenerator;
+
+ this.waitWithStopActivityFactory = waitWithStopActivityFactory;
+ this.waitActivityFactory = waitActivityFactory;
+ this.driveToTransferStationActivityFactory = driveToTransferStationActivityFactory;
// empty plan
LinkedList plan = new LinkedList<>();
@@ -127,11 +167,35 @@ public int getFreeCapacity(){
}
public void replan(DriverPlan plan){
- currentPlan = plan;
+ currentPlan = plan;
// The vehicle now waits, we have to start moving.
if(state == OnDemandVehicleState.WAITING && plan.getLength() > 1){
driveToNextTask();
}
+ if (state == OnDemandVehicleState.WAITINGFORTRANSFER) {
+ // if top akce neni stejna jako currentTask (currentTask je cekani)
+ if (currentPlan.getNextTask() != currentTask) {
+ ((PlanActionWait) currentTask).setWaitingPaused(true);
+ ((PlanActionWait) currentTask).setWaitingPausedAt(timeProvider.getCurrentSimTime());
+ ((WaitWithStop) getCurrentTopLevelActivity()).end();
+ // ted potrebuji aktivitu ukoncit, ona ale stale bezi
+ driveToNextTask();
+ }
+ // jinak pokracovat v aktivite
+ // todo priradit stop time
+ // a ukoncit aktivitu
+ // todo tam kde se spousti cekani, tak reagovat na start a stop time
+ // auto je v prubehu vykonavani wait akce
+ }
+ if (state == OnDemandVehicleState.DRIVING_TO_TRANSFER_STATION_TO_WAIT) {
+ if (currentPlan.getNextTask() != currentTask) {
+ // pokud se zmenila current task, tak ukoncim cestu na stanici
+ ((PhysicalVehicleDrive) getCurrentTopLevelActivity()).end();
+ }
+ // jinak necham aktivitu pokracovat
+
+// driveToNextTask();
+ }
// SPECIAL CASES - we don't have to do anything and let the current Drive action continue.
else if(
@@ -151,17 +215,26 @@ else if(
@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();
+ if (currentTask instanceof PlanActionPickup) {
+ if(((PlanActionPickup) currentTask).request.isOnboard()){
+ currentPlan.taskCompleted();
+ driveToNextTask();
+ }
}
+// else {
+// if(((PlanActionPickupTransfer) 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();
+// DemandAgent demandAgent = ((PlanActionPickup) currentTask).getRequest().getDemandAgent();
driveFactory.runActivity(this, vehicle, currentTrip);
}
}
@@ -170,7 +243,12 @@ protected void driveToDemandStartLocation() {
protected void driveToTargetLocation() {
state = OnDemandVehicleState.DRIVING_TO_TARGET_LOCATION;
if(getPosition().id == currentTask.getPosition().id){
- dropOffAndContinue();
+ if (currentTask instanceof PlanActionDropoff) {
+ dropOffAndContinue();
+ } else if (currentTask instanceof PlanActionDropoffTransfer) {
+// dropoffTransferAndContinue();
+ dropOffAndContinue();
+ }
}
else{
currentTrip = tripsUtil.createTrip(getPosition(), currentTask.getPosition(), vehicle);
@@ -192,25 +270,70 @@ protected void driveToNearestStation() {
}
}
+ @Override
+ public void finishedWaiting(boolean wasStopped) {
+ if (wasStopped) {
+// driveToNextTask();
+ } else {
+ currentPlan.taskCompleted();
+ currentTask = currentPlan.getNextTask();
+ if (currentTask instanceof PlanActionWait) {
+ startWaiting();
+ } else if (currentTask instanceof PlanActionPickup || currentTask instanceof PlanActionPickupTransfer) {
+ pickupAndContinue();
+ } else if (currentTask instanceof PlanActionDropoff || currentTask instanceof PlanActionDropoffTransfer) {
+ dropOffAndContinue();
+ }
+ }
+ }
+
+ @Override
+ public void startWaiting() {
+ // pokud je auto jinde nez ve stanici, tak chcu vytvorit trip ke stanici, spustit jizdu a az dojede,
+ // tak spustit cekani, ktere je kratsi o cas dojezdu na stanici
+ state = OnDemandVehicleState.WAITINGFORTRANSFER;
+ if (currentTask instanceof PlanActionWait) {
+ long substractTime = 0;
+ if (((PlanActionWait) currentTask).isWaitingPaused()) {
+ substractTime = ((PlanActionWait) currentTask).getWaitingPausedAt() - ((PlanActionWait) currentTask).getWaitingStartedAt();
+ }
+ ((PlanActionWait) currentTask).setWaitingStarted(true);
+ ((PlanActionWait) currentTask).setWaitingStartedAt(timeProvider.getCurrentSimTime());
+ ((PlanActionWait) currentTask).setWaitingPaused(false);
+ long waitTime = ((PlanActionWait) currentTask).getWaitTime();
+ waitWithStopActivityFactory.runActivity(this, waitTime - substractTime);
+ } else {
+ driveToNextTask();
+ }
+
+
+ }
+
@Override
public void finishedDriving(boolean wasStopped) {
- logTraveledDistance(wasStopped);
-
+
if(wasStopped){
driveToNextTask();
}
else{
switch(state){
+ // start location agenta - pickup misto
case DRIVING_TO_START_LOCATION:
+ logTraveledDistance(wasStopped);
pickupAndContinue();
break;
+ // dropoff misto agenta
case DRIVING_TO_TARGET_LOCATION:
+ logTraveledDistance(wasStopped);
dropOffAndContinue();
break;
+ // stanice auta
case DRIVING_TO_STATION:
+ logTraveledDistance(wasStopped);
finishDrivingToStation();
break;
case REBALANCING:
+ logTraveledDistance(wasStopped);
finishRebalancing();
break;
}
@@ -238,26 +361,83 @@ private void driveToNextTask() {
if(currentTask instanceof PlanActionPickup){
driveToDemandStartLocation();
}
- else{
+ else if(currentTask instanceof PlanActionWait) {
+ if (currentTask.getPosition() == this.getPosition()) {
+ startWaiting();
+ } else {
+ // drive to station and begin waiting
+ if (this.tripAlreadyPlanned) {
+ return;
+ }
+ // else make new trip and start driving with edited wait time
+ VehicleTrip newTrip = tripsUtil.createTrip(this.getPosition(), currentTask.getPosition(), vehicle);
+ this.currentTrip = newTrip;
+ state = OnDemandVehicleState.DRIVING_TO_TRANSFER_STATION_TO_WAIT;
+// driveFactory.create(this, vehicle, currentTrip).run();
+ driveToTransferStationActivityFactory.create(this, vehicle, currentTrip).run();
+ this.tripAlreadyPlanned = true;
+
+
+
+ }
+
+ }
+ else if(currentTask instanceof PlanActionPickupTransfer) {
+ driveToDemandStartLocation();
+ }
+ else if(currentTask instanceof PlanActionDropoffTransfer) {
+ driveToTargetLocation();
+ }
+ else // dropoff
+ {
driveToTargetLocation();
}
}
}
private void pickupAndContinue() {
+// state = OnDemandVehicleState.DRIVING_TO_TARGET_LOCATION;
try {
- DemandAgent demandAgent = ((PlanActionPickup) currentTask).getRequest().getDemandAgent();
- if(demandAgent.isDropped()){
- long currentTime = timeProvider.getCurrentSimTime();
- long droppTime = demandAgent.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));
+ DemandAgent demandAgent;
+ if (currentTask instanceof PlanActionPickup) {
+ demandAgent = ((PlanActionPickup) currentTask).getRequest().getDemandAgent();
+ if(demandAgent.isDropped()){
+ long currentTime = timeProvider.getCurrentSimTime();
+ long droppTime = demandAgent.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));
+ }
+ demandAgent.tripStarted(this);
}
- demandAgent.tripStarted(this);
+ else if (currentTask instanceof PlanActionPickupTransfer) {
+ demandAgent = ((PlanActionPickupTransfer) currentTask).getRequest().getDemandAgent();
+ if(demandAgent.isDropped()){
+ long currentTime = timeProvider.getCurrentSimTime();
+ long droppTime = demandAgent.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));
+ }
+ demandAgent.tripRePaused(this);
+ } else {
+ // should not be
+ throw new Exception(String.format("Wrong action order in plan"));
+
+ }
+
+// if(demandAgent.isDropped()){
+// long currentTime = timeProvider.getCurrentSimTime();
+// long droppTime = demandAgent.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));
+// }
+// demandAgent.tripStarted(this);
vehicle.pickUp(demandAgent);
// statistics TODO demand tirp?
+
// 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?
@@ -274,8 +454,16 @@ private void pickupAndContinue() {
}
private void dropOffAndContinue() {
- DemandAgent demandAgent = ((PlanActionDropoff) currentTask).getRequest().getDemandAgent();
- demandAgent.tripEnded();
+ DemandAgent demandAgent = null;
+ if (currentTask instanceof PlanActionDropoff) {
+ demandAgent = ((PlanActionDropoff) currentTask).getRequest().getDemandAgent();
+ demandAgent.tripEnded();
+ } else
+ {
+ demandAgent = ((PlanActionDropoffTransfer) currentTask).getRequest().getDemandAgent();
+ demandAgent.tripPaused();
+ }
+
vehicle.dropOff(demandAgent);
// statistics
@@ -298,6 +486,10 @@ public VehicleTrip getCurrentTripPlan() {
return currentTrip;
}
+ public PlanAction getCurrentTask() {
+ return currentTask;
+ }
+
public boolean hasFreeCapacity() {
return getFreeCapacity() > 0;
}
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..95562631 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
@@ -253,13 +253,16 @@ public void handleEvent(Event event) {
if(eventType == OnDemandVehicleEvent.PICKUP){
OnDemandVehicleEventContent eventContent = (OnDemandVehicleEventContent) event.getContent();
PlanComputationRequest request = requestsMapByDemandAgents.get(eventContent.getDemandId());
- if(!waitingRequests.remove(request)){
- try {
- throw new 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);
+ if (waitingRequests.contains(request)) {
+ if (!waitingRequests.remove(request)) {
+ try {
+ throw new 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);
}
}
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..939dbe61 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,10 +24,11 @@
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.WaitActivityFactory;
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.*;
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.OnDemandVehicleFactory;
@@ -39,19 +40,27 @@
*/
@Singleton
public class RidesharingOnDemandVehicleFactory extends OnDemandVehicleFactory{
+
+ WaitWithStopActivityFactory waitWithStopActivityFactory;
+
+ DriveToTransferStationActivityFactory driveToTransferStationActivityFactory;
@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) {
+ AgentpolisConfig agentpolisConfig,
+ WaitWithStopActivityFactory waitWithStopActivityFactory,
+ WaitActivityFactory waitActivityFactory,
+ DriveToTransferStationActivityFactory driveToTransferStationActivityFactory
+ ) {
super(
vehicleStorage,
tripsUtil,
@@ -60,9 +69,14 @@ public RidesharingOnDemandVehicleFactory(
eventProcessor,
timeProvider,
rebalancingIdGenerator,
- config,
+ config,
+ waitWithStopActivityFactory,
+ waitActivityFactory,
idGenerator,
agentpolisConfig);
+ this.waitWithStopActivityFactory = waitWithStopActivityFactory;
+ this.driveToTransferStationActivityFactory = driveToTransferStationActivityFactory;
+
}
@Override
@@ -80,8 +94,12 @@ public OnDemandVehicle create(String vehicleId, SimulationNode startPosition) {
config,
idGenerator,
agentpolisConfig,
+ waitWithStopActivityFactory,
+ waitActivityFactory,
+ driveToTransferStationActivityFactory,
vehicleId,
- startPosition);
+ startPosition)
+ ;
}
diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTNoFreezeSolver.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTNoFreezeSolver.java
new file mode 100644
index 00000000..bad8e87d
--- /dev/null
+++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTNoFreezeSolver.java
@@ -0,0 +1,1503 @@
+package cz.cvut.fel.aic.simod.ridesharing.greedyTASeT;
+
+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.trip.VehicleTrip;
+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.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.event.OnDemandVehicleEvent;
+import cz.cvut.fel.aic.simod.ridesharing.DARPSolver;
+import cz.cvut.fel.aic.simod.ridesharing.DroppedDemandsAnalyzer;
+import cz.cvut.fel.aic.simod.ridesharing.PlanCostProvider;
+import cz.cvut.fel.aic.simod.ridesharing.RideSharingOnDemandVehicle;
+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.storage.OnDemandvehicleStationStorage;
+import cz.cvut.fel.aic.simod.traveltimecomputation.TravelTimeProvider;
+import org.jgrapht.alg.util.Pair;
+
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+
+@Singleton
+public class GreedyTASeTNoFreezeSolver extends DARPSolver implements EventHandler {
+
+
+ private final TypedSimulation eventProcessor;
+
+ private final SimodConfig config;
+
+ private final TimeProvider timeProvider;
+
+ private final PositionUtil positionUtil;
+
+ private final DroppedDemandsAnalyzer droppedDemandsAnalyzer;
+
+ private final OnDemandvehicleStationStorage onDemandvehicleStationStorage;
+
+ private final double maxDistance = 100;
+
+ private final double maxDistanceSquared = 10000;
+
+ private final int maxDelayTime = 10;
+
+ private List transferPoints;
+
+ protected final DefaultPlanComputationRequest.DefaultPlanComputationRequestFactory requestFactory;
+
+ private Map planMap;
+
+
+
+
+ @Inject
+ public GreedyTASeTNoFreezeSolver(
+ OnDemandVehicleStorage vehicleStorage,
+ TravelTimeProvider travelTimeProvider,
+ PlanCostProvider travelCostProvider,
+ DefaultPlanComputationRequest.DefaultPlanComputationRequestFactory requestFactory,
+ TypedSimulation eventProcessor,
+ SimodConfig config,
+ TimeProvider timeProvider,
+ PositionUtil positionUtil,
+ DroppedDemandsAnalyzer droppedDemandsAnalyzer,
+ OnDemandvehicleStationStorage onDemandvehicleStationStorage,
+ AgentpolisConfig agentpolisConfig) {
+
+ super(vehicleStorage, travelTimeProvider, travelCostProvider, requestFactory);
+ this.eventProcessor = eventProcessor;
+ this.config = config;
+ this.timeProvider = timeProvider;
+ this.positionUtil = positionUtil;
+ this.droppedDemandsAnalyzer = droppedDemandsAnalyzer;
+ this.onDemandvehicleStationStorage = onDemandvehicleStationStorage;
+ this.requestFactory = requestFactory;
+
+ setEventHandeling();
+ }
+
+ public void setTransferPoints(List transferPoints) {
+ this.transferPoints = transferPoints;
+ }
+
+ @Override
+ public EventProcessor getEventProcessor() {
+ return eventProcessor;
+ }
+
+ @Override
+ public void handleEvent(Event event) {
+
+ }
+
+
+ private void setEventHandeling() {
+ List typesToHandle = new LinkedList<>();
+
+ typesToHandle.add(OnDemandVehicleEvent.PICKUP);
+ eventProcessor.addEventHandler(this, typesToHandle);
+ }
+
+ /**
+ * Transfer-allowed scheduling solver
+ * @return Map
+ */
+ @Override
+ public Map solve(List newRequests, List waitingRequests) {
+ Map planMap = new ConcurrentHashMap<>();
+ Map planMapReturn = new ConcurrentHashMap<>();
+ List taxis = new ArrayList<>();
+
+ for(AgentPolisEntity tVvehicle: vehicleStorage.getEntitiesForIteration()) {
+ RideSharingOnDemandVehicle vehicle = (RideSharingOnDemandVehicle) tVvehicle;
+ taxis.add(vehicle);
+ }
+
+ planMap = dispatch(taxis, newRequests);
+
+
+
+ return planMap;
+ }
+
+ /**
+ * Transfer-allowed scheduling function
+ * @return
+ */
+ private Map dispatch(List taxis, List requests) {
+ // because all passengers allow ridesharing, only greedy taset will be called
+ List carpoolAcceptingTaxis = taxis;
+ List carpoolAcceptingPassengers = requests;
+ Map map = heuristics(carpoolAcceptingTaxis, carpoolAcceptingPassengers);
+ return map;
+ }
+
+
+ private boolean isWithTransfer(DriverPlan plan) {
+ for(PlanAction action : plan.plan) {
+ if(action instanceof PlanRequestAction) {
+ if (action instanceof PlanActionDropoffTransfer || action instanceof PlanActionPickupTransfer || action instanceof PlanActionWait) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ private int findLastPickupIndex(DriverPlan plan) {
+ int index = -1;
+ for (int i = 0; i < plan.getLength(); i++) {
+ if (plan.plan.get(i) instanceof PlanActionPickup) {
+ index = i;
+ }
+ }
+ return index;
+ }
+
+ private int findLastPickupIndexList(List plan) {
+ int index = -1;
+ for (int i = 0; i < plan.size(); i++) {
+ if (plan.get(i) instanceof PlanActionPickup) {
+ index = i;
+ }
+ }
+ return index;
+ }
+
+ private int findLastTransferActionIndex(DriverPlan plan) {
+ int index = -1;
+ for (int i = 0; i < plan.getLength(); i++) {
+ if (plan.plan.get(i) instanceof PlanActionDropoffTransfer || plan.plan.get(i) instanceof PlanActionPickupTransfer || plan.plan.get(i) instanceof PlanActionWait) {
+ index = i;
+ }
+ }
+ return index;
+ }
+
+ private long countTimeToNewPickup(RideSharingOnDemandVehicle taxi, PlanComputationRequest request, List requestsOnBoard) {
+ DriverPlan taxiPlan;
+ if (planMap.containsKey(taxi)) {
+ taxiPlan = planMap.get(taxi);
+ } else {
+ taxiPlan = taxi.getCurrentPlanNoUpdate();
+ }
+ if (isWithTransfer(taxiPlan)) {
+ // nekdo prestupuje
+ int indexLastTransferAction = findLastTransferActionIndex(taxiPlan);
+ long timeToFinishCurrentEdge = 0;
+ SimulationNode previousPos = taxi.getPosition();
+ if (taxi.getCurrentTask() != null) {
+ timeToFinishCurrentEdge = travelTimeProvider.getTravelTime(taxi, taxi.getCurrentTask().getPosition());
+ previousPos = taxi.getCurrentTask().getPosition();
+ }
+ long timeToLastTransferAction = 0;
+ for (int q = 0; q < indexLastTransferAction + 1; q++) {
+ if (taxiPlan.plan.get(q) instanceof PlanActionWait) {
+ PlanActionWait wait = (PlanActionWait) taxiPlan.plan.get(q);
+ timeToLastTransferAction = timeToLastTransferAction + wait.getWaitTime();
+ } else {
+ timeToLastTransferAction = timeToLastTransferAction + travelTimeProvider.getExpectedTravelTime(previousPos, taxiPlan.plan.get(q).getPosition());
+ }
+ previousPos = taxiPlan.plan.get(q).getPosition();
+ }
+ // ted potrebuju najit posledni pickup ve zbyvajicim driver planu po prestupu
+ List segmentAfterTransfer = taxiPlan.plan.subList(indexLastTransferAction+1, taxiPlan.plan.size());
+ int indexLastPickupSegment = findLastPickupIndexList(segmentAfterTransfer);
+ long timeToLastPickup = 0;
+ SimulationNode previousPos2 = taxiPlan.plan.get(taxiPlan.plan.size()-1).getPosition();
+ if (segmentAfterTransfer.size() > 0) {
+ previousPos2 = segmentAfterTransfer.get(0).getPosition();
+ for (int q = 0; q < indexLastPickupSegment + 1; q++) {
+ timeToLastPickup = timeToLastPickup + travelTimeProvider.getExpectedTravelTime(previousPos2, segmentAfterTransfer.get(q).getPosition());
+ previousPos2 = segmentAfterTransfer.get(q).getPosition();
+ }
+ }
+ SimulationNode newPickupFrom = request.getFrom();
+ long timeToNewPick = travelTimeProvider.getExpectedTravelTime(previousPos2, newPickupFrom);
+ long estimatedArrivalToPickup = timeProvider.getCurrentSimTime() + timeToFinishCurrentEdge + timeToLastTransferAction + timeToLastPickup + timeToNewPick;
+ long maxTime = request.getMaxDropoffTime() * 1000;
+ if (estimatedArrivalToPickup > maxTime) {
+ return Long.MAX_VALUE;
+ }
+ return estimatedArrivalToPickup;
+ }
+ else {
+ //neprestupuje nikdo
+ int indexLastPickup = findLastPickupIndex(taxiPlan);
+ long timeToFinishCurrentEdge = 0;
+ SimulationNode previousPos = taxi.getPosition();
+ if (taxi.getCurrentTask() != null) {
+ timeToFinishCurrentEdge = travelTimeProvider.getTravelTime(taxi, taxi.getCurrentTask().getPosition());
+ previousPos = taxi.getCurrentTask().getPosition();
+ }
+ long timeToLastPickup = 0;
+ for (int q = 0; q < indexLastPickup + 1; q++) {
+ timeToLastPickup = timeToLastPickup + travelTimeProvider.getExpectedTravelTime(previousPos, taxiPlan.plan.get(q).getPosition());
+ previousPos = taxiPlan.plan.get(q).getPosition();
+ }
+ SimulationNode newPickupFrom = request.getFrom();
+ long timeToNewPick = travelTimeProvider.getExpectedTravelTime(previousPos, newPickupFrom);
+ long estimatedArrivalToNewPickup = timeProvider.getCurrentSimTime() + timeToFinishCurrentEdge + timeToLastPickup + timeToNewPick;
+ long maxTime = request.getMaxDropoffTime() * 1000;
+ if (estimatedArrivalToNewPickup > maxTime) {
+ return Long.MAX_VALUE;
+ }
+ return estimatedArrivalToNewPickup;
+ }
+ }
+
+ /**
+ * Greedy TASeT heuristics function
+ * @return
+ */
+ private Map heuristics(List taxis, List requests) {
+ //transfer points = charging stations
+ List transferPoints = this.transferPoints;
+
+ //lookup table LT - LT [t][k] stores the earliest arrival time for taxi k to charging station t without violating the tolerable delay for k’s current passengers
+ int stationsCount = transferPoints.size();
+ int taxisCount = taxis.size();
+ long[][] LT = new long[stationsCount][taxisCount];
+ //fill the LT table
+ for (int i = 0; i < taxisCount; i++) {
+ RideSharingOnDemandVehicle taxi = taxis.get(i);
+ SimulationNode taxiPosition = taxis.get(i).getPosition();
+ Set requestsOnBoardSet = new HashSet<>();
+ DriverPlan actualPlan = taxi.getCurrentPlanNoUpdate();
+ for(PlanAction action : actualPlan) {
+ if(action instanceof PlanRequestAction) {
+ PlanRequestAction requestAction = (PlanRequestAction) action;
+ requestsOnBoardSet.add(requestAction.request);
+ }
+ }
+ List requestsOnBoard = new ArrayList<>(requestsOnBoardSet);
+ // kolik lidi je prave ted v aute
+ boolean taxiFree = true;
+ int taxiCapacity = taxi.getCapacity();
+ if (requestsOnBoardSet.size() >= taxiCapacity) {
+ taxiFree = false;
+ }
+ for(int j = 0; j < stationsCount; j++) {
+ //check if taxi has free seat
+ if (!taxiFree) {
+ LT[j][i] = Long.MAX_VALUE;
+ }
+ else {
+ if (isWithTransfer(taxi.getCurrentPlanNoUpdate())) {
+ // nekdo prestupuje
+ int indexLastTransferAction = findLastTransferActionIndex(taxi.getCurrentPlanNoUpdate());
+ long timeToFinishCurrentEdge = 0;
+ SimulationNode previousPos = taxi.getPosition();
+ if (taxi.getCurrentTask() != null) {
+ timeToFinishCurrentEdge = travelTimeProvider.getTravelTime(taxi, taxi.getCurrentTask().getPosition());
+ previousPos = taxi.getCurrentTask().getPosition();
+ }
+ long timeToLastTransferAction = 0;
+ for (int q = 0; q < indexLastTransferAction + 1; q++) {
+ if (taxi.getCurrentPlanNoUpdate().plan.get(q) instanceof PlanActionWait) {
+ PlanActionWait wait = (PlanActionWait) taxi.getCurrentPlanNoUpdate().plan.get(q);
+ timeToLastTransferAction = timeToLastTransferAction + wait.getWaitTime();
+ } else {
+ timeToLastTransferAction = timeToLastTransferAction + travelTimeProvider.getExpectedTravelTime(previousPos, taxi.getCurrentPlanNoUpdate().plan.get(q).getPosition());
+ }
+ previousPos = taxi.getCurrentPlanNoUpdate().plan.get(q).getPosition();
+ }
+ // ted potrebuju najit posledni pickup ve zbyvajicim driver planu po prestupu
+ List segmentAfterTransfer = taxi.getCurrentPlanNoUpdate().plan.subList(indexLastTransferAction+1, taxi.getCurrentPlanNoUpdate().plan.size());
+ int indexLastPickupSegment = findLastPickupIndexList(segmentAfterTransfer);
+ long timeToLastPickup = 0;
+ SimulationNode previousPos2 = taxi.getCurrentPlanNoUpdate().plan.get(taxi.getCurrentPlanNoUpdate().plan.size()-1).getPosition();
+ if (segmentAfterTransfer.size() > 0) {
+ previousPos2 = segmentAfterTransfer.get(0).getPosition();
+ for (int q = 0; q < indexLastPickupSegment + 1; q++) {
+ timeToLastPickup = timeToLastPickup + travelTimeProvider.getExpectedTravelTime(previousPos2, segmentAfterTransfer.get(q).getPosition());
+ previousPos2 = segmentAfterTransfer.get(q).getPosition();
+ }
+ }
+ SimulationNode station = transferPoints.get(j);
+ long timeToStation = travelTimeProvider.getExpectedTravelTime(previousPos, station);
+ long estimatedArrivalToStation = timeProvider.getCurrentSimTime() + timeToFinishCurrentEdge + timeToLastTransferAction + timeToLastPickup + timeToStation;
+ LT[j][i] = estimatedArrivalToStation;
+ // zkontrolovat, zda arrival je v pohode z hlediska delay - kontroluju pro requesty po ukonceni prestupu
+ Set requestsInSegmentSet = new HashSet<>();
+ for(PlanAction action : segmentAfterTransfer) {
+ if(action instanceof PlanRequestAction) {
+ PlanRequestAction requestAction = (PlanRequestAction) action;
+ requestsInSegmentSet.add(requestAction.request);
+ }
+ }
+ List requestsInSegment = new ArrayList<>(requestsInSegmentSet);
+ for (PlanComputationRequest request : requestsInSegment) {
+ long maxTime = request.getMaxDropoffTime() * 1000;
+ if (LT[j][i] > maxTime) {
+ LT[j][i] = Long.MAX_VALUE;
+ break;
+ }
+ }
+ }
+ else {
+ //neprestupuje nikdo
+ int indexLastPickup = findLastPickupIndex(taxi.getCurrentPlanNoUpdate());
+ long timeToFinishCurrentEdge = 0;
+ SimulationNode previousPos = taxi.getPosition();
+ if (taxi.getCurrentTask() != null) {
+ timeToFinishCurrentEdge = travelTimeProvider.getTravelTime(taxi, taxi.getCurrentTask().getPosition());
+ previousPos = taxi.getCurrentTask().getPosition();
+ }
+ long timeToLastPickup = 0;
+ for (int q = 0; q < indexLastPickup + 1; q++) {
+ timeToLastPickup = timeToLastPickup + travelTimeProvider.getExpectedTravelTime(previousPos, taxi.getCurrentPlanNoUpdate().plan.get(q).getPosition());
+ previousPos = taxi.getCurrentPlanNoUpdate().plan.get(q).getPosition();
+ }
+ SimulationNode station = transferPoints.get(j);
+ long timeToStation = travelTimeProvider.getExpectedTravelTime(previousPos, station);
+ long estimatedArrivalToStation = timeProvider.getCurrentSimTime() + timeToFinishCurrentEdge + timeToLastPickup + timeToStation;
+ LT[j][i] = estimatedArrivalToStation;
+ // zkontrolovat, zda arrival je v pohode z hlediska delay
+ for (PlanComputationRequest request : requestsOnBoard) {
+ long maxTime = request.getMaxDropoffTime() * 1000;
+ if (LT[j][i] > maxTime) {
+ LT[j][i] = Long.MAX_VALUE;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ //we rank the requests in descending order by the number of taxis that are possible to pick them up in time (without considering transfer or destination)
+ //get possible taxis for every request and number of possible taxis
+ int[] possiblePickupTaxisCounts = new int[requests.size()];
+ int i = 0;
+ Map> possiblePickupTaxisMap = new HashMap<>();
+ for(PlanComputationRequest request : requests) {
+ int counter = 0;
+ List possiblePickupTaxisOneRequest = new ArrayList<>();
+ for(RideSharingOnDemandVehicle t : taxis) {
+ if (canServeRequestTASeT2(t, request)) {
+ counter++;
+ possiblePickupTaxisOneRequest.add(t);
+ }
+ }
+ possiblePickupTaxisCounts[i] = counter;
+ possiblePickupTaxisMap.put(request, possiblePickupTaxisOneRequest);
+ i++;
+ }
+
+
+ //sort R by the number of possible pickup taxis
+ List requestsCopy = new ArrayList<>(requests);
+ requests.sort(Comparator.comparing(x -> possiblePickupTaxisCounts[requestsCopy.indexOf(x)]));
+ //order to descending order
+ Collections.reverse(requests);
+
+ planMap = new ConcurrentHashMap<>();
+
+
+ for(PlanComputationRequest request : requests) {
+ List>, List>> templistP = new ArrayList<>();
+ // list ve kterem je list dvojic - list dvojic, protoze dvojice muze byt jen jedna (neni prestup) nebo dve (je prestup)
+ List delays = new ArrayList<>();
+ List transferTimes = new ArrayList<>();
+ List canPickupRequestTaxis = possiblePickupTaxisMap.get(request);
+ for (RideSharingOnDemandVehicle taxi : canPickupRequestTaxis) {
+ List posbitnry = findPlanWithNoTransferNew(request, taxi);
+ // pokud neexistuje ani jeden validni itinerar, tak je posbitnry null
+ // tehdy ho nebudu pridavat do templistu
+ if (posbitnry != null) {
+ if (checkValidItinerary(posbitnry, taxi)) {
+ List> tmp = new ArrayList<>();
+ List tmpVehs = new ArrayList<>();
+ tmpVehs.add(taxi);
+ tmp.add(posbitnry);
+ Pair>, List> pair = new Pair<>(tmp, tmpVehs);
+ templistP.add(pair);
+ long minimalArrivalTime = timeProvider.getCurrentSimTime() + travelTimeProvider.getExpectedTravelTime(request.getFrom(), request.getTo());
+ HashMap dropoffs = getEstimatedTimesOfDropoff(posbitnry, taxi);
+ long realArrivalTime = dropoffs.get(request);
+ long delay = realArrivalTime - minimalArrivalTime;
+ delays.add(delay);
+ transferTimes.add((long) 0);
+ }
+ }
+ Set requestsOnBoardSet = new HashSet<>();
+ DriverPlan actualPlan;
+ if (planMap.containsKey(taxi)) {
+ actualPlan = planMap.get(taxi);
+ } else {
+ actualPlan = taxi.getCurrentPlanNoUpdate();
+ }
+ for(PlanAction action : actualPlan) {
+ if(action instanceof PlanRequestAction) {
+ PlanRequestAction requestAction = (PlanRequestAction) action;
+ requestsOnBoardSet.add(requestAction.request);
+ }
+ }
+ List requestsOnBoard = new ArrayList<>(requestsOnBoardSet);
+
+ long timeToNewPickup = countTimeToNewPickup(taxi, request, requestsOnBoard);
+ int stationIndex = 0;
+ for (SimulationNode station : transferPoints) {
+ // je stanice potencialne vhodna pro prestup?
+ if (timeToNewPickup + travelTimeProvider.getExpectedTravelTime(request.getFrom(), station) >
+ request.getMaxDropoffTime() * 1000 - travelTimeProvider.getExpectedTravelTime(station, request.getTo())) {
+ continue;
+ }
+
+ // find k' = taxis that taxi k can transfer to at station
+ for (int k = 0; k < taxisCount; k++) {
+ // minimalni cas na druhy usek
+ //not possible to transfer to
+ if (LT[stationIndex][k] == Long.MAX_VALUE) {
+ continue;
+ } else if(LT[stationIndex][k] > request.getMaxDropoffTime() * 1000 - travelTimeProvider.getExpectedTravelTime(station, request.getTo())) {
+ continue;
+ } else if(taxi.equals(taxis.get(k))) {
+ continue;
+ } else if (station == request.getTo()) {
+ continue;
+ } else if (station == request.getFrom()) {
+ continue;
+ } else {
+ // split request to two requests with transfer point
+ long travelTimeFromStationToDest = travelTimeProvider.getExpectedTravelTime(station, request.getTo());
+ int maxDropOffTime = request.getMaxDropoffTime() - (int) Math.round(travelTimeFromStationToDest / 1000.0);
+ PlanActionDropoffTransfer dropoffActionTransfer = new PlanActionDropoffTransfer(request, station, maxDropOffTime);
+ PlanActionPickupTransfer pickupActionTransfer = new PlanActionPickupTransfer(request, station, maxDropOffTime);
+
+ List itnryp1 = findPlanWithNoTransferActionsNew(request.getPickUpAction(), dropoffActionTransfer, taxi); // pro auto
+ List itnryp2 = findPlanWithNoTransferActionsNew(pickupActionTransfer, request.getDropOffAction(), taxis.get(k));
+ if (itnryp1 == null || itnryp2 == null) {
+ // neexistuje plan
+ continue;
+ }
+ Pair>, Long> p = createChargePlanNoNewRequests(itnryp1, itnryp2, taxi, taxis.get(k), request);
+ if (p == null) {
+ // neni zadny validni plan a tedy neni mozne prestoupit, takze neudelam nic
+ continue;
+ } else {
+ List> itnrys = p.getFirst();
+ itnryp1 = itnrys.get(0);
+ itnryp2 = itnrys.get(1);
+ List> tmp2 = new ArrayList<>();
+ tmp2.add(itnryp1);
+ tmp2.add(itnryp2);
+ List tmpVehs2 = new ArrayList<>();
+ tmpVehs2.add(taxi);
+ tmpVehs2.add(taxis.get(k));
+ Pair>, List> pair2 = new Pair<>(tmp2, tmpVehs2);
+ templistP.add(pair2);
+ // travel time daneho requestu s prestupem spocitam jako:
+ // cas nez prvni auto dojede pro request a vyzvedne ho
+ // + cas jizdy v prvnim vozidle
+ // + pokud druhe auto prijede pozdeji nez to prvni tak k tomu prictu rozdil
+ // + doba jizdy v druhem aute
+ HashMap drops = getEstimatedTimesOfDropoff(itnryp2, taxis.get(k));
+ if (drops == null) {
+ // not valid
+ delays.add(Long.MAX_VALUE);
+ transferTimes.add((long) -1);
+ continue;
+ }
+ long minimalArrivalTime = timeProvider.getCurrentSimTime() + travelTimeProvider.getExpectedTravelTime(request.getFrom(), request.getTo());
+ long realArrivalTime = drops.get(request);
+ long delay = realArrivalTime - minimalArrivalTime;
+ delays.add(delay);
+ long transferTime = p.getSecond();
+ transferTimes.add(transferTime);
+ }
+ }
+ }
+ stationIndex++;
+ }
+ }
+ List listTransferPlans = new ArrayList<>();
+ for (int j = 0; j < templistP.size(); j++) {
+ TransferPlan t = new TransferPlan(transferTimes.get(j), delays.get(j), templistP.get(j));
+ listTransferPlans.add(t);
+ }
+ listTransferPlans.sort(TransferPlan::compareByDelay);
+
+ //vezmu hornich beta procent
+ double beta = 0.2;
+ int numOfTaken = (int) (delays.size() * beta);
+ if (numOfTaken == 0) {
+ numOfTaken = 1;
+ }
+ List sublistTransferPlans = new ArrayList<>();
+ for (int q = 0; q < numOfTaken; q++)
+ {
+ if(!listTransferPlans.isEmpty()) {
+ sublistTransferPlans.add(listTransferPlans.get(q));
+ }
+ }
+ sublistTransferPlans.sort(TransferPlan::compareByTransferTime);
+ Collections.reverse(sublistTransferPlans);
+
+ // ted mam serazene transferTimes
+ if (sublistTransferPlans.isEmpty()) {
+ continue;
+ }
+ else
+ {
+ // ziskam entry ktery je nejlepsi podle heuristiky
+ if (sublistTransferPlans.get(0).delay == Long.MAX_VALUE || sublistTransferPlans.get(0).trasferTime < 0) {
+ continue;
+ }
+ Pair>, List> key = sublistTransferPlans.get(0).pair;
+ List> plansForVehicles = key.getFirst();
+ List vehicles = key.getSecond();
+ for (int q = 0; q < vehicles.size(); q++) {
+ List vehPlan = plansForVehicles.get(q);
+ List planWithPos = new ArrayList<>();
+ planWithPos.add(vehicles.get(q).getCurrentPlanNoUpdate().plan.get(0));
+ planWithPos.addAll(vehPlan);
+ DriverPlan dp = new DriverPlan(planWithPos, 0, 0);
+ planMap.put(vehicles.get(q), dp);
+ }
+ }
+
+ // update k, k′ and LT
+ //update LT - not efficient
+ for (int z = 0; z < taxisCount; z++) {
+ RideSharingOnDemandVehicle taxi = taxis.get(z);
+ SimulationNode taxiPosition = taxis.get(z).getPosition();
+ Set requestsOnBoardSet = new HashSet<>();
+ DriverPlan actualPlan;
+ if (planMap.containsKey(taxis.get(z))) {
+ actualPlan = planMap.get(taxi);
+ } else {
+ actualPlan = taxi.getCurrentPlanNoUpdate();
+ }
+ for(PlanAction action : actualPlan) {
+ if(action instanceof PlanRequestAction) {
+ PlanRequestAction requestAction = (PlanRequestAction) action;
+ requestsOnBoardSet.add(requestAction.request);
+ }
+ }
+ List requestsOnBoard = new ArrayList<>(requestsOnBoardSet);
+ // kolik lidi je prave ted v aute
+ boolean taxiFree = true;
+ int taxiCapacity = taxi.getCapacity();
+ if (requestsOnBoardSet.size() >= taxiCapacity) {
+ taxiFree = false;
+ }
+ for(int j = 0; j < stationsCount; j++) {
+ //check if taxi has free seat
+ if (!taxiFree) {
+ LT[j][z] = Long.MAX_VALUE;
+ } else {
+ if (isWithTransfer(actualPlan)) {
+ // nekdo prestupuje
+ int indexLastTransferAction = findLastTransferActionIndex(actualPlan);
+ long timeToFinishCurrentEdge = 0;
+ SimulationNode previousPos = taxi.getPosition();
+ if (taxi.getCurrentTask() != null) {
+ timeToFinishCurrentEdge = travelTimeProvider.getTravelTime(taxi, taxi.getCurrentTask().getPosition());
+ previousPos = taxi.getCurrentTask().getPosition();
+ }
+ long timeToLastTransferAction = 0;
+ for (int q = 0; q < indexLastTransferAction + 1; q++) {
+ if (actualPlan.plan.get(q) instanceof PlanActionWait) {
+ PlanActionWait wait = (PlanActionWait) actualPlan.plan.get(q);
+ timeToLastTransferAction = timeToLastTransferAction + wait.getWaitTime();
+ } else {
+ timeToLastTransferAction = timeToLastTransferAction + travelTimeProvider.getExpectedTravelTime(previousPos, actualPlan.plan.get(q).getPosition());
+ }
+ previousPos = actualPlan.plan.get(q).getPosition();
+ }
+ // ted potrebuju najit posledni pickup ve zbyvajicim driver planu po prestupu
+ List segmentAfterTransfer = actualPlan.plan.subList(indexLastTransferAction + 1, actualPlan.plan.size());
+ int indexLastPickupSegment = findLastPickupIndexList(segmentAfterTransfer);
+ long timeToLastPickup = 0;
+ SimulationNode previousPos2 = actualPlan.plan.get(actualPlan.plan.size()-1).getPosition();
+ if (segmentAfterTransfer.size() > 0) {
+ previousPos2 = segmentAfterTransfer.get(0).getPosition();
+ for (int q = 0; q < indexLastPickupSegment + 1; q++) {
+ timeToLastPickup = timeToLastPickup + travelTimeProvider.getExpectedTravelTime(previousPos2, segmentAfterTransfer.get(q).getPosition());
+ previousPos2 = segmentAfterTransfer.get(q).getPosition();
+ }
+ }
+ SimulationNode station = transferPoints.get(j);
+ long timeToStation = travelTimeProvider.getExpectedTravelTime(previousPos2, station);
+ long estimatedArrivalToStation = timeProvider.getCurrentSimTime() + timeToFinishCurrentEdge + timeToLastTransferAction + timeToLastPickup + timeToStation;
+ LT[j][z] = estimatedArrivalToStation;
+ // zkontrolovat, zda arrival je v pohode z hlediska delay - kontroluju pro requesty po ukonceni prestupu
+ Set requestsInSegmentSet = new HashSet<>();
+ for (PlanAction action : segmentAfterTransfer) {
+ if (action instanceof PlanRequestAction) {
+ PlanRequestAction requestAction = (PlanRequestAction) action;
+ requestsInSegmentSet.add(requestAction.request);
+ }
+ }
+ List requestsInSegment = new ArrayList<>(requestsInSegmentSet);
+ for (PlanComputationRequest r : requestsInSegment) {
+ long maxTime = r.getMaxDropoffTime() * 1000;
+ if (LT[j][z] > maxTime) {
+ LT[j][z] = Long.MAX_VALUE;
+ break;
+ }
+ }
+ } else {
+ //neprestupuje nikdo
+ int indexLastPickup = findLastPickupIndex(actualPlan);
+ long timeToFinishCurrentEdge = 0;
+ SimulationNode previousPos = taxi.getPosition();
+ if (taxi.getCurrentTask() != null) {
+ timeToFinishCurrentEdge = travelTimeProvider.getTravelTime(taxi, taxi.getCurrentTask().getPosition());
+ previousPos = taxi.getCurrentTask().getPosition();
+ }
+ long timeToLastPickup = 0;
+ for (int q = 0; q < indexLastPickup + 1; q++) {
+ timeToLastPickup = timeToLastPickup + travelTimeProvider.getExpectedTravelTime(previousPos, actualPlan.plan.get(q).getPosition());
+ previousPos = actualPlan.plan.get(q).getPosition();
+ }
+ SimulationNode station = transferPoints.get(j);
+ long timeToStation = travelTimeProvider.getExpectedTravelTime(previousPos, station);
+ long estimatedArrivalToStation = timeProvider.getCurrentSimTime() + timeToFinishCurrentEdge + timeToLastPickup + timeToStation;
+ LT[j][z] = estimatedArrivalToStation;
+ // zkontrolovat, zda arrival je v pohode z hlediska delay
+ for (PlanComputationRequest r : requestsOnBoard) {
+ long maxTime = r.getMaxDropoffTime() * 1000;
+ if (LT[j][z] > maxTime) {
+ LT[j][z] = Long.MAX_VALUE;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return planMap;
+ }
+
+ private boolean checkValidItinerary(List itinerary, RideSharingOnDemandVehicle vehicle) {
+ SimulationNode previousDestination = vehicle.getPosition();
+ boolean ret = true;
+ long time = timeProvider.getCurrentSimTime();
+ long timeToFinishEdge = 0;
+ previousDestination = vehicle.getPosition();
+
+ // podivam se na trip plan
+ if (vehicle.getCurrentTripPlan() != null) {
+ if (vehicle.getCurrentTripPlan().getSize() == 0) {
+ SimulationNode stopLoc = (SimulationNode) vehicle.getCurrentTripPlan().getLastLocation();
+ // protoze je size trip planu 0, tak to znamena, ze uz je auto rozjete do posledni destinace tripu
+ // je ale mozne, ze tam jeste nedojelo, tedy jeho pozice je jina nez pozice posledniho bodu v trip planu
+ timeToFinishEdge += travelTimeProvider.getTravelTime(vehicle, stopLoc);
+ previousDestination = stopLoc;
+ }
+ else if (vehicle.getCurrentTripPlan().getSize() > 0) {
+ SimulationNode stopLoc = (SimulationNode) vehicle.getCurrentTripPlan().getFirstLocation();
+ SimulationNode currLoc = (SimulationNode) vehicle.getCurrentTripPlan().getAllLocations()[0];
+ boolean currLocIsVehiclePosition = false;
+ int curridx = 0;
+ while (currLoc != stopLoc) {
+ if (currLocIsVehiclePosition) {
+ timeToFinishEdge += travelTimeProvider.getTravelTime(vehicle, currLoc);
+ }
+ if (currLoc == vehicle.getPosition()) {
+ currLocIsVehiclePosition = true;
+ }
+ previousDestination = (SimulationNode) vehicle.getCurrentTripPlan().getAllLocations()[curridx];
+ curridx++;
+ currLoc = (SimulationNode) vehicle.getCurrentTripPlan().getAllLocations()[curridx];
+ }
+ }
+ }
+ time += timeToFinishEdge;
+
+ for (PlanAction action : itinerary) {
+ if (action instanceof PlanRequestAction) {
+ PlanComputationRequest pcq = ((PlanRequestAction) action).getRequest();
+ if (action instanceof PlanActionPickup) {
+ SimulationNode dest = pcq.getFrom();
+ time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest);
+ if (!(time < pcq.getMaxPickupTime()*1000)) {
+ //not valid itinerary
+ ret = false;
+ break;
+ }
+ previousDestination = dest;
+ } else if(action instanceof PlanActionPickupTransfer) {
+ PlanActionPickupTransfer pickupTransfer = (PlanActionPickupTransfer) action;
+ SimulationNode dest = pickupTransfer.getPosition();
+ time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest);
+ previousDestination = dest;
+ } else if(action instanceof PlanActionDropoffTransfer) {
+ PlanActionDropoffTransfer dropoffTransfer = (PlanActionDropoffTransfer) action;
+ SimulationNode dest = dropoffTransfer.getPosition();
+ time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest);
+ previousDestination = dest;
+ } else if (action instanceof PlanActionDropoff) {
+ SimulationNode dest = pcq.getTo();
+ time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest);
+ if (!(time < pcq.getMaxDropoffTime()*1000)) {
+ //not valid itinerary
+ ret = false;
+ break;
+ }
+ previousDestination = dest;
+ } else if (action instanceof PlanActionWait) {
+ PlanActionWait wait = (PlanActionWait) action;
+ time = time + wait.getWaitTime();
+ }
+ }
+ }
+ return ret;
+ }
+
+ private Pair>, Long> createChargePlanNoNewRequests(List itnryp1, List itnryp2, RideSharingOnDemandVehicle veh1, RideSharingOnDemandVehicle veh2, PlanComputationRequest request) {
+ long time1 = 0;
+ long timeToFinishEdge1 = 0;
+ SimulationNode previousDestination = veh1.getPosition();
+
+ // podivam se na trip plan
+ if (veh1.getCurrentTripPlan() != null) {
+ // pokud je get size u current trip planu vetsi nez nula, tak get first location vybere nejblizsi node kde se auto muze zastavit a je to spravne
+ // pokud je ale delka current trip nula, tak vyberu posledni akci z tripu - auto tam jeste nemuselo dojet a to zpusobuje chybku
+ // proto demand 298 neni vyzvednut vcas, protoze se tam neuvazuje cas ktere auto potrebuje na dokonceni trupu
+ if (veh1.getCurrentTripPlan().getSize() == 0) {
+ SimulationNode stopLoc = (SimulationNode) veh1.getCurrentTripPlan().getLastLocation();
+ // protoze je size trip planu 0, tak to znamena, ze uz je auto rozjete do posledni destinace tripu
+ // je ale mozne, ze tam jeste nedojelo, tedy jeho pozice je jina nez pozice posledniho bodu v trip planu
+ timeToFinishEdge1 += travelTimeProvider.getTravelTime(veh1, stopLoc);
+ previousDestination = stopLoc;
+ }
+ else if (veh1.getCurrentTripPlan().getSize() > 0) {
+ SimulationNode stopLoc = (SimulationNode) veh1.getCurrentTripPlan().getFirstLocation();
+ SimulationNode currLoc = (SimulationNode) veh1.getCurrentTripPlan().getAllLocations()[0];
+ boolean currLocIsVehiclePosition = false;
+ int curridx = 0;
+ while (currLoc != stopLoc) {
+ if (currLocIsVehiclePosition) {
+ timeToFinishEdge1 += travelTimeProvider.getTravelTime(veh1, currLoc);
+ }
+ if (currLoc == veh1.getPosition()) {
+ currLocIsVehiclePosition = true;
+ }
+ previousDestination = (SimulationNode) veh1.getCurrentTripPlan().getAllLocations()[curridx];
+ curridx++;
+ currLoc = (SimulationNode) veh1.getCurrentTripPlan().getAllLocations()[curridx];
+ }
+ }
+ }
+ time1 = timeToFinishEdge1;
+
+ // nemusim pricitat current sim time, protoze budu od sebe oba casy odecitat, jde mi jen o jejich rozdil
+ long transferTime = 0;
+ //expected arrival time of first car
+ for (PlanAction action : itnryp1) {
+ if (action instanceof PlanRequestAction) {
+ PlanComputationRequest pcq = ((PlanRequestAction) action).getRequest();
+ if (action instanceof PlanActionPickup) {
+ SimulationNode dest = pcq.getFrom();
+ time1 = time1 + travelTimeProvider.getExpectedTravelTime(previousDestination, dest);
+ previousDestination = dest;
+ } else if(action instanceof PlanActionPickupTransfer) {
+ PlanActionPickupTransfer pickupTransfer = (PlanActionPickupTransfer) action;
+ SimulationNode dest = pickupTransfer.getPosition();
+ time1 = time1 + travelTimeProvider.getExpectedTravelTime(previousDestination, dest);
+ previousDestination = dest;
+ } else if(action instanceof PlanActionDropoffTransfer) {
+ PlanActionDropoffTransfer dropoffTransfer = (PlanActionDropoffTransfer) action;
+ SimulationNode dest = dropoffTransfer.getPosition();
+ time1 = time1 + travelTimeProvider.getExpectedTravelTime(previousDestination, dest);
+ if (dropoffTransfer.request == request) {
+ break;
+ }
+ previousDestination = dest;
+ } else if (action instanceof PlanActionDropoff) {
+ SimulationNode dest = pcq.getTo();
+ time1 = time1 + travelTimeProvider.getExpectedTravelTime(previousDestination, dest);
+ previousDestination = dest;
+ } else if (action instanceof PlanActionWait) {
+ PlanActionWait wait = (PlanActionWait) action;
+ time1 = time1 + wait.getWaitTime();
+ }
+ }
+ }
+ // expected arrival of second car
+ int indexPickupSecondCar = 0;
+ long time2 = 0;
+ long timeToFinishEdge2 = 0;
+ PlanActionPickupTransfer pickup = null;
+ previousDestination = veh2.getPosition();
+
+ // podivam se na trip plan
+ if (veh2.getCurrentTripPlan() != null) {
+ if (veh2.getCurrentTripPlan().getSize() == 0) {
+ SimulationNode stopLoc = (SimulationNode) veh2.getCurrentTripPlan().getLastLocation();
+ // protoze je size trip planu 0, tak to znamena, ze uz je auto rozjete do posledni destinace tripu
+ // je ale mozne, ze tam jeste nedojelo, tedy jeho pozice je jina nez pozice posledniho bodu v trip planu
+ timeToFinishEdge2 += travelTimeProvider.getTravelTime(veh2, stopLoc);
+ previousDestination = stopLoc;
+ } else if (veh2.getCurrentTripPlan().getSize() > 0) {
+ SimulationNode stopLoc = (SimulationNode) veh2.getCurrentTripPlan().getFirstLocation();
+ SimulationNode currLoc = (SimulationNode) veh2.getCurrentTripPlan().getAllLocations()[0];
+ boolean currLocIsVehiclePosition = false;
+ int curridx = 0;
+ while (currLoc != stopLoc) {
+ if (currLocIsVehiclePosition) {
+ timeToFinishEdge2 += travelTimeProvider.getTravelTime(veh2, currLoc);
+ }
+ if (currLoc == veh2.getPosition()) {
+ currLocIsVehiclePosition = true;
+ }
+ previousDestination = (SimulationNode) veh2.getCurrentTripPlan().getAllLocations()[curridx];
+ curridx++;
+ currLoc = (SimulationNode) veh2.getCurrentTripPlan().getAllLocations()[curridx];
+ }
+ }
+ }
+ time2 = timeToFinishEdge2;
+
+ for (PlanAction action : itnryp2) {
+ if (action instanceof PlanRequestAction) {
+ PlanComputationRequest pcq = ((PlanRequestAction) action).getRequest();
+ if (action instanceof PlanActionPickup) {
+ SimulationNode dest = pcq.getFrom();
+ time2 = time2 + travelTimeProvider.getExpectedTravelTime(previousDestination, dest);
+ previousDestination = dest;
+ } else if(action instanceof PlanActionPickupTransfer) {
+ PlanActionPickupTransfer pickupTransfer = (PlanActionPickupTransfer) action;
+ SimulationNode dest = pickupTransfer.getPosition();
+ time2 = time2 + travelTimeProvider.getExpectedTravelTime(previousDestination, dest);
+ if (pickupTransfer.request == request) {
+ pickup = pickupTransfer;
+ break;
+ }
+ previousDestination = dest;
+ } else if(action instanceof PlanActionDropoffTransfer) {
+ PlanActionDropoffTransfer dropoffTransfer = (PlanActionDropoffTransfer) action;
+ SimulationNode dest = dropoffTransfer.getPosition();
+ time2 = time2 + travelTimeProvider.getExpectedTravelTime(previousDestination, dest);
+ previousDestination = dest;
+ } else if (action instanceof PlanActionDropoff) {
+ SimulationNode dest = pcq.getTo();
+ time2 = time2 + travelTimeProvider.getExpectedTravelTime(previousDestination, dest);
+ previousDestination = dest;
+ } else if (action instanceof PlanActionWait) {
+ PlanActionWait wait = (PlanActionWait) action;
+ time2 = time2 + wait.getWaitTime();
+ }
+ }
+ indexPickupSecondCar++;
+ }
+ long waitTime = time2 - time1; // k wait time prictu navic rezervu
+
+ // pokud je zaporny, tak druhe auto bude muset cekat waitTime dlouho
+ // pokud je kladny, tak to znamena ze prvni auto prijede drive nez druhe - bude cekat cestujici
+
+ boolean valid = true;
+ long maxTransferTime;
+
+// pridat wait i pro druhe auto tam, kde je rozdil mensi nez 5 s
+// aby tam byla rezerva
+ if (waitTime > 0 && waitTime < 2000) {
+ maxTransferTime = time1;
+ // ceka aspon 2 s
+ long newWait = 2000 - waitTime;
+ setMaxTransferTimeForDropoffTransferAction(maxTransferTime, itnryp1, request);
+ PlanActionWait waitAction = new PlanActionWait(request, pickup.getPosition(), pickup.getMaxTime(), newWait);
+ transferTime = newWait;
+ itnryp2.add(indexPickupSecondCar, waitAction);
+
+ //check tolerable delay for passengers in vehicle2
+ long time = 0;
+ previousDestination = veh2.getPosition();
+ // podivam se na trip plan
+ if (veh2.getCurrentTripPlan() != null) {
+ if (veh2.getCurrentTripPlan().getSize() == 0) {
+ SimulationNode stopLoc = (SimulationNode) veh2.getCurrentTripPlan().getLastLocation();
+ // protoze je size trip planu 0, tak to znamena, ze uz je auto rozjete do posledni destinace tripu
+ // je ale mozne, ze tam jeste nedojelo, tedy jeho pozice je jina nez pozice posledniho bodu v trip planu
+ time += travelTimeProvider.getTravelTime(veh2, stopLoc);
+ previousDestination = stopLoc;
+ }
+ else if (veh2.getCurrentTripPlan().getSize() > 0) {
+ SimulationNode stopLoc = (SimulationNode) veh2.getCurrentTripPlan().getFirstLocation();
+ SimulationNode currLoc = (SimulationNode) veh2.getCurrentTripPlan().getAllLocations()[0];
+ boolean currLocIsVehiclePosition = false;
+ int curridx = 0;
+ while (currLoc != stopLoc) {
+ if (currLocIsVehiclePosition) {
+ time += travelTimeProvider.getTravelTime(veh2, currLoc);
+ }
+ if (currLoc == veh2.getPosition()) {
+ currLocIsVehiclePosition = true;
+ }
+ previousDestination = (SimulationNode) veh2.getCurrentTripPlan().getAllLocations()[curridx];
+ curridx++;
+ currLoc = (SimulationNode) veh2.getCurrentTripPlan().getAllLocations()[curridx];
+ }
+ }
+ }
+
+ for (PlanAction action : itnryp2) {
+ if (action instanceof PlanRequestAction) {
+ PlanComputationRequest pcq = ((PlanRequestAction) action).getRequest();
+ if (action instanceof PlanActionPickup) {
+ SimulationNode dest = pcq.getFrom();
+ time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest);
+ if (!(time <= pcq.getMaxPickupTime()*1000)) {
+ //not valid itinerary - check new driver plan
+ valid = false;
+ break;
+ }
+ previousDestination = dest;
+ } else if (action instanceof PlanActionDropoff) {
+ SimulationNode dest = pcq.getTo();
+ time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest);
+ if (!(time <= pcq.getMaxDropoffTime()*1000)) {
+ //not valid itinerary - check new driver plan
+ valid = false;
+ break;
+ }
+ previousDestination = dest;
+ } else if (action instanceof PlanActionWait) {
+ PlanActionWait wait = (PlanActionWait) action;
+ time = time + wait.getWaitTime();
+ previousDestination = wait.getPosition();
+ } else if (action instanceof PlanActionPickupTransfer) {
+ PlanActionPickupTransfer p = (PlanActionPickupTransfer) action;
+ SimulationNode dest = p.getPosition();
+ time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest);
+ if (!(time <= p.getMaxTime()*1000)) {
+ valid = false;
+ break;
+ }
+ previousDestination = dest;
+ } else if(action instanceof PlanActionDropoffTransfer) {
+ PlanActionDropoffTransfer p = (PlanActionDropoffTransfer) action;
+ SimulationNode dest = p.getPosition();
+ time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest);
+ if (!(time <= p.getMaxTime()*1000)) {
+ valid = false;
+ break;
+ }
+ previousDestination = dest;
+ }
+ }
+ }
+ }
+ // pridam wait time do planu pro druhe auto pokud je wait time zaporny
+ // pozor, pokud bych chtela smazat casovou rezervu 5 s, tak je tam nekde problem s wait akci s casem 0
+ // - tak na to by bylo potreba udelat zvlast podminku a nejaky minimalni wait time tam nastavit, aby bylo zajistene poradi pri pruchodu algoritmem
+ else if (waitTime <= 0) {
+ maxTransferTime = time1;
+ // pridat 1000 je malo, ale 2000 dostacuje
+ waitTime = waitTime - 2000;
+ setMaxTransferTimeForDropoffTransferAction(maxTransferTime, itnryp1, request);
+ //transfer time je -waitTime
+ // pickup by nemel byt null protoze se nastavi v predeslem loopu
+ assert pickup != null;
+ PlanActionWait waitAction = new PlanActionWait(request, pickup.getPosition(), pickup.getMaxTime(), -waitTime);
+ transferTime = -waitTime;
+ itnryp2.add(indexPickupSecondCar, waitAction);
+
+ //check tolerable delay for passengers in vehicle2
+ long time = 0;
+ previousDestination = veh2.getPosition();
+ // podivam se na trip plan
+ if (veh2.getCurrentTripPlan() != null) {
+ if (veh2.getCurrentTripPlan().getSize() == 0) {
+ SimulationNode stopLoc = (SimulationNode) veh2.getCurrentTripPlan().getLastLocation();
+ // protoze je size trip planu 0, tak to znamena, ze uz je auto rozjete do posledni destinace tripu
+ // je ale mozne, ze tam jeste nedojelo, tedy jeho pozice je jina nez pozice posledniho bodu v trip planu
+ time += travelTimeProvider.getTravelTime(veh2, stopLoc);
+ previousDestination = stopLoc;
+ }
+ else if (veh2.getCurrentTripPlan().getSize() > 0) {
+ SimulationNode stopLoc = (SimulationNode) veh2.getCurrentTripPlan().getFirstLocation();
+ SimulationNode currLoc = (SimulationNode) veh2.getCurrentTripPlan().getAllLocations()[0];
+ boolean currLocIsVehiclePosition = false;
+ int curridx = 0;
+ while (currLoc != stopLoc) {
+ if (currLocIsVehiclePosition) {
+ time += travelTimeProvider.getTravelTime(veh2, currLoc);
+ }
+ if (currLoc == veh2.getPosition()) {
+ currLocIsVehiclePosition = true;
+ }
+ previousDestination = (SimulationNode) veh2.getCurrentTripPlan().getAllLocations()[curridx];
+ curridx++;
+ currLoc = (SimulationNode) veh2.getCurrentTripPlan().getAllLocations()[curridx];
+ }
+ }
+ }
+
+ for (PlanAction action : itnryp2) {
+ if (action instanceof PlanRequestAction) {
+ PlanComputationRequest pcq = ((PlanRequestAction) action).getRequest();
+ if (action instanceof PlanActionPickup) {
+ SimulationNode dest = pcq.getFrom();
+ time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest);
+ if (!(time <= pcq.getMaxPickupTime()*1000)) {
+ //not valid itinerary - check new driver plan
+ valid = false;
+ break;
+ }
+ previousDestination = dest;
+ } else if (action instanceof PlanActionDropoff) {
+ SimulationNode dest = pcq.getTo();
+ time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest);
+ if (!(time <= pcq.getMaxDropoffTime()*1000)) {
+ //not valid itinerary - check new driver plan
+ valid = false;
+ break;
+ }
+ previousDestination = dest;
+ } else if (action instanceof PlanActionWait) {
+ PlanActionWait wait = (PlanActionWait) action;
+ time = time + wait.getWaitTime();
+ previousDestination = wait.getPosition();
+ } else if (action instanceof PlanActionPickupTransfer) {
+ PlanActionPickupTransfer p = (PlanActionPickupTransfer) action;
+ SimulationNode dest = p.getPosition();
+ time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest);
+ if (!(time <= p.getMaxTime()*1000)) {
+ valid = false;
+ break;
+ }
+ previousDestination = dest;
+ } else if(action instanceof PlanActionDropoffTransfer) {
+ PlanActionDropoffTransfer p = (PlanActionDropoffTransfer) action;
+ SimulationNode dest = p.getPosition();
+ time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest);
+ if (!(time <= p.getMaxTime()*1000)) {
+ valid = false;
+ break;
+ }
+ previousDestination = dest;
+ }
+ }
+ }
+ }
+ else {
+ maxTransferTime = time2 - 2000;
+// maxTransferTime = time1;
+ setMaxTransferTimeForDropoffTransferAction(maxTransferTime, itnryp1, request);
+ }
+ if(valid) {
+ List> itnrys = new ArrayList<>();
+ itnrys.add(itnryp1);
+ itnrys.add(itnryp2);
+ Pair>, Long> ret = new Pair<>(itnrys, transferTime);
+ return ret;
+ }
+ else {
+ return null;
+ }
+ }
+
+ public List getPickupActions(List plan) {
+ List pickups = new ArrayList<>();
+ for(PlanAction action : plan) {
+ if(action instanceof PlanActionPickup || action instanceof PlanActionPickupTransfer) {
+ pickups.add(action);
+ }
+ }
+ return pickups;
+ }
+
+ public void setMaxTransferTimeForDropoffTransferAction(long maxTime, List itinerary, PlanComputationRequest request) {
+ maxTime = maxTime + timeProvider.getCurrentSimTime();
+ int maxTimeInt = (int) Math.floor(maxTime / 1000.0);
+ for (PlanAction action : itinerary) {
+ if (action instanceof PlanActionDropoffTransfer) {
+ if(((PlanActionDropoffTransfer) action).getRequest() == request) {
+ PlanActionDropoffTransfer ac = (PlanActionDropoffTransfer) action;
+ ac.setMaxTime(maxTimeInt-1);
+ }
+ }
+ }
+ }
+
+
+ public List getDropoffActions(List plan) {
+ List dropoffs = new ArrayList<>();
+ for(PlanAction action : plan) {
+ if(action instanceof PlanActionDropoff || action instanceof PlanActionDropoffTransfer) {
+ dropoffs.add(action);
+ }
+ }
+ return dropoffs;
+ }
+
+ private HashMap getEstimatedTimesOfDropoff(List itinerary, RideSharingOnDemandVehicle vehicle) {
+ long time = timeProvider.getCurrentSimTime();
+ long timeToFinishEdge = 0;
+ SimulationNode previousDestination = vehicle.getPosition();
+ if (vehicle.getCurrentTripPlan() != null) {
+ if (vehicle.getCurrentTripPlan().getSize() == 0) {
+ SimulationNode stopLoc = (SimulationNode) vehicle.getCurrentTripPlan().getLastLocation();
+ // protoze je size trip planu 0, tak to znamena, ze uz je auto rozjete do posledni destinace tripu
+ // je ale mozne, ze tam jeste nedojelo, tedy jeho pozice je jina nez pozice posledniho bodu v trip planu
+ timeToFinishEdge += travelTimeProvider.getTravelTime(vehicle, stopLoc);
+ previousDestination = stopLoc;
+ }
+ else if (vehicle.getCurrentTripPlan().getSize() > 0) {
+ SimulationNode stopLoc = (SimulationNode) vehicle.getCurrentTripPlan().getFirstLocation();
+ SimulationNode currLoc = (SimulationNode) vehicle.getCurrentTripPlan().getAllLocations()[0];
+ boolean currLocIsVehiclePosition = false;
+ int curridx = 0;
+ while (currLoc != stopLoc) {
+ if (currLocIsVehiclePosition) {
+ timeToFinishEdge += travelTimeProvider.getTravelTime(vehicle, currLoc);
+ }
+ if (currLoc == vehicle.getPosition()) {
+ currLocIsVehiclePosition = true;
+ }
+ previousDestination = (SimulationNode) vehicle.getCurrentTripPlan().getAllLocations()[curridx];
+ curridx++;
+ currLoc = (SimulationNode) vehicle.getCurrentTripPlan().getAllLocations()[curridx];
+ }
+ }
+ }
+
+ time = time + timeToFinishEdge;
+
+ HashMap times = new HashMap<>();
+ for (PlanAction action : itinerary) {
+ if (action instanceof PlanActionPickup || action instanceof PlanActionPickupTransfer) {
+ time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, action.getPosition());
+ if (time > ((PlanRequestAction) action).request.getMaxPickupTime() * 1000) {
+ //not valid
+ return null;
+ }
+ previousDestination = action.getPosition();
+ } else if (action instanceof PlanActionDropoff || action instanceof PlanActionDropoffTransfer) {
+ time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, action.getPosition());
+ if (time > ((PlanRequestAction) action).request.getMaxDropoffTime() * 1000) {
+ //not valid
+ return null;
+ }
+ times.put(((PlanRequestAction) action).getRequest(), time);
+ previousDestination = action.getPosition();
+ } else if (action instanceof PlanActionWait) {
+ time = time + ((PlanActionWait) action).getWaitTime();
+ }
+
+ }
+ return times;
+ }
+
+ private List findItineraryWithMinimumDelayNew(List> lst, List originalPlan, RideSharingOnDemandVehicle vehicle) {
+ HashMap timesOfDropOriginal = getEstimatedTimesOfDropoff(originalPlan, vehicle);
+ if (timesOfDropOriginal == null) {
+ //plan neni validni
+ // to je chyba, puvodni plan by mel byt validni vzdy
+ return null;
+ //TODO throw exception
+ }
+ List delays = new ArrayList<>();
+ for (List itnry : lst) {
+ HashMap timesOfDropNew = getEstimatedTimesOfDropoff(itnry, vehicle);
+ if (timesOfDropNew == null) {
+ //plan neni validni
+ delays.add(Long.MAX_VALUE);
+ } else {
+ // plan je validni, spocitam zpozdeni
+ long delay = countDelayDifference(timesOfDropOriginal, timesOfDropNew);
+ delays.add(delay);
+ }
+ }
+ //find max in delays
+ int maxAt = 0;
+ for (int i = 0; i < delays.size(); i++) {
+ maxAt = delays.get(i) > delays.get(maxAt) ? i : maxAt;
+ }
+ if (delays.get(maxAt) == Long.MAX_VALUE) {
+ return null;
+ }
+ List bestPlan = lst.get(maxAt);
+ return bestPlan;
+ }
+
+ private long countDelayDifference(HashMap originalMap, HashMap newMap) {
+ long time = 0;
+ for (Map.Entry entry : originalMap.entrySet()) {
+ long difference = Math.abs(entry.getValue() - newMap.get(entry.getKey()));
+ time = time + difference;
+ }
+ // todo maybe add delay for a new passenger?
+ return time;
+ }
+
+ private List removeCurrentPositionActions(List listOfActionsWithPositions) {
+ List copyOfList = new ArrayList<>();
+ copyOfList.addAll(listOfActionsWithPositions);
+ for (PlanAction action : listOfActionsWithPositions) {
+ if (action instanceof PlanActionCurrentPosition) {
+ copyOfList.remove(action);
+ }
+ }
+ return copyOfList;
+ }
+
+
+ private List findPlanWithNoTransferNew(PlanComputationRequest newRequest, RideSharingOnDemandVehicle vehicle) {
+ DriverPlan vehiclePlan;
+ if (planMap.containsKey(vehicle)) {
+ vehiclePlan = planMap.get(vehicle);
+ } else {
+ vehiclePlan = vehicle.getCurrentPlanNoUpdate();
+ }
+ if (isWithTransfer(vehiclePlan)) {
+ // v aute nekdo prestupuje
+ // musim oddelit segment s prestupem
+ // ze zbytku vezmu pickups, pridam novy a potom hledam permutace dropoff akci
+ int indexLastTransfer = findLastTransferActionIndex(vehiclePlan);
+ List segmentWithTransfer = vehiclePlan.plan.subList(0, indexLastTransfer+1);
+ List segmentWithTransferWithoutPositionAction = removeCurrentPositionActions(segmentWithTransfer);
+
+ List segmentAfterTransfer = vehiclePlan.plan.subList(indexLastTransfer+1, vehiclePlan.plan.size());
+ List> lstTemp = new ArrayList<>();
+ List> lst = new ArrayList<>();
+ List newPlan = new ArrayList<>();
+ for (PlanAction action : segmentAfterTransfer) {
+ newPlan.add(action);
+ }
+ //add pickup and dropoff for new request
+ newPlan.add(newRequest.getPickUpAction());
+ newPlan.add(newRequest.getDropOffAction());
+ //get pickup order based on heuristic from TASeT paper
+ List pickups = getPickupActions(newPlan);
+ List dropoffs = getDropoffActions(newPlan);
+ //permute dropoff orders
+ List> dropoffOrders = permute(dropoffs);
+ for (List dropoffPlan : dropoffOrders) {
+ lstTemp.add(createItineraryList(pickups, dropoffPlan));
+ }
+ // ted spojit puvodni segment a kadzy itinerare z lst
+ for (List itnry : lstTemp) {
+ List newList = new ArrayList<>(segmentWithTransferWithoutPositionAction);
+ newList.addAll(itnry);
+ lst.add(newList);
+ }
+ return findItineraryWithMinimumDelayNew(lst, vehiclePlan.plan, vehicle);
+
+ } else {
+ //neni prestup v aute
+ List> lst = new ArrayList<>();
+ List newPlan = new ArrayList<>();
+ newPlan.addAll(vehiclePlan.plan);
+ //add pickup and dropoff for new request
+ newPlan.add(newRequest.getPickUpAction());
+ newPlan.add(newRequest.getDropOffAction());
+ //get pickup order based on heuristic from TASeT paper
+ List pickups = getPickupActions(newPlan);
+ List dropoffs = getDropoffActions(newPlan);
+ //permute dropoff orders
+ List> dropoffOrders = permute(dropoffs);
+ for (List dropoffPlan : dropoffOrders) {
+ lst.add(createItineraryList(pickups, dropoffPlan));
+ }
+ return findItineraryWithMinimumDelayNew(lst, vehiclePlan.plan, vehicle);
+ }
+ }
+
+ private List findPlanWithNoTransferActionsNew(PlanAction pickup, PlanAction dropoff, RideSharingOnDemandVehicle vehicle) {
+ DriverPlan vehiclePlan;
+ if (planMap.containsKey(vehicle)) {
+ vehiclePlan = planMap.get(vehicle);
+ } else {
+ vehiclePlan = vehicle.getCurrentPlanNoUpdate();
+ }
+ if (isWithTransfer(vehiclePlan)) {
+ // v aute nekdo prestupuje
+ // musim oddelit segment s prestupem
+ // ze zbytku vezmu pickups, pridam novy a potom hledam permutace dropoff akci
+ int indexLastTransfer = findLastTransferActionIndex(vehiclePlan);
+ List segmentWithTransfer = vehiclePlan.plan.subList(0, indexLastTransfer+1);
+ List segmentWithTransferWithoutPositionAction = removeCurrentPositionActions(segmentWithTransfer);
+
+ List segmentAfterTransfer = vehiclePlan.plan.subList(indexLastTransfer+1, vehiclePlan.plan.size());
+ List> lstTemp = new ArrayList<>();
+ List> lst = new ArrayList<>();
+ List newPlan = new ArrayList<>();
+ newPlan.addAll(segmentAfterTransfer);
+ //add pickup and dropoff for new request
+ newPlan.add(pickup);
+ newPlan.add(dropoff);
+ //get pickup order based on heuristic from TASeT paper
+ List pickups = getPickupActions(newPlan);
+ List dropoffs = getDropoffActions(newPlan);
+ //permute dropoff orders
+ List> dropoffOrders = permute(dropoffs);
+ for (List dropoffPlan : dropoffOrders) {
+ lstTemp.add(createItineraryList(pickups, dropoffPlan));
+ }
+ // ted spojit puvodni segment a kadzy itinerare z lst
+ for (List itnry : lstTemp) {
+ List newList = new ArrayList<>(segmentWithTransferWithoutPositionAction);
+ newList.addAll(itnry);
+ lst.add(newList);
+ }
+ return findItineraryWithMinimumDelayNew(lst, vehiclePlan.plan, vehicle);
+
+ } else {
+ //neni prestup v aute
+ List> lst = new ArrayList<>();
+ List newPlan = new ArrayList<>();
+ newPlan.addAll(vehiclePlan.plan);
+ //add pickup and dropoff for new request
+ newPlan.add(pickup);
+ newPlan.add(dropoff);
+ //get pickup order based on heuristic from TASeT paper
+ List pickups = getPickupActions(newPlan);
+ List dropoffs = getDropoffActions(newPlan);
+ //permute dropoff orders
+ List> dropoffOrders = permute(dropoffs);
+ for (List dropoffPlan : dropoffOrders) {
+ lst.add(createItineraryList(pickups, dropoffPlan));
+ }
+ return findItineraryWithMinimumDelayNew(lst, vehiclePlan.plan, vehicle);
+ }
+ }
+
+ private List createItineraryList(List pickupOrder, List dropoffOrder) {
+ List listOfActionsOrdered = new ArrayList<>(pickupOrder);
+ listOfActionsOrdered.addAll(dropoffOrder);
+ return listOfActionsOrdered;
+ }
+
+ /**
+ * @return new list with all permutations of PlanActrions from lst List.
+ */
+ public List> permute(List lst) {
+ List> list = new ArrayList<>();
+ permuteHelper(list, new ArrayList<>(), lst);
+ return list;
+ }
+
+ /**
+ * Helper function for permute()
+ */
+ private void permuteHelper(List> list, List resultList, List lst){
+ // Base case
+ if(resultList.size() == lst.size()){
+ list.add(new ArrayList<>(resultList));
+ }
+ else{
+ for(int i = 0; i < lst.size(); i++){
+ if(resultList.contains(lst.get(i)))
+ {
+ // If element already exists in the list then skip
+ continue;
+ }
+ // Choose element
+ resultList.add(lst.get(i));
+ // Explore
+ permuteHelper(list, resultList, lst);
+ // Unchoose element
+ resultList.remove(resultList.size() - 1);
+ }
+ }
+ }
+
+ private boolean canServeRequestTASeT2(RideSharingOnDemandVehicle vehicle, PlanComputationRequest request) {
+ Set requestsOnBoardSet = new HashSet<>();
+ DriverPlan actualPlan = vehicle.getCurrentPlanNoUpdate();
+ for (PlanAction action : actualPlan) {
+ if (action instanceof PlanRequestAction) {
+ PlanRequestAction requestAction = (PlanRequestAction) action;
+ requestsOnBoardSet.add(requestAction.request);
+ }
+ }
+ List requestsOnBoard = new ArrayList<>(requestsOnBoardSet);
+ // kolik lidi je prave ted v aute
+ boolean taxiFree = true;
+ int taxiCapacity = vehicle.getCapacity();
+ if (requestsOnBoardSet.size() >= taxiCapacity) {
+ taxiFree = false;
+ }
+ if (!taxiFree) {
+ return false;
+ } else {
+ if (requestsOnBoard.size() == 0) {
+ long timeToNewRequest = travelTimeProvider.getTravelTime(vehicle, request.getFrom());
+ if (timeToNewRequest <= request.getMaxPickupTime() * 1000) {
+ return true;
+ }
+ return false;
+ }
+ if (isWithTransfer(vehicle.getCurrentPlanNoUpdate())) {
+ // nekdo prestupuje
+ int indexLastTransferAction = findLastTransferActionIndex(vehicle.getCurrentPlanNoUpdate());
+ long timeToFinishCurrentEdge = 0;
+ SimulationNode previousPos = vehicle.getPosition();
+ if (vehicle.getCurrentTask() != null) {
+ timeToFinishCurrentEdge = travelTimeProvider.getTravelTime(vehicle, vehicle.getCurrentTask().getPosition());
+ previousPos = vehicle.getCurrentTask().getPosition();
+ }
+ long timeToLastTransferAction = 0;
+ for (int q = 0; q < indexLastTransferAction + 1; q++) {
+ if (vehicle.getCurrentPlanNoUpdate().plan.get(q) instanceof PlanActionWait) {
+ PlanActionWait wait = (PlanActionWait) vehicle.getCurrentPlanNoUpdate().plan.get(q);
+ timeToLastTransferAction = timeToLastTransferAction + wait.getWaitTime();
+ } else {
+ timeToLastTransferAction = timeToLastTransferAction + travelTimeProvider.getExpectedTravelTime(previousPos, vehicle.getCurrentPlanNoUpdate().plan.get(q).getPosition());
+ }
+ previousPos = vehicle.getCurrentPlanNoUpdate().plan.get(q).getPosition();
+ }
+ // ted potrebuju najit posledni pickup ve zbyvajicim driver planu po prestupu
+ List segmentAfterTransfer = vehicle.getCurrentPlanNoUpdate().plan.subList(indexLastTransferAction + 1, vehicle.getCurrentPlanNoUpdate().plan.size());
+ int indexLastPickupSegment = findLastPickupIndexList(segmentAfterTransfer);
+ long timeToLastPickup = 0;
+ SimulationNode previousPos2 = vehicle.getCurrentPlanNoUpdate().plan.get(vehicle.getCurrentPlanNoUpdate().plan.size() - 1).getPosition();
+ if (segmentAfterTransfer.size() > 0) {
+ previousPos2 = segmentAfterTransfer.get(0).getPosition();
+ for (int q = 0; q < indexLastPickupSegment + 1; q++) {
+ timeToLastPickup = timeToLastPickup + travelTimeProvider.getExpectedTravelTime(previousPos2, segmentAfterTransfer.get(q).getPosition());
+ previousPos2 = segmentAfterTransfer.get(q).getPosition();
+ }
+ }
+
+ //odtud jestli muze dojet k requestu - tj. cas od mista kde skoncil k vyzvednuti requestu
+ long timeToNewRequest = travelTimeProvider.getExpectedTravelTime(previousPos2, request.getFrom());
+ long estimatedArrival = timeProvider.getCurrentSimTime() + timeToFinishCurrentEdge + timeToLastTransferAction + timeToLastPickup + timeToNewRequest;
+ if (estimatedArrival <= request.getMaxPickupTime() * 1000) {
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ //neprestupuje nikdo
+ int indexLastPickup = findLastPickupIndex(vehicle.getCurrentPlanNoUpdate());
+ long timeToFinishCurrentEdge = 0;
+ SimulationNode previousPos = vehicle.getPosition();
+ if (vehicle.getCurrentTask() != null) {
+ timeToFinishCurrentEdge = travelTimeProvider.getTravelTime(vehicle, vehicle.getCurrentTask().getPosition());
+ previousPos = vehicle.getCurrentTask().getPosition();
+ }
+ long timeToLastPickup = 0;
+ for (int q = 0; q < indexLastPickup + 1; q++) {
+ timeToLastPickup = timeToLastPickup + travelTimeProvider.getExpectedTravelTime(previousPos, vehicle.getCurrentPlanNoUpdate().plan.get(q).getPosition());
+ previousPos = vehicle.getCurrentPlanNoUpdate().plan.get(q).getPosition();
+ }
+ long timeToNewRequest = travelTimeProvider.getExpectedTravelTime(previousPos, request.getFrom());
+ long estimatedArrival = timeProvider.getCurrentSimTime() + timeToFinishCurrentEdge + timeToLastPickup + timeToNewRequest;
+ if (estimatedArrival <= request.getMaxPickupTime() * 1000) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ }
+ }
+}
+
diff --git a/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java
new file mode 100644
index 00000000..a26c41d1
--- /dev/null
+++ b/src/main/java/cz/cvut/fel/aic/simod/ridesharing/greedyTASeT/GreedyTASeTSolver.java
@@ -0,0 +1,1634 @@
+package cz.cvut.fel.aic.simod.ridesharing.greedyTASeT;
+
+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.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.event.OnDemandVehicleEvent;
+import cz.cvut.fel.aic.simod.ridesharing.DARPSolver;
+import cz.cvut.fel.aic.simod.ridesharing.DroppedDemandsAnalyzer;
+import cz.cvut.fel.aic.simod.ridesharing.PlanCostProvider;
+import cz.cvut.fel.aic.simod.ridesharing.RideSharingOnDemandVehicle;
+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.storage.OnDemandvehicleStationStorage;
+import cz.cvut.fel.aic.simod.traveltimecomputation.TravelTimeProvider;
+import org.jgrapht.alg.util.Pair;
+
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+
+@Singleton
+public class GreedyTASeTSolver extends DARPSolver implements EventHandler {
+
+
+ private final TypedSimulation eventProcessor;
+
+ private final SimodConfig config;
+
+ private final TimeProvider timeProvider;
+
+ private final PositionUtil positionUtil;
+
+ private final DroppedDemandsAnalyzer droppedDemandsAnalyzer;
+
+ private final OnDemandvehicleStationStorage onDemandvehicleStationStorage;
+
+ private List transferPoints;
+
+ protected final DefaultPlanComputationRequest.DefaultPlanComputationRequestFactory requestFactory;
+
+ private Map planMap;
+
+ protected List> inactiveVehicles;
+
+ protected List> waitingTimes;
+
+
+ @Inject
+ public GreedyTASeTSolver(
+ OnDemandVehicleStorage vehicleStorage,
+ TravelTimeProvider travelTimeProvider,
+ PlanCostProvider travelCostProvider,
+ DefaultPlanComputationRequest.DefaultPlanComputationRequestFactory requestFactory,
+ TypedSimulation eventProcessor,
+ SimodConfig config,
+ TimeProvider timeProvider,
+ PositionUtil positionUtil,
+ DroppedDemandsAnalyzer droppedDemandsAnalyzer,
+ OnDemandvehicleStationStorage onDemandvehicleStationStorage,
+ AgentpolisConfig agentpolisConfig) {
+
+ super(vehicleStorage, travelTimeProvider, travelCostProvider, requestFactory);
+ this.eventProcessor = eventProcessor;
+ this.config = config;
+ this.timeProvider = timeProvider;
+ this.positionUtil = positionUtil;
+ this.droppedDemandsAnalyzer = droppedDemandsAnalyzer;
+ this.onDemandvehicleStationStorage = onDemandvehicleStationStorage;
+ this.requestFactory = requestFactory;
+ inactiveVehicles = new ArrayList<>();
+ waitingTimes = new ArrayList<>();
+
+ setEventHandeling();
+ }
+
+ public void setTransferPoints(List transferPoints) {
+ this.transferPoints = transferPoints;
+ }
+
+ @Override
+ public EventProcessor getEventProcessor() {
+ return eventProcessor;
+ }
+
+ @Override
+ public void handleEvent(Event event) {
+
+ }
+
+
+ private void setEventHandeling() {
+ List typesToHandle = new LinkedList<>();
+
+ typesToHandle.add(OnDemandVehicleEvent.PICKUP);
+ eventProcessor.addEventHandler(this, typesToHandle);
+ }
+
+ /**
+ * Transfer-allowed scheduling solver
+ * @return Map
+ */
+ @Override
+ public Map solve(List newRequests, List waitingRequests) {
+ Map planMap = new ConcurrentHashMap<>();
+ Map planMapReturn = new ConcurrentHashMap<>();
+ List taxis = new ArrayList<>();
+
+ for(AgentPolisEntity tVvehicle: vehicleStorage.getEntitiesForIteration()) {
+ RideSharingOnDemandVehicle vehicle = (RideSharingOnDemandVehicle) tVvehicle;
+ taxis.add(vehicle);
+ }
+
+ planMap = dispatch(taxis, newRequests);
+
+
+
+ return planMap;
+ }
+
+ /**
+ * Transfer-allowed scheduling function
+ * @return
+ */
+ private Map dispatch(List taxis, List requests) {
+ // because all passengers allow ridesharing, only greedy taset will be called
+ List carpoolAcceptingTaxis = taxis;
+ List carpoolAcceptingPassengers = requests;
+ Map map = heuristics(carpoolAcceptingTaxis, carpoolAcceptingPassengers);
+ return map;
+ }
+
+
+ private boolean isWithTransfer(DriverPlan plan) {
+ for(PlanAction action : plan.plan) {
+ if(action instanceof PlanRequestAction) {
+ if (action instanceof PlanActionDropoffTransfer || action instanceof PlanActionPickupTransfer || action instanceof PlanActionWait) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+
+ private void logInactiveVehicles(List vehicles) {
+ for (RideSharingOnDemandVehicle vehicle : vehicles) {
+ if (vehicle.getCurrentPlanNoUpdate().plan.size() == 1) {
+ if (!planMap.containsKey(vehicle)) {
+ // toto vozidlo ma prazdny plan
+ inactiveVehicles.add(new Pair(vehicle.getId(), (int) Math.round(timeProvider.getCurrentSimTime() / 1000.0)));
+ }
+ }
+ }
+ }
+
+ private void logWaitingTime(RideSharingOnDemandVehicle vehicle, Integer waitTimeInSeconds) {
+ waitingTimes.add(new Pair(vehicle.getId(), waitTimeInSeconds));
+ }
+
+ private int findLastPickupIndex(DriverPlan plan) {
+ int index = -1;
+ for (int i = 0; i < plan.getLength(); i++) {
+ if (plan.plan.get(i) instanceof PlanActionPickup) {
+ index = i;
+ }
+ }
+ return index;
+ }
+
+ private int findLastPickupIndexList(List plan) {
+ int index = -1;
+ for (int i = 0; i < plan.size(); i++) {
+ if (plan.get(i) instanceof PlanActionPickup) {
+ index = i;
+ }
+ }
+ return index;
+ }
+
+ private int findLastTransferActionIndex(DriverPlan plan) {
+ int index = -1;
+ for (int i = 0; i < plan.getLength(); i++) {
+ if (plan.plan.get(i) instanceof PlanActionDropoffTransfer || plan.plan.get(i) instanceof PlanActionPickupTransfer || plan.plan.get(i) instanceof PlanActionWait) {
+ index = i;
+ }
+ }
+ return index;
+ }
+
+ private long countTimeToNewPickup(RideSharingOnDemandVehicle taxi, PlanComputationRequest request, List requestsOnBoard) {
+ DriverPlan taxiPlan;
+ if (planMap.containsKey(taxi)) {
+ taxiPlan = planMap.get(taxi);
+ } else {
+ taxiPlan = taxi.getCurrentPlanNoUpdate();
+ }
+ if (isWithTransfer(taxiPlan)) {
+ int indexLastTransferAction = findLastTransferActionIndex(taxiPlan);
+ long timeToFinishCurrentEdge = 0;
+ SimulationNode previousPos = taxi.getPosition();
+ if (taxi.getCurrentTask() != null) {
+ timeToFinishCurrentEdge = travelTimeProvider.getTravelTime(taxi, taxi.getCurrentTask().getPosition());
+ previousPos = taxi.getCurrentTask().getPosition();
+ }
+ long timeToLastTransferAction = 0;
+ for (int q = 0; q < indexLastTransferAction + 1; q++) {
+ if (taxiPlan.plan.get(q) instanceof PlanActionWait) {
+ PlanActionWait wait = (PlanActionWait) taxiPlan.plan.get(q);
+ timeToLastTransferAction = timeToLastTransferAction + wait.getWaitTime();
+ } else {
+ timeToLastTransferAction = timeToLastTransferAction + travelTimeProvider.getExpectedTravelTime(previousPos, taxiPlan.plan.get(q).getPosition());
+ }
+ previousPos = taxiPlan.plan.get(q).getPosition();
+ }
+ List segmentAfterTransfer = taxiPlan.plan.subList(indexLastTransferAction+1, taxiPlan.plan.size());
+ int indexLastPickupSegment = findLastPickupIndexList(segmentAfterTransfer);
+ long timeToLastPickup = 0;
+ SimulationNode previousPos2 = taxiPlan.plan.get(taxiPlan.plan.size()-1).getPosition();
+ if (segmentAfterTransfer.size() > 0) {
+ previousPos2 = segmentAfterTransfer.get(0).getPosition();
+ for (int q = 0; q < indexLastPickupSegment + 1; q++) {
+ timeToLastPickup = timeToLastPickup + travelTimeProvider.getExpectedTravelTime(previousPos2, segmentAfterTransfer.get(q).getPosition());
+ previousPos2 = segmentAfterTransfer.get(q).getPosition();
+ }
+ }
+ SimulationNode newPickupFrom = request.getFrom();
+ long timeToNewPick = travelTimeProvider.getExpectedTravelTime(previousPos2, newPickupFrom);
+ long estimatedArrivalToPickup = timeProvider.getCurrentSimTime() + timeToFinishCurrentEdge + timeToLastTransferAction + timeToLastPickup + timeToNewPick;
+ long maxTime = request.getMaxDropoffTime() * 1000;
+ if (estimatedArrivalToPickup > maxTime) {
+ return Long.MAX_VALUE;
+ }
+ return estimatedArrivalToPickup;
+ }
+ else {
+ int indexLastPickup = findLastPickupIndex(taxiPlan);
+ long timeToFinishCurrentEdge = 0;
+ SimulationNode previousPos = taxi.getPosition();
+ if (taxi.getCurrentTask() != null) {
+ timeToFinishCurrentEdge = travelTimeProvider.getTravelTime(taxi, taxi.getCurrentTask().getPosition());
+ previousPos = taxi.getCurrentTask().getPosition();
+ }
+ long timeToLastPickup = 0;
+ for (int q = 0; q < indexLastPickup + 1; q++) {
+ timeToLastPickup = timeToLastPickup + travelTimeProvider.getExpectedTravelTime(previousPos, taxiPlan.plan.get(q).getPosition());
+ previousPos = taxiPlan.plan.get(q).getPosition();
+ }
+ SimulationNode newPickupFrom = request.getFrom();
+ long timeToNewPick = travelTimeProvider.getExpectedTravelTime(previousPos, newPickupFrom);
+ long estimatedArrivalToNewPickup = timeProvider.getCurrentSimTime() + timeToFinishCurrentEdge + timeToLastPickup + timeToNewPick;
+ long maxTime = request.getMaxDropoffTime() * 1000;
+ if (estimatedArrivalToNewPickup > maxTime) {
+ return Long.MAX_VALUE;
+ }
+ return estimatedArrivalToNewPickup;
+ }
+ }
+
+ /**
+ * Greedy TASeT heuristics function
+ * @return
+ */
+ private Map heuristics(List taxis, List requests) {
+ //transfer points = charging stations
+ List transferPoints = this.transferPoints;
+
+ //lookup table LT - LT [t][k] stores the earliest arrival time for taxi k to charging station t without violating the tolerable delay for k’s current passengers
+ int stationsCount = transferPoints.size();
+ int taxisCount = taxis.size();
+ long[][] LT = new long[stationsCount][taxisCount];
+ //fill the LT table
+ for (int i = 0; i < taxisCount; i++) {
+ RideSharingOnDemandVehicle taxi = taxis.get(i);
+ Set requestsOnBoardSet = new HashSet<>();
+ DriverPlan actualPlan = taxi.getCurrentPlanNoUpdate();
+ for(PlanAction action : actualPlan) {
+ if(action instanceof PlanRequestAction) {
+ PlanRequestAction requestAction = (PlanRequestAction) action;
+ requestsOnBoardSet.add(requestAction.request);
+ }
+ }
+ List requestsOnBoard = new ArrayList<>(requestsOnBoardSet);
+ // kolik lidi je prave ted v aute
+ boolean taxiFree = true;
+ int taxiCapacity = taxi.getCapacity();
+ if (requestsOnBoardSet.size() >= taxiCapacity) {
+ taxiFree = false;
+ }
+ for(int j = 0; j < stationsCount; j++) {
+ //check if taxi has free seat
+ if (!taxiFree) {
+ LT[j][i] = Long.MAX_VALUE;
+ }
+ else {
+ if (isWithTransfer(taxi.getCurrentPlanNoUpdate())) {
+ // nekdo prestupuje
+ int indexLastTransferAction = findLastTransferActionIndex(taxi.getCurrentPlanNoUpdate());
+ long timeToFinishCurrentEdge = 0;
+ SimulationNode previousPos = taxi.getPosition();
+ if (taxi.getCurrentTask() != null) {
+ timeToFinishCurrentEdge = travelTimeProvider.getTravelTime(taxi, taxi.getCurrentTask().getPosition());
+ previousPos = taxi.getCurrentTask().getPosition();
+ }
+ long timeToLastTransferAction = 0;
+ for (int q = 0; q < indexLastTransferAction + 1; q++) {
+ if (taxi.getCurrentPlanNoUpdate().plan.get(q) instanceof PlanActionWait) {
+ PlanActionWait wait = (PlanActionWait) taxi.getCurrentPlanNoUpdate().plan.get(q);
+ timeToLastTransferAction = timeToLastTransferAction + wait.getWaitTime();
+ } else {
+ timeToLastTransferAction = timeToLastTransferAction + travelTimeProvider.getExpectedTravelTime(previousPos, taxi.getCurrentPlanNoUpdate().plan.get(q).getPosition());
+ }
+ previousPos = taxi.getCurrentPlanNoUpdate().plan.get(q).getPosition();
+ }
+ // ted potrebuju najit posledni pickup ve zbyvajicim driver planu po prestupu
+ List segmentAfterTransfer = taxi.getCurrentPlanNoUpdate().plan.subList(indexLastTransferAction+1, taxi.getCurrentPlanNoUpdate().plan.size());
+ int indexLastPickupSegment = findLastPickupIndexList(segmentAfterTransfer);
+ long timeToLastPickup = 0;
+ SimulationNode previousPos2 = taxi.getCurrentPlanNoUpdate().plan.get(taxi.getCurrentPlanNoUpdate().plan.size()-1).getPosition();
+ if (segmentAfterTransfer.size() > 0) {
+ previousPos2 = segmentAfterTransfer.get(0).getPosition();
+ for (int q = 0; q < indexLastPickupSegment + 1; q++) {
+ timeToLastPickup = timeToLastPickup + travelTimeProvider.getExpectedTravelTime(previousPos2, segmentAfterTransfer.get(q).getPosition());
+ previousPos2 = segmentAfterTransfer.get(q).getPosition();
+ }
+ }
+ SimulationNode station = transferPoints.get(j);
+ long timeToStation = travelTimeProvider.getExpectedTravelTime(previousPos, station);
+ long estimatedArrivalToStation = timeProvider.getCurrentSimTime() + timeToFinishCurrentEdge + timeToLastTransferAction + timeToLastPickup + timeToStation;
+ LT[j][i] = estimatedArrivalToStation;
+ Set requestsInSegmentSet = new HashSet<>();
+ for(PlanAction action : segmentAfterTransfer) {
+ if(action instanceof PlanRequestAction) {
+ PlanRequestAction requestAction = (PlanRequestAction) action;
+ requestsInSegmentSet.add(requestAction.request);
+ }
+ }
+ List requestsInSegment = new ArrayList<>(requestsInSegmentSet);
+ for (PlanComputationRequest request : requestsInSegment) {
+ long maxTime = request.getMaxDropoffTime() * 1000;
+ if (LT[j][i] > maxTime) {
+ LT[j][i] = Long.MAX_VALUE;
+ break;
+ }
+ }
+ }
+ else {
+ int indexLastPickup = findLastPickupIndex(taxi.getCurrentPlanNoUpdate());
+ long timeToFinishCurrentEdge = 0;
+ SimulationNode previousPos = taxi.getPosition();
+ if (taxi.getCurrentTask() != null) {
+ timeToFinishCurrentEdge = travelTimeProvider.getTravelTime(taxi, taxi.getCurrentTask().getPosition());
+ previousPos = taxi.getCurrentTask().getPosition();
+ }
+ long timeToLastPickup = 0;
+ for (int q = 0; q < indexLastPickup + 1; q++) {
+ timeToLastPickup = timeToLastPickup + travelTimeProvider.getExpectedTravelTime(previousPos, taxi.getCurrentPlanNoUpdate().plan.get(q).getPosition());
+ previousPos = taxi.getCurrentPlanNoUpdate().plan.get(q).getPosition();
+ }
+ SimulationNode station = transferPoints.get(j);
+ long timeToStation = travelTimeProvider.getExpectedTravelTime(previousPos, station);
+ long estimatedArrivalToStation = timeProvider.getCurrentSimTime() + timeToFinishCurrentEdge + timeToLastPickup + timeToStation;
+ LT[j][i] = estimatedArrivalToStation;
+ for (PlanComputationRequest request : requestsOnBoard) {
+ long maxTime = request.getMaxDropoffTime() * 1000;
+ if (LT[j][i] > maxTime) {
+ LT[j][i] = Long.MAX_VALUE;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ //we rank the requests in descending order by the number of taxis that are possible to pick them up in time (without considering transfer or destination)
+ //get possible taxis for every request and number of possible taxis
+ int[] possiblePickupTaxisCounts = new int[requests.size()];
+ int i = 0;
+ Map> possiblePickupTaxisMap = new HashMap<>();
+ for(PlanComputationRequest request : requests) {
+ int counter = 0;
+ List possiblePickupTaxisOneRequest = new ArrayList<>();
+ for(RideSharingOnDemandVehicle t : taxis) {
+ if (canServeRequestTASeT2(t, request)) {
+ counter++;
+ possiblePickupTaxisOneRequest.add(t);
+ }
+ }
+ possiblePickupTaxisCounts[i] = counter;
+ possiblePickupTaxisMap.put(request, possiblePickupTaxisOneRequest);
+ i++;
+ }
+
+
+ //sort R by the number of possible pickup taxis
+ List requestsCopy = new ArrayList<>(requests);
+ requests.sort(Comparator.comparing(x -> possiblePickupTaxisCounts[requestsCopy.indexOf(x)]));
+ //order to descending order - ve skutecnosti to ma byt ascending, i kdyz pisou descending :]]]
+// Collections.reverse(requests);
+
+ planMap = new ConcurrentHashMap<>();
+
+
+ for(PlanComputationRequest request : requests) {
+ List>, List>> templistP = new ArrayList<>();
+ List delays = new ArrayList<>();
+ List transferTimes = new ArrayList<>();
+ List canPickupRequestTaxis = possiblePickupTaxisMap.get(request);
+ for (RideSharingOnDemandVehicle taxi : canPickupRequestTaxis) {
+ List posbitnry = findPlanWithNoTransferNew(request, taxi);
+ if (posbitnry != null) {
+ if (checkValidItinerary(posbitnry, taxi)) {
+ List> tmp = new ArrayList<>();
+ List tmpVehs = new ArrayList<>();
+ tmpVehs.add(taxi);
+ tmp.add(posbitnry);
+ Pair>, List> pair = new Pair<>(tmp, tmpVehs);
+ templistP.add(pair);
+ long minimalArrivalTime = timeProvider.getCurrentSimTime() + travelTimeProvider.getExpectedTravelTime(request.getFrom(), request.getTo());
+ HashMap dropoffs = getEstimatedTimesOfDropoff(posbitnry, taxi);
+ long realArrivalTime = dropoffs.get(request);
+ long delay = realArrivalTime - minimalArrivalTime;
+ delays.add(delay);
+ transferTimes.add((long) 0);
+ }
+ }
+ Set requestsOnBoardSet = new HashSet<>();
+ DriverPlan actualPlan;
+ if (planMap.containsKey(taxi)) {
+ actualPlan = planMap.get(taxi);
+ } else {
+ actualPlan = taxi.getCurrentPlanNoUpdate();
+ }
+ for(PlanAction action : actualPlan) {
+ if(action instanceof PlanRequestAction) {
+ PlanRequestAction requestAction = (PlanRequestAction) action;
+ requestsOnBoardSet.add(requestAction.request);
+ }
+ }
+ List requestsOnBoard = new ArrayList<>(requestsOnBoardSet);
+
+ long timeToNewPickup = countTimeToNewPickup(taxi, request, requestsOnBoard);
+ int stationIndex = 0;
+ for (SimulationNode station : transferPoints) {
+ if (timeToNewPickup + travelTimeProvider.getExpectedTravelTime(request.getFrom(), station) >
+ request.getMaxDropoffTime() * 1000 - travelTimeProvider.getExpectedTravelTime(station, request.getTo())) {
+ continue;
+ }
+
+ // find k' = taxis that taxi k can transfer to at station
+ for (int k = 0; k < taxisCount; k++) {
+ //not possible to transfer to
+ if (LT[stationIndex][k] == Long.MAX_VALUE) {
+ continue;
+ } else if(LT[stationIndex][k] > request.getMaxDropoffTime() * 1000 - travelTimeProvider.getExpectedTravelTime(station, request.getTo())) {
+ continue;
+ } else if(taxi.equals(taxis.get(k))) {
+ continue;
+ } else if (station == request.getTo()) {
+ continue;
+ } else if (station == request.getFrom()) {
+ continue;
+ } else {
+ // split request to two requests with transfer point
+ long travelTimeFromStationToDest = travelTimeProvider.getExpectedTravelTime(station, request.getTo());
+ int maxDropOffTime = request.getMaxDropoffTime() - (int) Math.round(travelTimeFromStationToDest / 1000.0);
+ PlanActionDropoffTransfer dropoffActionTransfer = new PlanActionDropoffTransfer(request, station, maxDropOffTime);
+ PlanActionPickupTransfer pickupActionTransfer = new PlanActionPickupTransfer(request, station, maxDropOffTime);
+
+ List itnryp1 = findPlanWithNoTransferActionsNew(request.getPickUpAction(), dropoffActionTransfer, taxi); // pro auto
+ List itnryp2 = findPlanWithNoTransferActionsNew(pickupActionTransfer, request.getDropOffAction(), taxis.get(k));
+ if (itnryp1 == null || itnryp2 == null) {
+ continue;
+ }
+ Pair>, Long> p = createChargePlanNoNewRequestsWithRounding(itnryp1, itnryp2, taxi, taxis.get(k), request);
+ if (p == null) {
+ continue;
+ } else {
+ List> itnrys = p.getFirst();
+ itnryp1 = itnrys.get(0);
+ itnryp2 = itnrys.get(1);
+ List> tmp2 = new ArrayList<>();
+ tmp2.add(itnryp1);
+ tmp2.add(itnryp2);
+ List tmpVehs2 = new ArrayList<>();
+ tmpVehs2.add(taxi);
+ tmpVehs2.add(taxis.get(k));
+ Pair>, List> pair2 = new Pair<>(tmp2, tmpVehs2);
+ templistP.add(pair2);
+ HashMap drops = getEstimatedTimesOfDropoff(itnryp2, taxis.get(k));
+ if (drops == null) {
+ delays.add(Long.MAX_VALUE);
+ transferTimes.add((long) -1);
+ continue;
+ }
+ long minimalArrivalTime = timeProvider.getCurrentSimTime() + travelTimeProvider.getExpectedTravelTime(request.getFrom(), request.getTo());
+ long realArrivalTime = drops.get(request);
+ long delay = realArrivalTime - minimalArrivalTime;
+ delays.add(delay);
+ long transferTime = p.getSecond();
+ transferTimes.add(transferTime);
+ }
+ }
+ }
+ stationIndex++;
+ }
+ }
+ List listTransferPlans = new ArrayList<>();
+ for (int j = 0; j < templistP.size(); j++) {
+ TransferPlan t = new TransferPlan(transferTimes.get(j), delays.get(j), templistP.get(j));
+ listTransferPlans.add(t);
+ }
+ listTransferPlans.sort(TransferPlan::compareByDelay);
+
+ double beta = 0.2;
+ int numOfTaken = (int) (delays.size() * beta);
+ if (numOfTaken == 0) {
+ numOfTaken = 1;
+ }
+ List sublistTransferPlans = new ArrayList<>();
+ for (int q = 0; q < numOfTaken; q++)
+ {
+ if(!listTransferPlans.isEmpty()) {
+ sublistTransferPlans.add(listTransferPlans.get(q));
+ }
+ }
+ sublistTransferPlans.sort(TransferPlan::compareByTransferTime);
+ Collections.reverse(sublistTransferPlans);
+
+ if (sublistTransferPlans.isEmpty()) {
+ continue;
+ }
+ else
+ {
+ if (sublistTransferPlans.get(0).delay == Long.MAX_VALUE || sublistTransferPlans.get(0).trasferTime < 0) {
+ continue;
+ }
+ Pair>, List> key = sublistTransferPlans.get(0).pair;
+ List> plansForVehicles = key.getFirst();
+ List vehicles = key.getSecond();
+ for (int q = 0; q < vehicles.size(); q++) {
+ List vehPlan = plansForVehicles.get(q);
+ List planWithPos = new ArrayList<>();
+ planWithPos.add(vehicles.get(q).getCurrentPlanNoUpdate().plan.get(0));
+ planWithPos.addAll(vehPlan);
+ int waitTime = findWaitingAction(vehPlan, vehicles.get(q), request);
+ if (waitTime > 0) {
+ logWaitingTime(vehicles.get(q), waitTime);
+ }
+ DriverPlan dp = new DriverPlan(planWithPos, 0, 0);
+ planMap.put(vehicles.get(q), dp);
+ }
+ }
+
+ // update k, k′ and LT
+ for (int z = 0; z < taxisCount; z++) {
+ RideSharingOnDemandVehicle taxi = taxis.get(z);
+ Set requestsOnBoardSet = new HashSet<>();
+ DriverPlan actualPlan;
+ if (planMap.containsKey(taxis.get(z))) {
+ actualPlan = planMap.get(taxi);
+ } else {
+ actualPlan = taxi.getCurrentPlanNoUpdate();
+ }
+ for(PlanAction action : actualPlan) {
+ if(action instanceof PlanRequestAction) {
+ PlanRequestAction requestAction = (PlanRequestAction) action;
+ requestsOnBoardSet.add(requestAction.request);
+ }
+ }
+ List requestsOnBoard = new ArrayList<>(requestsOnBoardSet);
+ boolean taxiFree = true;
+ int taxiCapacity = taxi.getCapacity();
+ if (requestsOnBoardSet.size() >= taxiCapacity) {
+ taxiFree = false;
+ }
+ for(int j = 0; j < stationsCount; j++) {
+ if (!taxiFree) {
+ LT[j][z] = Long.MAX_VALUE;
+ } else {
+ if (isWithTransfer(actualPlan)) {
+ int indexLastTransferAction = findLastTransferActionIndex(actualPlan);
+ long timeToFinishCurrentEdge = 0;
+ SimulationNode previousPos = taxi.getPosition();
+ if (taxi.getCurrentTask() != null) {
+ timeToFinishCurrentEdge = travelTimeProvider.getTravelTime(taxi, taxi.getCurrentTask().getPosition());
+ previousPos = taxi.getCurrentTask().getPosition();
+ }
+ long timeToLastTransferAction = 0;
+ for (int q = 0; q < indexLastTransferAction + 1; q++) {
+ if (actualPlan.plan.get(q) instanceof PlanActionWait) {
+ PlanActionWait wait = (PlanActionWait) actualPlan.plan.get(q);
+ timeToLastTransferAction = timeToLastTransferAction + wait.getWaitTime();
+ } else {
+ timeToLastTransferAction = timeToLastTransferAction + travelTimeProvider.getExpectedTravelTime(previousPos, actualPlan.plan.get(q).getPosition());
+ }
+ previousPos = actualPlan.plan.get(q).getPosition();
+ }
+ List segmentAfterTransfer = actualPlan.plan.subList(indexLastTransferAction + 1, actualPlan.plan.size());
+ int indexLastPickupSegment = findLastPickupIndexList(segmentAfterTransfer);
+ long timeToLastPickup = 0;
+ SimulationNode previousPos2 = actualPlan.plan.get(actualPlan.plan.size()-1).getPosition();
+ if (segmentAfterTransfer.size() > 0) {
+ previousPos2 = segmentAfterTransfer.get(0).getPosition();
+ for (int q = 0; q < indexLastPickupSegment + 1; q++) {
+ timeToLastPickup = timeToLastPickup + travelTimeProvider.getExpectedTravelTime(previousPos2, segmentAfterTransfer.get(q).getPosition());
+ previousPos2 = segmentAfterTransfer.get(q).getPosition();
+ }
+ }
+ SimulationNode station = transferPoints.get(j);
+ long timeToStation = travelTimeProvider.getExpectedTravelTime(previousPos2, station);
+ long estimatedArrivalToStation = timeProvider.getCurrentSimTime() + timeToFinishCurrentEdge + timeToLastTransferAction + timeToLastPickup + timeToStation;
+ LT[j][z] = estimatedArrivalToStation;
+ Set requestsInSegmentSet = new HashSet<>();
+ for (PlanAction action : segmentAfterTransfer) {
+ if (action instanceof PlanRequestAction) {
+ PlanRequestAction requestAction = (PlanRequestAction) action;
+ requestsInSegmentSet.add(requestAction.request);
+ }
+ }
+ List requestsInSegment = new ArrayList<>(requestsInSegmentSet);
+ for (PlanComputationRequest r : requestsInSegment) {
+ long maxTime = r.getMaxDropoffTime() * 1000;
+ if (LT[j][z] > maxTime) {
+ LT[j][z] = Long.MAX_VALUE;
+ break;
+ }
+ }
+ } else {
+ int indexLastPickup = findLastPickupIndex(actualPlan);
+ long timeToFinishCurrentEdge = 0;
+ SimulationNode previousPos = taxi.getPosition();
+ if (taxi.getCurrentTask() != null) {
+ timeToFinishCurrentEdge = travelTimeProvider.getTravelTime(taxi, taxi.getCurrentTask().getPosition());
+ previousPos = taxi.getCurrentTask().getPosition();
+ }
+ long timeToLastPickup = 0;
+ for (int q = 0; q < indexLastPickup + 1; q++) {
+ timeToLastPickup = timeToLastPickup + travelTimeProvider.getExpectedTravelTime(previousPos, actualPlan.plan.get(q).getPosition());
+ previousPos = actualPlan.plan.get(q).getPosition();
+ }
+ SimulationNode station = transferPoints.get(j);
+ long timeToStation = travelTimeProvider.getExpectedTravelTime(previousPos, station);
+ long estimatedArrivalToStation = timeProvider.getCurrentSimTime() + timeToFinishCurrentEdge + timeToLastPickup + timeToStation;
+ LT[j][z] = estimatedArrivalToStation;
+ for (PlanComputationRequest r : requestsOnBoard) {
+ long maxTime = r.getMaxDropoffTime() * 1000;
+ if (LT[j][z] > maxTime) {
+ LT[j][z] = Long.MAX_VALUE;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ logInactiveVehicles(taxis);
+
+ return planMap;
+ }
+
+ public Integer findWaitingAction(List plan, RideSharingOnDemandVehicle vehicle, PlanComputationRequest request) {
+ for (PlanAction action : plan) {
+ if (action instanceof PlanActionWait) {
+ if (((PlanActionWait) action).getRequest() == request) {
+ PlanActionWait wait = (PlanActionWait) action;
+ return (int) Math.round(wait.getWaitTime() / 1000.0);
+ }
+ }
+ }
+ return 0;
+ }
+
+ public List> getInactiveVehicles() {
+ return inactiveVehicles;
+ }
+
+ public List> getWaitingTimes() {
+ return waitingTimes;
+ }
+
+ private boolean checkValidItinerary(List itinerary, RideSharingOnDemandVehicle vehicle) {
+ SimulationNode previousDestination = vehicle.getPosition();
+ boolean ret = true;
+ long time = timeProvider.getCurrentSimTime();
+ long timeToFinishEdge = 0;
+ previousDestination = vehicle.getPosition();
+
+ if (vehicle.getCurrentTripPlan() != null) {
+ if (vehicle.getCurrentTripPlan().getSize() == 0) {
+ SimulationNode stopLoc = (SimulationNode) vehicle.getCurrentTripPlan().getLastLocation();
+ timeToFinishEdge += travelTimeProvider.getTravelTime(vehicle, stopLoc);
+ previousDestination = stopLoc;
+ }
+ else if (vehicle.getCurrentTripPlan().getSize() > 0) {
+ SimulationNode stopLoc = (SimulationNode) vehicle.getCurrentTripPlan().getFirstLocation();
+ SimulationNode currLoc = (SimulationNode) vehicle.getCurrentTripPlan().getAllLocations()[0];
+ boolean currLocIsVehiclePosition = false;
+ int curridx = 0;
+ while (currLoc != stopLoc) {
+ if (currLocIsVehiclePosition) {
+ timeToFinishEdge += travelTimeProvider.getTravelTime(vehicle, currLoc);
+ }
+ if (currLoc == vehicle.getPosition()) {
+ currLocIsVehiclePosition = true;
+ }
+ previousDestination = (SimulationNode) vehicle.getCurrentTripPlan().getAllLocations()[curridx];
+ curridx++;
+ currLoc = (SimulationNode) vehicle.getCurrentTripPlan().getAllLocations()[curridx];
+ }
+ }
+ }
+ time += timeToFinishEdge;
+
+ for (PlanAction action : itinerary) {
+ if (action instanceof PlanRequestAction) {
+ PlanComputationRequest pcq = ((PlanRequestAction) action).getRequest();
+ if (action instanceof PlanActionPickup) {
+ SimulationNode dest = pcq.getFrom();
+ time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest);
+ if (!(time < pcq.getMaxPickupTime()*1000)) {
+ ret = false;
+ break;
+ }
+ previousDestination = dest;
+ } else if(action instanceof PlanActionPickupTransfer) {
+ PlanActionPickupTransfer pickupTransfer = (PlanActionPickupTransfer) action;
+ SimulationNode dest = pickupTransfer.getPosition();
+ time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest);
+ previousDestination = dest;
+ } else if(action instanceof PlanActionDropoffTransfer) {
+ PlanActionDropoffTransfer dropoffTransfer = (PlanActionDropoffTransfer) action;
+ SimulationNode dest = dropoffTransfer.getPosition();
+ time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest);
+ previousDestination = dest;
+ } else if (action instanceof PlanActionDropoff) {
+ SimulationNode dest = pcq.getTo();
+ time = time + travelTimeProvider.getExpectedTravelTime(previousDestination, dest);
+ if (!(time < pcq.getMaxDropoffTime()*1000)) {
+ ret = false;
+ break;
+ }
+ previousDestination = dest;
+ } else if (action instanceof PlanActionWait) {
+ PlanActionWait wait = (PlanActionWait) action;
+ time = time + wait.getWaitTime();
+ }
+ }
+ }
+ return ret;
+ }
+
+ private Pair>, Long> createChargePlanNoNewRequests(List itnryp1, List