{ "cells": [ { "cell_type": "code", "execution_count": 1, "id": "initial_id", "metadata": { "ExecuteTime": { "end_time": "2023-11-07T23:05:35.179983Z", "start_time": "2023-11-07T23:05:34.039783Z" }, "collapsed": true }, "outputs": [], "source": [ "import pandas as pd\n", "import folium\n", "import utils" ] }, { "cell_type": "code", "execution_count": 2, "id": "73b780e762c9de37", "metadata": { "ExecuteTime": { "end_time": "2023-11-07T23:05:35.194166Z", "start_time": "2023-11-07T23:05:35.181233Z" } }, "outputs": [], "source": [ "# Load the data\n", "ListA = pd.read_csv('List A.csv')\n", "ListB = pd.read_csv('List B.csv')\n", "ListC = pd.read_csv('List C.csv')\n", "ListD = pd.read_csv('List D.csv')" ] }, { "cell_type": "code", "execution_count": 3, "id": "be4c8c1d77842ef7", "metadata": { "ExecuteTime": { "end_time": "2023-11-07T23:05:35.195314Z", "start_time": "2023-11-07T23:05:35.193156Z" } }, "outputs": [], "source": [ "# Create two centroids, one in the North End and one in the Seaport District\n", "centroids = [[42.365, -71.054], [42.351, -71.045]]\n", "\n", "northeastern_coordinate = \"-71.09033,42.33976\"" ] }, { "cell_type": "code", "execution_count": 4, "id": "ffe4025e97a6c6b9", "metadata": { "ExecuteTime": { "end_time": "2023-11-07T23:05:35.201800Z", "start_time": "2023-11-07T23:05:35.197747Z" } }, "outputs": [], "source": [ "# Combine the two lists and add a column to indicate the list\n", "ListA['list'] = 'A'\n", "ListB['list'] = 'B'\n", "ListC['list'] = 'C'\n", "ListD['list'] = 'D'\n", "\n", "TotalList = pd.concat([ListA, ListB, ListC, ListD])" ] }, { "cell_type": "code", "execution_count": 5, "id": "72657779b4484aae", "metadata": { "ExecuteTime": { "end_time": "2023-11-07T23:05:35.215762Z", "start_time": "2023-11-07T23:05:35.200811Z" } }, "outputs": [], "source": [ "# Remove all columns but name and gps\n", "TotalList = TotalList[['name', 'gps', 'list']]" ] }, { "cell_type": "code", "execution_count": 6, "id": "a157ffaec020a29a", "metadata": { "ExecuteTime": { "end_time": "2023-11-07T23:05:35.215916Z", "start_time": "2023-11-07T23:05:35.204173Z" } }, "outputs": [], "source": [ "# Convert the gps column to a list of lists for k-means\n", "TotalList['gps'] = TotalList['gps'].apply(lambda x: x.strip('[]').split(','))\n", "TotalList['gps'] = TotalList['gps'].apply(lambda x: [float(i) for i in x])" ] }, { "cell_type": "code", "execution_count": 7, "id": "a03ebde91b87fa3b", "metadata": { "ExecuteTime": { "end_time": "2023-11-07T23:05:35.216384Z", "start_time": "2023-11-07T23:05:35.206794Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
namegpslist
0521 Commercial Street #525[42.3688272, -71.0553792]A
1Acorn St[42.3576234, -71.0688746]A
2Arlington's Great Meadows[42.4299758, -71.2038948]A
3Arthur Fiedler Statue[42.3565057, -71.0754527]A
4BU Beach[42.3511927, -71.1060828]A
............
33The Quiet Few[42.3670906, -71.0359889]D
34The Tall Ship Boston[42.3649544, -71.0414523]D
35Toasted Flats[42.3711266, -71.0371343]D
36Vega Market[42.3891835, -71.033703]D
37Winthrop High School[42.3803348, -70.9799864]D
\n", "

169 rows × 3 columns

\n", "
" ], "text/plain": [ " name gps list\n", "0 521 Commercial Street #525 [42.3688272, -71.0553792] A\n", "1 Acorn St [42.3576234, -71.0688746] A\n", "2 Arlington's Great Meadows [42.4299758, -71.2038948] A\n", "3 Arthur Fiedler Statue [42.3565057, -71.0754527] A\n", "4 BU Beach [42.3511927, -71.1060828] A\n", ".. ... ... ...\n", "33 The Quiet Few [42.3670906, -71.0359889] D\n", "34 The Tall Ship Boston [42.3649544, -71.0414523] D\n", "35 Toasted Flats [42.3711266, -71.0371343] D\n", "36 Vega Market [42.3891835, -71.033703] D\n", "37 Winthrop High School [42.3803348, -70.9799864] D\n", "\n", "[169 rows x 3 columns]" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "display(TotalList)" ] }, { "cell_type": "markdown", "id": "4bd41be9aca5094b", "metadata": {}, "source": [ "# 2 Routes" ] }, { "cell_type": "markdown", "id": "90d1d2f1a931597f", "metadata": {}, "source": [ "## Cluster and Minimize" ] }, { "cell_type": "code", "execution_count": 8, "id": "ee9b3c1ecb360976", "metadata": { "ExecuteTime": { "end_time": "2023-11-07T23:06:04.963804Z", "start_time": "2023-11-07T23:05:35.213646Z" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/Users/garrinshieh/anaconda3/lib/python3.11/site-packages/sklearn/cluster/_kmeans.py:1412: FutureWarning: The default value of `n_init` will change from 10 to 'auto' in 1.4. Set the value of `n_init` explicitly to suppress the warning\n", " super()._check_params_vs_input(X, default_n_init=10)\n", "/Users/garrinshieh/anaconda3/lib/python3.11/site-packages/sklearn/cluster/_kmeans.py:1412: RuntimeWarning: Explicit initial center position passed: performing only one init in KMeans instead of n_init=10.\n", " super()._check_params_vs_input(X, default_n_init=10)\n" ] } ], "source": [ "# Cluster and minimize the data\n", "_, routes = utils.cluster_and_optimize(TotalList, centroids, northeastern_coordinate,\n", " time_diff=0.25, max_time=24)\n", "\n", "route_1_coordinates = routes[0]\n", "route_2_coordinates = routes[1]" ] }, { "cell_type": "markdown", "id": "c85b8ef869e35006", "metadata": { "ExecuteTime": { "end_time": "2023-11-07T17:33:02.697755Z", "start_time": "2023-11-07T17:33:02.687460Z" } }, "source": [ "## Create JSON" ] }, { "cell_type": "code", "execution_count": 9, "id": "aa618161182b5b07", "metadata": { "ExecuteTime": { "end_time": "2023-11-07T23:06:04.981278Z", "start_time": "2023-11-07T23:06:04.967948Z" } }, "outputs": [], "source": [ "# Create a JSON request for the API\n", "# This is the data we want to get from the API\n", "route_1 = utils.list_to_string(route_1_coordinates)\n", "route_2 = utils.list_to_string(route_2_coordinates)" ] }, { "cell_type": "code", "execution_count": 10, "id": "32c485788eedd94", "metadata": { "ExecuteTime": { "end_time": "2023-11-07T23:06:07.185941Z", "start_time": "2023-11-07T23:06:04.976840Z" } }, "outputs": [], "source": [ "# Create a dataframe from the JSON\n", "df1 = utils.create_json_df(route_1, utils.list_to_string([centroids[0]]), northeastern_coordinate)\n", "df2 = utils.create_json_df(route_2, utils.list_to_string([centroids[1]]), northeastern_coordinate)" ] }, { "cell_type": "code", "execution_count": 11, "id": "49dba1f17ca8337e", "metadata": { "ExecuteTime": { "end_time": "2023-11-07T23:06:07.206851Z", "start_time": "2023-11-07T23:06:07.193514Z" } }, "outputs": [], "source": [ "# Add columns for the route number\n", "df1['route'] = 1\n", "df2['route'] = 2\n", "\n", "# Concatenate the two dataframes\n", "df = pd.concat([df1, df2], ignore_index=True)" ] }, { "cell_type": "code", "execution_count": 12, "id": "f231d9a35358988c", "metadata": { "ExecuteTime": { "end_time": "2023-11-07T23:06:07.219423Z", "start_time": "2023-11-07T23:06:07.214064Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
waypoint_indextrips_indexhintdistancenamelocationlatlonroute
0001IwsgDuNLIBFAAAAWgEAAA8AAAAAAAAAFQP1QGa9GUI7qN...8.262982[-71.053931, 42.365054]-71.05393142.3650541
110G4gsgDiILICSAwAA5gAAAOkAAAAAAAAAQljLQnyXy0Fhy8...2.602121[-71.056164, 42.366918]-71.05616442.3669181
220gIosgLaKLIDOAAAArgAAAFwBAAAAAAAAp3O3QafxmUEQiR...15.458439[-71.055561, 42.368861]-71.05556142.3688611
330HpwsgCKcLIAAAAAAEgAAAAAAAAAAAAAAAAAAACg870AAAA...39.201677[-71.062507, 42.365968]-71.06250742.3659681
440qn8sgKt_LIAfAAAAAAAAAAAAAAAAAAAA2ElcQAAAAAAAAA...39.331841[-71.064277, 42.358851]-71.06427742.3588511
..............................
1686107hAigPYQIoA2AgAAYwEAAAAAAAAAAAAAnsd7Qq9XHUIAAA...7.478611[-71.096959, 42.344689]-71.09695942.3446892
169620bwwigH0MIoAFAAAAEAAAAFUAAAArAAAAag0xP3921D-BFx...8.340476[-71.095003, 42.342001]-71.09500342.3420012
170630MQwigFwMIoAoAAAANQAAABwAAAB-AAAAoidqQSAYl0GvUh...11.504463[-71.094327, 42.341231]-71.09432742.3412312
171640k4chgBiIIYAKAAAAFwAAAPQDAAB_AgAAHn2aP-biHUBi6e...36.240351[-71.093834, 42.339096]-71.09383442.3390962
172650DoUhgBeFIYCcAAAAJgAAAAAAAAARAAAAm0CKQdkZiEAAAA...0.236958Northeastern (Inbound)[-71.090331, 42.339762]-71.09033142.3397622
\n", "

173 rows × 9 columns

\n", "
" ], "text/plain": [ " waypoint_index trips_index \\\n", "0 0 0 \n", "1 1 0 \n", "2 2 0 \n", "3 3 0 \n", "4 4 0 \n", ".. ... ... \n", "168 61 0 \n", "169 62 0 \n", "170 63 0 \n", "171 64 0 \n", "172 65 0 \n", "\n", " hint distance \\\n", "0 1IwsgDuNLIBFAAAAWgEAAA8AAAAAAAAAFQP1QGa9GUI7qN... 8.262982 \n", "1 G4gsgDiILICSAwAA5gAAAOkAAAAAAAAAQljLQnyXy0Fhy8... 2.602121 \n", "2 gIosgLaKLIDOAAAArgAAAFwBAAAAAAAAp3O3QafxmUEQiR... 15.458439 \n", "3 HpwsgCKcLIAAAAAAEgAAAAAAAAAAAAAAAAAAACg870AAAA... 39.201677 \n", "4 qn8sgKt_LIAfAAAAAAAAAAAAAAAAAAAA2ElcQAAAAAAAAA... 39.331841 \n", ".. ... ... \n", "168 7hAigPYQIoA2AgAAYwEAAAAAAAAAAAAAnsd7Qq9XHUIAAA... 7.478611 \n", "169 bwwigH0MIoAFAAAAEAAAAFUAAAArAAAAag0xP3921D-BFx... 8.340476 \n", "170 MQwigFwMIoAoAAAANQAAABwAAAB-AAAAoidqQSAYl0GvUh... 11.504463 \n", "171 k4chgBiIIYAKAAAAFwAAAPQDAAB_AgAAHn2aP-biHUBi6e... 36.240351 \n", "172 DoUhgBeFIYCcAAAAJgAAAAAAAAARAAAAm0CKQdkZiEAAAA... 0.236958 \n", "\n", " name location lat lon \\\n", "0 [-71.053931, 42.365054] -71.053931 42.365054 \n", "1 [-71.056164, 42.366918] -71.056164 42.366918 \n", "2 [-71.055561, 42.368861] -71.055561 42.368861 \n", "3 [-71.062507, 42.365968] -71.062507 42.365968 \n", "4 [-71.064277, 42.358851] -71.064277 42.358851 \n", ".. ... ... ... ... \n", "168 [-71.096959, 42.344689] -71.096959 42.344689 \n", "169 [-71.095003, 42.342001] -71.095003 42.342001 \n", "170 [-71.094327, 42.341231] -71.094327 42.341231 \n", "171 [-71.093834, 42.339096] -71.093834 42.339096 \n", "172 Northeastern (Inbound) [-71.090331, 42.339762] -71.090331 42.339762 \n", "\n", " route \n", "0 1 \n", "1 1 \n", "2 1 \n", "3 1 \n", "4 1 \n", ".. ... \n", "168 2 \n", "169 2 \n", "170 2 \n", "171 2 \n", "172 2 \n", "\n", "[173 rows x 9 columns]" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "display(df)" ] }, { "cell_type": "markdown", "id": "75be92e34a36147f", "metadata": {}, "source": [ "## Map" ] }, { "cell_type": "code", "execution_count": 13, "id": "80fd847da2833913", "metadata": { "ExecuteTime": { "end_time": "2023-11-07T23:06:07.316817Z", "start_time": "2023-11-07T23:06:07.221200Z" } }, "outputs": [ { "data": { "text/html": [ "
Make this Notebook Trusted to load map: File -> Trust Notebook
" ], "text/plain": [ "" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Create a map\n", "m = folium.Map(location=[df['lon'].mean(), df['lat'].mean()], zoom_start=11)\n", "\n", "# Add the points and lines for the two routes with different colors\n", "colors = ['red', 'blue']\n", "\n", "for route in df['route'].unique():\n", " df_route = df[df['route'] == route]\n", " folium.PolyLine(df_route[['lon', 'lat']].values.tolist(), color=colors[route - 1]).add_to(m)\n", " for i in range(len(df_route)):\n", " folium.CircleMarker(df_route[['lon', 'lat']].iloc[i].values.tolist(), radius=3, color=colors[route - 1]).add_to(\n", " m)\n", "\n", "# Display the map\n", "m" ] }, { "cell_type": "markdown", "id": "a7b562f75f7e0813", "metadata": {}, "source": [ "## Results" ] }, { "cell_type": "code", "execution_count": 14, "id": "f53c97acec1c2fc4", "metadata": { "ExecuteTime": { "end_time": "2023-11-07T23:06:07.318988Z", "start_time": "2023-11-07T23:06:07.297230Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Route 1 has 105 waypoints\n", "Route 2 has 64 waypoints\n" ] } ], "source": [ "# Get the number of waypoints for each route\n", "route_1_waypoints = len(route_1_coordinates)\n", "route_2_waypoints = len(route_2_coordinates)\n", "print(\"Route 1 has {} waypoints\".format(route_1_waypoints))\n", "print(\"Route 2 has {} waypoints\".format(route_2_waypoints))" ] }, { "cell_type": "code", "execution_count": 15, "id": "a3ec09dfb5cbb5b3", "metadata": { "ExecuteTime": { "end_time": "2023-11-07T23:06:09.735945Z", "start_time": "2023-11-07T23:06:07.299647Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The trip will take 13.1925 hours\n", "The trip will take 13.017777777777777 hours\n" ] } ], "source": [ "trip_hrs_1 = utils.get_trip_time(route_1, route_1_waypoints, utils.list_to_string([centroids[0]]),\n", " northeastern_coordinate)\n", "print(\"The trip will take {} hours\".format(trip_hrs_1))\n", "trip_hrs_2 = utils.get_trip_time(route_2, route_2_waypoints, utils.list_to_string([centroids[1]]),\n", " northeastern_coordinate)\n", "print(\"The trip will take {} hours\".format(trip_hrs_2))" ] }, { "cell_type": "markdown", "id": "de7b5856172d213c", "metadata": {}, "source": [ "# 3 Routes" ] }, { "cell_type": "code", "execution_count": 16, "id": "bb6e00857e8175c0", "metadata": { "ExecuteTime": { "end_time": "2023-11-07T23:07:36.195528Z", "start_time": "2023-11-07T23:06:09.732162Z" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/Users/garrinshieh/anaconda3/lib/python3.11/site-packages/sklearn/cluster/_kmeans.py:1412: FutureWarning: The default value of `n_init` will change from 10 to 'auto' in 1.4. Set the value of `n_init` explicitly to suppress the warning\n", " super()._check_params_vs_input(X, default_n_init=10)\n", "/Users/garrinshieh/anaconda3/lib/python3.11/site-packages/sklearn/cluster/_kmeans.py:1412: RuntimeWarning: Explicit initial center position passed: performing only one init in KMeans instead of n_init=10.\n", " super()._check_params_vs_input(X, default_n_init=10)\n" ] } ], "source": [ "# Cluster and minimize the data\n", "# Add a third centroid in the Financial District\n", "centroids.append([42.356, -71.055])\n", "_, routes = utils.cluster_and_optimize(TotalList, centroids, northeastern_coordinate, time_diff=0.3, max_time=24)\n", "\n", "route_1_coordinates = routes[0]\n", "route_2_coordinates = routes[1]\n", "route_3_coordinates = routes[2]" ] }, { "cell_type": "markdown", "id": "19afb4f687b37383", "metadata": {}, "source": [ "## Create JSON" ] }, { "cell_type": "code", "execution_count": 17, "id": "e886e061f86a2118", "metadata": { "ExecuteTime": { "end_time": "2023-11-07T23:07:36.198703Z", "start_time": "2023-11-07T23:07:36.194798Z" } }, "outputs": [], "source": [ "# Create a JSON request for the API\n", "# This is the data we want to get from the API\n", "route_1 = utils.list_to_string(route_1_coordinates)\n", "route_2 = utils.list_to_string(route_2_coordinates)\n", "route_3 = utils.list_to_string(route_3_coordinates)" ] }, { "cell_type": "code", "execution_count": 18, "id": "23e4682fe9e30631", "metadata": { "ExecuteTime": { "end_time": "2023-11-07T23:07:38.315154Z", "start_time": "2023-11-07T23:07:36.199174Z" } }, "outputs": [], "source": [ "# Create a dataframe from the JSON\n", "df1 = utils.create_json_df(route_1, utils.list_to_string([centroids[0]]), northeastern_coordinate)\n", "df2 = utils.create_json_df(route_2, utils.list_to_string([centroids[1]]), northeastern_coordinate)\n", "df3 = utils.create_json_df(route_3, utils.list_to_string([centroids[2]]), northeastern_coordinate)" ] }, { "cell_type": "code", "execution_count": 19, "id": "c3a5c5d6f3ac46c0", "metadata": { "ExecuteTime": { "end_time": "2023-11-07T23:07:38.325567Z", "start_time": "2023-11-07T23:07:38.320173Z" } }, "outputs": [], "source": [ "# Add columns for the route number\n", "df1['route'] = 1\n", "df2['route'] = 2\n", "df3['route'] = 3\n", "\n", "# Concatenate the three dataframes\n", "df = pd.concat([df1, df2, df3], ignore_index=True)" ] }, { "cell_type": "code", "execution_count": 20, "id": "17a8cc8fed5450a6", "metadata": { "ExecuteTime": { "end_time": "2023-11-07T23:07:38.333653Z", "start_time": "2023-11-07T23:07:38.322616Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
waypoint_indextrips_indexhintdistancenamelocationlatlonroute
0001IwsgDuNLIBFAAAAWgEAAA8AAAAAAAAAFQP1QGa9GUI7qN...8.262982[-71.053931, 42.365054]-71.05393142.3650541
110G4gsgDiILICSAwAA5gAAAOkAAAAAAAAAQljLQnyXy0Fhy8...2.602121[-71.056164, 42.366918]-71.05616442.3669181
220gIosgLaKLIDOAAAArgAAAFwBAAAAAAAAp3O3QafxmUEQiR...15.458439[-71.055561, 42.368861]-71.05556142.3688611
330HpwsgCKcLIAAAAAAEgAAAAAAAAAAAAAAAAAAACg870AAAA...39.201677[-71.062507, 42.365968]-71.06250742.3659681
440LRUugHAVLoA1AAAA7wEAAKAAAADqAAAAYZa9QBEBXEIOWo...1.865658[-71.061735, 42.369195]-71.06173542.3691951
..............................
1704907hAigPYQIoA2AgAAYwEAAAAAAAAAAAAAnsd7Qq9XHUIAAA...7.478611[-71.096959, 42.344689]-71.09695942.3446893
171500bwwigH0MIoAFAAAAEAAAAFUAAAArAAAAag0xP3921D-BFx...8.340476[-71.095003, 42.342001]-71.09500342.3420013
172510MQwigFwMIoAoAAAANQAAABwAAAB-AAAAoidqQSAYl0GvUh...11.504463[-71.094327, 42.341231]-71.09432742.3412313
173520k4chgBiIIYAKAAAAFwAAAPQDAAB_AgAAHn2aP-biHUBi6e...36.240351[-71.093834, 42.339096]-71.09383442.3390963
174530DoUhgBeFIYCcAAAAJgAAAAAAAAARAAAAm0CKQdkZiEAAAA...0.236958Northeastern (Inbound)[-71.090331, 42.339762]-71.09033142.3397623
\n", "

175 rows × 9 columns

\n", "
" ], "text/plain": [ " waypoint_index trips_index \\\n", "0 0 0 \n", "1 1 0 \n", "2 2 0 \n", "3 3 0 \n", "4 4 0 \n", ".. ... ... \n", "170 49 0 \n", "171 50 0 \n", "172 51 0 \n", "173 52 0 \n", "174 53 0 \n", "\n", " hint distance \\\n", "0 1IwsgDuNLIBFAAAAWgEAAA8AAAAAAAAAFQP1QGa9GUI7qN... 8.262982 \n", "1 G4gsgDiILICSAwAA5gAAAOkAAAAAAAAAQljLQnyXy0Fhy8... 2.602121 \n", "2 gIosgLaKLIDOAAAArgAAAFwBAAAAAAAAp3O3QafxmUEQiR... 15.458439 \n", "3 HpwsgCKcLIAAAAAAEgAAAAAAAAAAAAAAAAAAACg870AAAA... 39.201677 \n", "4 LRUugHAVLoA1AAAA7wEAAKAAAADqAAAAYZa9QBEBXEIOWo... 1.865658 \n", ".. ... ... \n", "170 7hAigPYQIoA2AgAAYwEAAAAAAAAAAAAAnsd7Qq9XHUIAAA... 7.478611 \n", "171 bwwigH0MIoAFAAAAEAAAAFUAAAArAAAAag0xP3921D-BFx... 8.340476 \n", "172 MQwigFwMIoAoAAAANQAAABwAAAB-AAAAoidqQSAYl0GvUh... 11.504463 \n", "173 k4chgBiIIYAKAAAAFwAAAPQDAAB_AgAAHn2aP-biHUBi6e... 36.240351 \n", "174 DoUhgBeFIYCcAAAAJgAAAAAAAAARAAAAm0CKQdkZiEAAAA... 0.236958 \n", "\n", " name location lat lon \\\n", "0 [-71.053931, 42.365054] -71.053931 42.365054 \n", "1 [-71.056164, 42.366918] -71.056164 42.366918 \n", "2 [-71.055561, 42.368861] -71.055561 42.368861 \n", "3 [-71.062507, 42.365968] -71.062507 42.365968 \n", "4 [-71.061735, 42.369195] -71.061735 42.369195 \n", ".. ... ... ... ... \n", "170 [-71.096959, 42.344689] -71.096959 42.344689 \n", "171 [-71.095003, 42.342001] -71.095003 42.342001 \n", "172 [-71.094327, 42.341231] -71.094327 42.341231 \n", "173 [-71.093834, 42.339096] -71.093834 42.339096 \n", "174 Northeastern (Inbound) [-71.090331, 42.339762] -71.090331 42.339762 \n", "\n", " route \n", "0 1 \n", "1 1 \n", "2 1 \n", "3 1 \n", "4 1 \n", ".. ... \n", "170 3 \n", "171 3 \n", "172 3 \n", "173 3 \n", "174 3 \n", "\n", "[175 rows x 9 columns]" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "display(df)" ] }, { "cell_type": "markdown", "id": "b20a57aa09792c39", "metadata": {}, "source": [ "## Map" ] }, { "cell_type": "code", "execution_count": 21, "id": "702adaec008a6ec8", "metadata": { "ExecuteTime": { "end_time": "2023-11-07T23:07:38.444061Z", "start_time": "2023-11-07T23:07:38.336503Z" } }, "outputs": [ { "data": { "text/html": [ "
Make this Notebook Trusted to load map: File -> Trust Notebook
" ], "text/plain": [ "" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Create a map\n", "m = folium.Map(location=[df['lon'].mean(), df['lat'].mean()], zoom_start=11)\n", "\n", "# Add the points and lines for the three routes with different colors\n", "colors = ['red', 'blue', 'green']\n", "\n", "for route in df['route'].unique():\n", " df_route = df[df['route'] == route]\n", " folium.PolyLine(df_route[['lon', 'lat']].values.tolist(), color=colors[route - 1]).add_to(m)\n", " for i in range(len(df_route)):\n", " folium.CircleMarker(df_route[['lon', 'lat']].iloc[i].values.tolist(), radius=3, color=colors[route - 1]).add_to(\n", " m)\n", "\n", "# Display the map\n", "m" ] }, { "cell_type": "markdown", "id": "a947e49e27c734e9", "metadata": {}, "source": [ "## Results" ] }, { "cell_type": "code", "execution_count": 22, "id": "4106acf2adad01d7", "metadata": { "ExecuteTime": { "end_time": "2023-11-07T23:07:38.445284Z", "start_time": "2023-11-07T23:07:38.401884Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Route 1 has 61 waypoints\n", "Route 2 has 56 waypoints\n", "Route 3 has 52 waypoints\n" ] } ], "source": [ "# Get the number of waypoints for each route\n", "route_1_waypoints = len(route_1_coordinates)\n", "route_2_waypoints = len(route_2_coordinates)\n", "route_3_waypoints = len(route_3_coordinates)\n", "print(\"Route 1 has {} waypoints\".format(route_1_waypoints))\n", "print(\"Route 2 has {} waypoints\".format(route_2_waypoints))\n", "print(\"Route 3 has {} waypoints\".format(route_3_waypoints))" ] }, { "cell_type": "code", "execution_count": 23, "id": "c58106faf0fc7f4e", "metadata": { "ExecuteTime": { "end_time": "2023-11-07T23:07:40.521741Z", "start_time": "2023-11-07T23:07:38.405889Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The trip will take 9.394444444444444 hours\n", "The trip will take 8.852777777777778 hours\n", "The trip will take 9.325555555555555 hours\n" ] } ], "source": [ "# Get the trip time for each route\n", "trip_hrs_1 = utils.get_trip_time(route_1, route_1_waypoints, utils.list_to_string([centroids[0]]),\n", " northeastern_coordinate)\n", "print(\"The trip will take {} hours\".format(trip_hrs_1))\n", "trip_hrs_2 = utils.get_trip_time(route_2, route_2_waypoints, utils.list_to_string([centroids[1]]),\n", " northeastern_coordinate)\n", "print(\"The trip will take {} hours\".format(trip_hrs_2))\n", "trip_hrs_3 = utils.get_trip_time(route_3, route_3_waypoints, utils.list_to_string([centroids[2]]),\n", " northeastern_coordinate)\n", "print(\"The trip will take {} hours\".format(trip_hrs_3))" ] }, { "cell_type": "markdown", "id": "4068a0b6460f19ab", "metadata": {}, "source": [ "# 10 ROUTES (because I can)" ] }, { "cell_type": "code", "execution_count": 24, "id": "5995d6556f940e67", "metadata": { "ExecuteTime": { "end_time": "2023-11-07T23:09:18.376367Z", "start_time": "2023-11-07T23:07:40.529888Z" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/Users/garrinshieh/anaconda3/lib/python3.11/site-packages/sklearn/cluster/_kmeans.py:1412: FutureWarning: The default value of `n_init` will change from 10 to 'auto' in 1.4. Set the value of `n_init` explicitly to suppress the warning\n", " super()._check_params_vs_input(X, default_n_init=10)\n", "/Users/garrinshieh/anaconda3/lib/python3.11/site-packages/sklearn/cluster/_kmeans.py:1412: RuntimeWarning: Explicit initial center position passed: performing only one init in KMeans instead of n_init=10.\n", " super()._check_params_vs_input(X, default_n_init=10)\n" ] } ], "source": [ "# Cluster and minimize the data\n", "# Add seven more centroids around Boston with different latitudes and longitudes\n", "for i in range(7):\n", " centroids.append([42.365 + i * 0.01, -71.054 + i * 0.01])\n", "\n", "_, routes = utils.cluster_and_optimize(TotalList, centroids, northeastern_coordinate, time_diff=0.5, max_time=24)" ] }, { "cell_type": "markdown", "id": "8c6f5aeb5e6c2832", "metadata": {}, "source": [ "## Create JSON" ] }, { "cell_type": "code", "execution_count": 25, "id": "375b090921cab03e", "metadata": { "ExecuteTime": { "end_time": "2023-11-07T23:09:18.395941Z", "start_time": "2023-11-07T23:09:18.378652Z" } }, "outputs": [], "source": [ "# Create a JSON request for the API\n", "# This is the data we want to get from the API\n", "route_strings = []\n", "for route in routes:\n", " route_strings.append(utils.list_to_string(route))" ] }, { "cell_type": "code", "execution_count": 26, "id": "74f619c6df3bd6c4", "metadata": { "ExecuteTime": { "end_time": "2023-11-07T23:09:21.149586Z", "start_time": "2023-11-07T23:09:18.384347Z" } }, "outputs": [], "source": [ "# Create a dataframe from the JSON\n", "dfs = []\n", "for i in range(len(routes)):\n", " dfs.append(utils.create_json_df(route_strings[i], utils.list_to_string([centroids[i]]), northeastern_coordinate))\n", " \n", "# Concatenate the dataframes\n", "df = pd.concat(dfs, ignore_index=True)" ] }, { "cell_type": "code", "execution_count": 30, "id": "488924ebe78c61aa", "metadata": { "ExecuteTime": { "end_time": "2023-11-07T23:10:17.312994Z", "start_time": "2023-11-07T23:10:17.307208Z" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/var/folders/8b/9mzlkxlx3zx9nmpy8prjpmm80000gn/T/ipykernel_42497/2886398449.py:3: SettingWithCopyWarning: \n", "A value is trying to be set on a copy of a slice from a DataFrame\n", "\n", "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n", " df['route'].iloc[i * len(routes[i]):(i + 1) * len(routes[i])] = i + 1\n" ] } ], "source": [ "# Add columns for the route number\n", "for i in range(len(routes)):\n", " df['route'].iloc[i * len(routes[i]):(i + 1) * len(routes[i])] = i + 1" ] }, { "cell_type": "code", "execution_count": 31, "id": "8e436ba5d3949420", "metadata": { "ExecuteTime": { "end_time": "2023-11-07T23:10:19.393773Z", "start_time": "2023-11-07T23:10:19.390813Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
waypoint_indextrips_indexhintdistancenamelocationlatlonroute
0001IwsgDuNLIBFAAAAWgEAAA8AAAAAAAAAFQP1QGa9GUI7qN...8.262982[-71.053931, 42.365054]-71.05393142.3650541
110LRUugHAVLoA1AAAA7wEAAKAAAADqAAAAYZa9QBEBXEIOWo...1.865658[-71.061735, 42.369195]-71.06173542.3691951
220lM4AgM3LAIAEAAAAHAAAAJEAAAC_AgAAyLv6PxJ7NEGyPn...2.242639Miller's River Littoral Way[-71.065634, 42.371832]-71.06563442.3718321
330ZQ0fgPINH4AgAAAAEQAAAFEAAAAqAAAArYRYQRHu20BfWQ...48.627645[-71.06828, 42.369868]-71.06828042.3698684
440HR8ugIJiBICVAQAARwAAAAAAAACLAAAAQ1M0Qu3l-EAAAA...0.645763[-71.094764, 42.377355]-71.09476442.3773551
..............................
184110-2EugABiLoCcAQAAigAAAAAAAAAAAAAAMQI3QqZ0dUEAAA...7.363621[-71.102659, 42.382131]-71.10265942.38213110
185120VSIfgAYjH4AUAAAAAAAAACUBAADDAAAAaIcPQAAAAADYBw...18.888832[-71.110851, 42.374259]-71.11085142.3742596
1861300OEhgPvhIYADAAAABgAAAA8AAAA0AAAA2lq-PipQFD-Y-N...2.009578[-71.085166, 42.349997]-71.08516642.3499976
187140C-AhgGbgIYBZAAAAMQAAAAAAAABqAAAAj5QfQS1zq0AAAA...4.887502[-71.091358, 42.348977]-71.09135842.3489776
188150DoUhgBeFIYCcAAAAJgAAAAAAAAARAAAAm0CKQdkZiEAAAA...0.236958Northeastern (Inbound)[-71.090331, 42.339762]-71.09033142.3397626
\n", "

189 rows × 9 columns

\n", "
" ], "text/plain": [ " waypoint_index trips_index \\\n", "0 0 0 \n", "1 1 0 \n", "2 2 0 \n", "3 3 0 \n", "4 4 0 \n", ".. ... ... \n", "184 11 0 \n", "185 12 0 \n", "186 13 0 \n", "187 14 0 \n", "188 15 0 \n", "\n", " hint distance \\\n", "0 1IwsgDuNLIBFAAAAWgEAAA8AAAAAAAAAFQP1QGa9GUI7qN... 8.262982 \n", "1 LRUugHAVLoA1AAAA7wEAAKAAAADqAAAAYZa9QBEBXEIOWo... 1.865658 \n", "2 lM4AgM3LAIAEAAAAHAAAAJEAAAC_AgAAyLv6PxJ7NEGyPn... 2.242639 \n", "3 ZQ0fgPINH4AgAAAAEQAAAFEAAAAqAAAArYRYQRHu20BfWQ... 48.627645 \n", "4 HR8ugIJiBICVAQAARwAAAAAAAACLAAAAQ1M0Qu3l-EAAAA... 0.645763 \n", ".. ... ... \n", "184 -2EugABiLoCcAQAAigAAAAAAAAAAAAAAMQI3QqZ0dUEAAA... 7.363621 \n", "185 VSIfgAYjH4AUAAAAAAAAACUBAADDAAAAaIcPQAAAAADYBw... 18.888832 \n", "186 0OEhgPvhIYADAAAABgAAAA8AAAA0AAAA2lq-PipQFD-Y-N... 2.009578 \n", "187 C-AhgGbgIYBZAAAAMQAAAAAAAABqAAAAj5QfQS1zq0AAAA... 4.887502 \n", "188 DoUhgBeFIYCcAAAAJgAAAAAAAAARAAAAm0CKQdkZiEAAAA... 0.236958 \n", "\n", " name location lat \\\n", "0 [-71.053931, 42.365054] -71.053931 \n", "1 [-71.061735, 42.369195] -71.061735 \n", "2 Miller's River Littoral Way [-71.065634, 42.371832] -71.065634 \n", "3 [-71.06828, 42.369868] -71.068280 \n", "4 [-71.094764, 42.377355] -71.094764 \n", ".. ... ... ... \n", "184 [-71.102659, 42.382131] -71.102659 \n", "185 [-71.110851, 42.374259] -71.110851 \n", "186 [-71.085166, 42.349997] -71.085166 \n", "187 [-71.091358, 42.348977] -71.091358 \n", "188 Northeastern (Inbound) [-71.090331, 42.339762] -71.090331 \n", "\n", " lon route \n", "0 42.365054 1 \n", "1 42.369195 1 \n", "2 42.371832 1 \n", "3 42.369868 4 \n", "4 42.377355 1 \n", ".. ... ... \n", "184 42.382131 10 \n", "185 42.374259 6 \n", "186 42.349997 6 \n", "187 42.348977 6 \n", "188 42.339762 6 \n", "\n", "[189 rows x 9 columns]" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Display the dataframe\n", "display(df)" ] }, { "cell_type": "markdown", "id": "1552586cb84a48c5", "metadata": {}, "source": [ "## Map" ] }, { "cell_type": "code", "execution_count": 37, "id": "4305c6981e48e87f", "metadata": { "ExecuteTime": { "end_time": "2023-11-07T23:13:22.619199Z", "start_time": "2023-11-07T23:13:22.527566Z" } }, "outputs": [ { "data": { "text/html": [ "
Make this Notebook Trusted to load map: File -> Trust Notebook
" ], "text/plain": [ "" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Create a map\n", "m = folium.Map(location=[df['lon'].mean(), df['lat'].mean()], zoom_start=11)\n", "\n", "# Add the points and lines for the three routes with different colors\n", "colors = ['red', 'blue', 'green', 'orange', 'purple', 'pink', 'black', 'gray', 'brown', 'yellow']\n", "\n", "for route in df['route'].unique():\n", " df_route = df[df['route'] == route]\n", " folium.PolyLine(df_route[['lon', 'lat']].values.tolist(), color=colors[route - 1]).add_to(m)\n", " for i in range(len(df_route)):\n", " folium.CircleMarker(df_route[['lon', 'lat']].iloc[i].values.tolist(), radius=3, color=colors[route - 1]).add_to(\n", " m)\n", " \n", "# Display the map\n", "m" ] }, { "cell_type": "markdown", "id": "4723f2f26efe49d3", "metadata": {}, "source": [ "## Results" ] }, { "cell_type": "code", "execution_count": 36, "id": "5887f93dd890bc77", "metadata": { "ExecuteTime": { "end_time": "2023-11-07T23:12:32.990935Z", "start_time": "2023-11-07T23:12:32.987254Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Route 1 has 20 waypoints\n", "Route 2 has 10 waypoints\n", "Route 3 has 28 waypoints\n", "Route 4 has 1 waypoints\n", "Route 5 has 15 waypoints\n", "Route 6 has 37 waypoints\n", "Route 7 has 18 waypoints\n", "Route 8 has 16 waypoints\n", "Route 9 has 10 waypoints\n", "Route 10 has 14 waypoints\n" ] } ], "source": [ "# Get the number of waypoints for each route\n", "route_waypoints = []\n", "for route in routes:\n", " route_waypoints.append(len(route))\n", "for i in range(len(route_waypoints)):\n", " print(\"Route {} has {} waypoints\".format(i + 1, route_waypoints[i]))" ] }, { "cell_type": "code", "execution_count": 34, "id": "3a4b529fc3f2b336", "metadata": { "ExecuteTime": { "end_time": "2023-11-07T23:11:11.477373Z", "start_time": "2023-11-07T23:11:08.172393Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The trip will take 3.1816666666666666 hours\n", "The trip will take 3.8113888888888887 hours\n", "The trip will take 3.9852777777777777 hours\n", "The trip will take 3.8975 hours\n", "The trip will take 4.088611111111111 hours\n", "The trip will take 4.039444444444444 hours\n", "The trip will take 3.17 hours\n", "The trip will take 3.209722222222222 hours\n", "The trip will take 4.1275 hours\n", "The trip will take 3.2069444444444444 hours\n" ] } ], "source": [ "# Get the trip time for each route\n", "trip_hrs = []\n", "for i in range(len(routes)):\n", " trip_hrs.append(utils.get_trip_time(route_strings[i], route_waypoints[i], utils.list_to_string([centroids[i]]),\n", " northeastern_coordinate))\n", "for i in range(len(trip_hrs)):\n", " print(\"The trip will take {} hours\".format(trip_hrs[i]))" ] }, { "cell_type": "code", "execution_count": null, "id": "a4cf5509f890423a", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.11.4" } }, "nbformat": 4, "nbformat_minor": 5 }