diff --git a/Maps/Driving Distance/Driving Distance between two places.ipynb b/Maps/Driving Distance/Driving Distance between two places.ipynb index c858623..620d9a1 100644 --- a/Maps/Driving Distance/Driving Distance between two places.ipynb +++ b/Maps/Driving Distance/Driving Distance between two places.ipynb @@ -35,7 +35,7 @@ "# from sklearn.external import six\n", "# to:\n", "# import six\n", - "from mlrose import TravellingSales, TSPOpt, genetic_alg # for travelling salesman problem\n", + "import mlrose # for travelling salesman problem\n", "\n", "# that was fixed in mlrose_hiive, though the outputs are different\n", "# import mlrose_hiive\n", @@ -44,14 +44,92 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:05:07.485286Z", "start_time": "2020-11-28T22:05:07.454379Z" } }, - "outputs": [], + "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", + "
Countrycapitallatloncodecontinent
0SomalilandHargeisa9.55000044.050000NaNAfrica
1South Georgia and South Sandwich IslandsKing Edward Point-54.283333-36.500000GSAntarctica
2French Southern and Antarctic LandsPort-aux-Français-49.35000070.216667TFAntarctica
\n", + "
" + ], + "text/plain": [ + " Country capital lat \\\n", + "0 Somaliland Hargeisa 9.550000 \n", + "1 South Georgia and South Sandwich Islands King Edward Point -54.283333 \n", + "2 French Southern and Antarctic Lands Port-aux-Français -49.350000 \n", + "\n", + " lon code continent \n", + "0 44.050000 NaN Africa \n", + "1 -36.500000 GS Antarctica \n", + "2 70.216667 TF Antarctica " + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "# load the dataframe with capitals\n", "df = pd.read_csv(\"concap.csv\")\n", @@ -77,14 +155,80 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:05:07.501279Z", "start_time": "2020-11-28T22:05:07.488341Z" } }, - "outputs": [], + "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", + "
indexCountrycapitallatloncodecontinent
081FranceParis48.8666672.333333FREurope
1110ItalyRome41.90000012.483333ITEurope
\n", + "
" + ], + "text/plain": [ + " index Country capital lat lon code continent\n", + "0 81 France Paris 48.866667 2.333333 FR Europe\n", + "1 110 Italy Rome 41.900000 12.483333 IT Europe" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "# to start with let's filter only 2 capitals. Rome and Paris.\n", "ropa = df[df[\"capital\"].isin([\"Rome\",\"Paris\"])].reset_index()\n", @@ -118,14 +262,25 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:05:07.516777Z", "start_time": "2020-11-28T22:05:07.503271Z" } }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "(Distance(1107.8818760940028), 1107.8818760940028, 688.4058822066647)" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "d = distance.distance((cities.loc[0, \"lat\"], cities.loc[0, \"lon\"]), (cities.loc[1, \"lat\"], cities.loc[1, \"lon\"]))\n", "d, d.km, d.miles" @@ -133,28 +288,125 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:05:07.532846Z", "start_time": "2020-11-28T22:05:07.517777Z" } }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "1107.8818760940028" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "getattr(d, \"km\")" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:05:07.612199Z", "start_time": "2020-11-28T22:05:07.534842Z" } }, - "outputs": [], + "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", + "
measurementfeetftkilometerskmmimilesnauticalnm
method
geodesic3.634783e+063.634783e+061107.8818761107.881876688.405882688.405882598.208356598.208356
great_circle3.630457e+063.630457e+061106.5632051106.563205687.586498687.586498597.496331597.496331
\n", + "
" + ], + "text/plain": [ + "measurement feet ft kilometers km \\\n", + "method \n", + "geodesic 3.634783e+06 3.634783e+06 1107.881876 1107.881876 \n", + "great_circle 3.630457e+06 3.630457e+06 1106.563205 1106.563205 \n", + "\n", + "measurement mi miles nautical nm \n", + "method \n", + "geodesic 688.405882 688.405882 598.208356 598.208356 \n", + "great_circle 687.586498 687.586498 597.496331 597.496331 " + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "results = []\n", "for f in [distance.distance, distance.great_circle, distance.geodesic]:\n", @@ -181,14 +433,178 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:05:07.689528Z", "start_time": "2020-11-28T22:05:07.615166Z" } }, - "outputs": [], + "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", + "
measurementfeetftkilometerskmmimilesnauticalnm
method
geodesic3.634783e+063.634783e+061107.8818761107.881876688.405882688.405882598.208356598.208356
geodesic: Airy (1830)3.634455e+063.634455e+061107.7819641107.781964688.343800688.343800598.154408598.154408
geodesic: Clarke (1880)3.634851e+063.634851e+061107.9026241107.902624688.418774688.418774598.219559598.219559
geodesic: GRS-673.634796e+063.634796e+061107.8858731107.885873688.408366688.408366598.210515598.210515
geodesic: GRS-803.634783e+063.634783e+061107.8818761107.881876688.405882688.405882598.208356598.208356
geodesic: Intl 19243.634927e+063.634927e+061107.9258041107.925804688.433178688.433178598.232075598.232075
geodesic: WGS-843.634783e+063.634783e+061107.8818761107.881876688.405882688.405882598.208356598.208356
great_circle3.630457e+063.630457e+061106.5632051106.563205687.586498687.586498597.496331597.496331
\n", + "
" + ], + "text/plain": [ + "measurement feet ft kilometers km \\\n", + "method \n", + "geodesic 3.634783e+06 3.634783e+06 1107.881876 1107.881876 \n", + "geodesic: Airy (1830) 3.634455e+06 3.634455e+06 1107.781964 1107.781964 \n", + "geodesic: Clarke (1880) 3.634851e+06 3.634851e+06 1107.902624 1107.902624 \n", + "geodesic: GRS-67 3.634796e+06 3.634796e+06 1107.885873 1107.885873 \n", + "geodesic: GRS-80 3.634783e+06 3.634783e+06 1107.881876 1107.881876 \n", + "geodesic: Intl 1924 3.634927e+06 3.634927e+06 1107.925804 1107.925804 \n", + "geodesic: WGS-84 3.634783e+06 3.634783e+06 1107.881876 1107.881876 \n", + "great_circle 3.630457e+06 3.630457e+06 1106.563205 1106.563205 \n", + "\n", + "measurement mi miles nautical nm \n", + "method \n", + "geodesic 688.405882 688.405882 598.208356 598.208356 \n", + "geodesic: Airy (1830) 688.343800 688.343800 598.154408 598.154408 \n", + "geodesic: Clarke (1880) 688.418774 688.418774 598.219559 598.219559 \n", + "geodesic: GRS-67 688.408366 688.408366 598.210515 598.210515 \n", + "geodesic: GRS-80 688.405882 688.405882 598.208356 598.208356 \n", + "geodesic: Intl 1924 688.433178 688.433178 598.232075 598.232075 \n", + "geodesic: WGS-84 688.405882 688.405882 598.208356 598.208356 \n", + "great_circle 687.586498 687.586498 597.496331 597.496331 " + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "# the distnace for various ellipsiods\n", "for ellipsoid in distance.ELLIPSOIDS:\n", @@ -211,14 +627,25 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:05:07.705353Z", "start_time": "2020-11-28T22:05:07.691360Z" } }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "397.76330968599365" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "hest = df[df[\"capital\"].isin([\"Helsinki\",\"Stockholm\"])].reset_index()\n", "cities = hest.copy()\n", @@ -246,7 +673,7 @@ "* `steps` - whether to return route steps - e.g. at the crossroad turn left\n", "* `geometries` - how is the route returned, either `polyline` (def`ault), `polyline6` , `geojson`\n", "* `overview` - how to return the route - `simplified` (default), `full`, `false`\n", - "* `annotations` - if aditional metadata are provided for each point on the route\n", + "* `annotations` - if additional metadata are provided for each point on the route\n", "\n", "For our purpose, we can run the simplest request, having everything set to false or default. We will simply call: `http://router.project-osrm.org/route/v1/driving/cities.loc[0, \"lon\"],cities.loc[0, \"lat\"];cities.loc[1, \"lon\"],cities.loc[1, \"lat\"]?overview=false`\n", "\n", @@ -255,7 +682,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 9, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:05:07.938822Z", @@ -277,14 +704,25 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:05:07.954778Z", "start_time": "2020-11-28T22:05:07.940816Z" } }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "b'{\"code\":\"Ok\",\"waypoints\":[{\"hint\":\"SJu0lP___39RAAAAYQAAAAkAAAAAAAAAUTdZQvgsIUGPZrZAAAAAAFEAAABhAAAACQAAAAAAAADcFwEA45kjAJ6l6QKVmiMAa6XpAgEAvwwTttuE\",\"distance\":14.236102,\"location\":[2.333155,48.866718],\"name\":\"Rue Saint-Roch\"},{\"hint\":\"F1L0jv___38VAAAAZgAAAAAAAAAAAAAA3AxzQf1MYEIAAAAAAAAAABUAAABmAAAAAAAAAAAAAADcFwEAbXu-AFBXfwIFe74A4Fd_AgAAHw8TttuE\",\"distance\":18.175415,\"location\":[12.483437,41.899856],\"name\":\"Via dell\\'Umilt\\xc3\\xa0\"}],\"routes\":[{\"legs\":[{\"steps\":[],\"weight\":54305.7,\"distance\":1432281.4,\"summary\":\"\",\"duration\":54279.6}],\"weight_name\":\"routability\",\"weight\":54305.7,\"distance\":1432281.4,\"duration\":54279.6}]}'" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "r.content" ] @@ -298,14 +736,42 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 11, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:05:07.969741Z", "start_time": "2020-11-28T22:05:07.958770Z" } }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "{'code': 'Ok',\n", + " 'waypoints': [{'hint': 'SJu0lP___39RAAAAYQAAAAkAAAAAAAAAUTdZQvgsIUGPZrZAAAAAAFEAAABhAAAACQAAAAAAAADcFwEA45kjAJ6l6QKVmiMAa6XpAgEAvwwTttuE',\n", + " 'distance': 14.236102,\n", + " 'location': [2.333155, 48.866718],\n", + " 'name': 'Rue Saint-Roch'},\n", + " {'hint': 'F1L0jv___38VAAAAZgAAAAAAAAAAAAAA3AxzQf1MYEIAAAAAAAAAABUAAABmAAAAAAAAAAAAAADcFwEAbXu-AFBXfwIFe74A4Fd_AgAAHw8TttuE',\n", + " 'distance': 18.175415,\n", + " 'location': [12.483437, 41.899856],\n", + " 'name': \"Via dell'Umiltà\"}],\n", + " 'routes': [{'legs': [{'steps': [],\n", + " 'weight': 54305.7,\n", + " 'distance': 1432281.4,\n", + " 'summary': '',\n", + " 'duration': 54279.6}],\n", + " 'weight_name': 'routability',\n", + " 'weight': 54305.7,\n", + " 'distance': 1432281.4,\n", + " 'duration': 54279.6}]}" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "json.loads(r.content)" ] @@ -319,14 +785,25 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:05:07.984709Z", "start_time": "2020-11-28T22:05:07.974726Z" } }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "(1432281.4, 54279.6)" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "route_1 = json.loads(r.content)[\"routes\"][0]\n", "route_1[\"distance\"], route_1[\"duration\"]" @@ -348,7 +825,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 13, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:05:08.000656Z", @@ -357,19 +834,30 @@ }, "outputs": [], "source": [ - "x = datetime.timedelta(seconds=route_1[\"duration\"]+100000)" + "x = datetime.timedelta(seconds=route_1[\"duration\"])" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 14, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:05:08.031575Z", "start_time": "2020-11-28T22:05:08.008635Z" } }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "'15:04:39.600000'" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "str(x)" ] @@ -388,14 +876,57 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 15, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:05:08.063487Z", "start_time": "2020-11-28T22:05:08.037559Z" } }, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
duration
01 days 18:51:19
\n", + "
" + ], + "text/plain": [ + " duration\n", + "0 1 days 18:51:19" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "dftime = pd.DataFrame({\"duration\":route_1[\"duration\"]+100000}, index=[0])\n", "dftime[\"duration\"] = dftime[\"duration\"].astype(\"timedelta64[s]\")\n", @@ -420,18 +951,26 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 16, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:05:08.079445Z", "start_time": "2020-11-28T22:05:08.069473Z" } }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "https://maps.googleapis.com/maps/api/directions/json?origin=48.86666666666667,2.333333&destination=41.9,12.483333&mode=driving&key=...your_google_api_key" + ] + } + ], "source": [ "origin_coor = \",\".join([str(cities.loc[0,\"lat\"]), str(cities.loc[0,\"lon\"])])\n", "destination_coor = \",\".join([str(cities.loc[1,\"lat\"]), str(cities.loc[1,\"lon\"])])\n", - "API_KEY = \"api_key\"\n", + "API_KEY = \"...your_google_api_key...\"\n", "url = f\"https://maps.googleapis.com/maps/api/directions/json?origin={origin_coor}&destination={destination_coor}&mode=driving&key={API_KEY}\"\n", "\n", "# alternatively you can specify the start point (origin) and the destination using the places' names\n", @@ -441,7 +980,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 17, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:05:08.607266Z", @@ -462,18 +1001,50 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 18, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:05:08.622179Z", "start_time": "2020-11-28T22:05:08.609244Z" } }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "({'text': '13 hours 44 mins', 'value': 49460},\n", + " {'text': '1,420 km', 'value': 1420429})" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "results = json.loads(r.content)\n", - "legs = results[\"routes\"][0][\"legs\"]\n", - "legs[0][\"duration\"], legs[0][\"distance\"]" + "legs = results.get(\"routes\").pop(0).get(\"legs\")\n", + "legs[0].get(\"duration\"), legs[0].get(\"distance\")" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'text': '13 hours 44 mins', 'value': 49460}" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "legs.pop(0).get(\"duration\")" ] }, { @@ -488,7 +1059,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 20, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:05:08.638137Z", @@ -502,14 +1073,147 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 21, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:05:08.654093Z", "start_time": "2020-11-28T22:05:08.640131Z" } }, - "outputs": [], + "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", + "
Countrycapitallatloncodecontinent
0AustriaVienna48.20000016.366667ATEurope
1Czech RepublicPrague50.08333314.466667CZEurope
2GermanyBerlin52.51666713.400000DEEurope
3HungaryBudapest47.50000019.083333HUEurope
4LiechtensteinVaduz47.1333339.516667LIEurope
5PolandWarsaw52.25000021.000000PLEurope
6SlovakiaBratislava48.15000017.116667SKEurope
7SloveniaLjubljana46.05000014.516667SIEurope
8SwitzerlandBern46.9166677.466667CHEurope
\n", + "
" + ], + "text/plain": [ + " Country capital lat lon code continent\n", + "0 Austria Vienna 48.200000 16.366667 AT Europe\n", + "1 Czech Republic Prague 50.083333 14.466667 CZ Europe\n", + "2 Germany Berlin 52.516667 13.400000 DE Europe\n", + "3 Hungary Budapest 47.500000 19.083333 HU Europe\n", + "4 Liechtenstein Vaduz 47.133333 9.516667 LI Europe\n", + "5 Poland Warsaw 52.250000 21.000000 PL Europe\n", + "6 Slovakia Bratislava 48.150000 17.116667 SK Europe\n", + "7 Slovenia Ljubljana 46.050000 14.516667 SI Europe\n", + "8 Switzerland Bern 46.916667 7.466667 CH Europe" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "ce_cities = df[df[\"code\"].isin(ce_countries)].reset_index(drop=True)\n", "ce_cities" @@ -524,7 +1228,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 22, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:05:08.670052Z", @@ -546,14 +1250,25 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 23, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:05:08.749878Z", "start_time": "2020-11-28T22:05:08.673043Z" } }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "(347770, 13949.1)" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "# let's try on the first two cities\n", "# confirm that it's correct on https://www.openstreetmap.org/directions?engine=fossgis_osrm_car&route=48.208%2C16.372%3B50.087%2C14.421\n", @@ -578,33 +1293,84 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 24, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:05:08.764805Z", "start_time": "2020-11-28T22:05:08.755822Z" } }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "36" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "# https://stackoverflow.com/questions/464864/how-to-get-all-possible-combinations-of-a-list-s-elements\n", "# https://stackoverflow.com/questions/3025162/statistics-combinations-in-python\n", - "len([c for c in itertools.combinations(list(cities[\"capital\"]),2)])" + "combination = itertools.combinations(list(ce_cities[\"capital\"]),2)\n", + "len([c for c in itertools.combinations(list(ce_cities[\"capital\"]),2)])" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['Vienna',\n", + " 'Prague',\n", + " 'Berlin',\n", + " 'Budapest',\n", + " 'Vaduz',\n", + " 'Warsaw',\n", + " 'Bratislava',\n", + " 'Ljubljana',\n", + " 'Bern']" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "list(ce_cities[\"capital\"])" + ] + }, + { + "cell_type": "code", + "execution_count": 26, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:05:08.779756Z", "start_time": "2020-11-28T22:05:08.768787Z" } }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "36" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "# from python 3.8 you can use math.comb to get just the number. \n", - "# math.comb(9,2)" + "math.comb(9,2)" ] }, { @@ -621,7 +1387,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 27, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:05:35.576147Z", @@ -642,14 +1408,146 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 28, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:05:35.607036Z", "start_time": "2020-11-28T22:05:35.583100Z" } }, - "outputs": [], + "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", + "
origindestinationduration(s)distnace(m)
00113949.1347770.0
10227424.4695795.8
2039661.4246594.9
30424166.6647192.9
40529367.0689921.3
...............
678341862.11102405.4
68849856.0235662.0
698552573.81503176.5
708635718.7936757.6
718732803.4804505.5
\n", + "

72 rows × 4 columns

\n", + "
" + ], + "text/plain": [ + " origin destination duration(s) distnace(m)\n", + "0 0 1 13949.1 347770.0\n", + "1 0 2 27424.4 695795.8\n", + "2 0 3 9661.4 246594.9\n", + "3 0 4 24166.6 647192.9\n", + "4 0 5 29367.0 689921.3\n", + ".. ... ... ... ...\n", + "67 8 3 41862.1 1102405.4\n", + "68 8 4 9856.0 235662.0\n", + "69 8 5 52573.8 1503176.5\n", + "70 8 6 35718.7 936757.6\n", + "71 8 7 32803.4 804505.5\n", + "\n", + "[72 rows x 4 columns]" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "distances_df = pd.DataFrame(dist_array,columns=[\"origin\",\"destination\",\"duration(s)\",\"distnace(m)\"])\n", "distances_df" @@ -657,14 +1555,170 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 29, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:05:35.652943Z", "start_time": "2020-11-28T22:05:35.613036Z" } }, - "outputs": [], + "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", + "
origindestinationduration(s)distnace(m)origin_namedestination_name
00113949.1347770.0ViennaPrague
172113651.1347924.9BerlinPrague
253119597.1527313.6BudapestPrague
334122708.2619664.1VaduzPrague
415126667.0673676.6WarsawPrague
.....................
324024148.1646604.5VaduzVienna
405029492.4682624.3WarsawVienna
48603533.180739.1BratislavaVienna
567014274.3374135.9LjubljanaVienna
648032685.3848610.7BernVienna
\n", + "

72 rows × 6 columns

\n", + "
" + ], + "text/plain": [ + " origin destination duration(s) distnace(m) origin_name destination_name\n", + "0 0 1 13949.1 347770.0 Vienna Prague\n", + "17 2 1 13651.1 347924.9 Berlin Prague\n", + "25 3 1 19597.1 527313.6 Budapest Prague\n", + "33 4 1 22708.2 619664.1 Vaduz Prague\n", + "41 5 1 26667.0 673676.6 Warsaw Prague\n", + ".. ... ... ... ... ... ...\n", + "32 4 0 24148.1 646604.5 Vaduz Vienna\n", + "40 5 0 29492.4 682624.3 Warsaw Vienna\n", + "48 6 0 3533.1 80739.1 Bratislava Vienna\n", + "56 7 0 14274.3 374135.9 Ljubljana Vienna\n", + "64 8 0 32685.3 848610.7 Bern Vienna\n", + "\n", + "[72 rows x 6 columns]" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "distances_df = distances_df.merge(ce_cities[[\"capital\"]], left_on = \"origin\", right_index=True).rename(columns={\"capital\":\"origin_name\"})\n", "distances_df = distances_df.merge(ce_cities[[\"capital\"]], left_on = \"destination\", right_index=True).rename(columns={\"capital\":\"destination_name\"})\n", @@ -688,7 +1742,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 30, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:05:35.667872Z", @@ -710,23 +1764,44 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 65, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:05:35.699788Z", "start_time": "2020-11-28T22:05:35.669868Z" } }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "[(0, 1, 13949.1),\n", + " (0, 2, 27424.4),\n", + " (0, 3, 9661.4),\n", + " (0, 4, 24166.6),\n", + " (0, 5, 29367.),\n", + " '...',\n", + " (8, 3, 41862.1),\n", + " (8, 4, 9856.),\n", + " (8, 5, 52573.8),\n", + " (8, 6, 35718.7),\n", + " (8, 7, 32803.4)]" + ] + }, + "execution_count": 65, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "# turn the first three columns of the dataframe into the list of tuples\n", "dist_list = list(distances_df[[\"origin\",\"destination\",\"duration(s)\"]].sort_values(by=[\"origin\",\"destination\"]).to_records(index=False))\n", - "dist_list" + "dist_list[:5] + [\"...\"] + dist_list[-5:]" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 32, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:05:35.715744Z", @@ -741,7 +1816,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 33, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:05:35.731702Z", @@ -756,21 +1831,32 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 34, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:05:36.287216Z", "start_time": "2020-11-28T22:05:35.733696Z" } }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "(array([5, 2, 1, 6, 3, 7, 4, 8, 0]), 168798.30000000002)" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "mlrose.genetic_alg(problem_fit, random_state = 2)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 35, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:05:36.795536Z", @@ -785,21 +1871,29 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 36, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:05:36.810757Z", "start_time": "2020-11-28T22:05:36.797331Z" } }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The best state found is: [5 2 1 6 3 7 4 8 0], taking 168798.30000000002 (1 day, 22:53:18.300000)\n" + ] + } + ], "source": [ "print(f\"The best state found is: {best_state}, taking {best_fitness} ({str(datetime.timedelta(seconds=best_fitness))})\")" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 37, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:06:29.554931Z", @@ -814,14 +1908,22 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 38, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:06:29.570917Z", "start_time": "2020-11-28T22:06:29.557969Z" } }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The best state found is: [1 8 4 7 3 6 0 5 2], taking 157397.0 (1 day, 19:43:17)\n" + ] + } + ], "source": [ "print(f\"The best state found is: {best_state}, taking {best_fitness} ({str(datetime.timedelta(seconds=best_fitness))})\")" ] @@ -835,14 +1937,25 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 39, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:06:29.602881Z", "start_time": "2020-11-28T22:06:29.576884Z" } }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "{1: 0, 8: 1, 4: 2, 7: 3, 3: 4, 6: 5, 0: 6, 5: 7, 2: 8}" + ] + }, + "execution_count": 39, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "orders = {city: order for order, city in enumerate(best_state)}\n", "orders" @@ -850,14 +1963,157 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 40, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:06:29.649739Z", "start_time": "2020-11-28T22:06:29.612784Z" } }, - "outputs": [], + "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", + "
Countrycapitallatloncodecontinentorder
1Czech RepublicPrague50.08333314.466667CZEurope0
8SwitzerlandBern46.9166677.466667CHEurope1
4LiechtensteinVaduz47.1333339.516667LIEurope2
7SloveniaLjubljana46.05000014.516667SIEurope3
3HungaryBudapest47.50000019.083333HUEurope4
6SlovakiaBratislava48.15000017.116667SKEurope5
0AustriaVienna48.20000016.366667ATEurope6
5PolandWarsaw52.25000021.000000PLEurope7
2GermanyBerlin52.51666713.400000DEEurope8
\n", + "
" + ], + "text/plain": [ + " Country capital lat lon code continent order\n", + "1 Czech Republic Prague 50.083333 14.466667 CZ Europe 0\n", + "8 Switzerland Bern 46.916667 7.466667 CH Europe 1\n", + "4 Liechtenstein Vaduz 47.133333 9.516667 LI Europe 2\n", + "7 Slovenia Ljubljana 46.050000 14.516667 SI Europe 3\n", + "3 Hungary Budapest 47.500000 19.083333 HU Europe 4\n", + "6 Slovakia Bratislava 48.150000 17.116667 SK Europe 5\n", + "0 Austria Vienna 48.200000 16.366667 AT Europe 6\n", + "5 Poland Warsaw 52.250000 21.000000 PL Europe 7\n", + "2 Germany Berlin 52.516667 13.400000 DE Europe 8" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "ce_cities[\"order\"] = ce_cities.index.map(orders)\n", "ce_cities = ce_cities.sort_values(by=\"order\")\n", @@ -878,14 +2134,178 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 41, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:06:29.680656Z", "start_time": "2020-11-28T22:06:29.652736Z" } }, - "outputs": [], + "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", + "
Countrycapitallatloncodecontinentordernext_city
1Czech RepublicPrague50.08333314.466667CZEurope0Bern
8SwitzerlandBern46.9166677.466667CHEurope1Vaduz
4LiechtensteinVaduz47.1333339.516667LIEurope2Ljubljana
7SloveniaLjubljana46.05000014.516667SIEurope3Budapest
3HungaryBudapest47.50000019.083333HUEurope4Bratislava
6SlovakiaBratislava48.15000017.116667SKEurope5Vienna
0AustriaVienna48.20000016.366667ATEurope6Warsaw
5PolandWarsaw52.25000021.000000PLEurope7Berlin
2GermanyBerlin52.51666713.400000DEEurope8Prague
\n", + "
" + ], + "text/plain": [ + " Country capital lat lon code continent order \\\n", + "1 Czech Republic Prague 50.083333 14.466667 CZ Europe 0 \n", + "8 Switzerland Bern 46.916667 7.466667 CH Europe 1 \n", + "4 Liechtenstein Vaduz 47.133333 9.516667 LI Europe 2 \n", + "7 Slovenia Ljubljana 46.050000 14.516667 SI Europe 3 \n", + "3 Hungary Budapest 47.500000 19.083333 HU Europe 4 \n", + "6 Slovakia Bratislava 48.150000 17.116667 SK Europe 5 \n", + "0 Austria Vienna 48.200000 16.366667 AT Europe 6 \n", + "5 Poland Warsaw 52.250000 21.000000 PL Europe 7 \n", + "2 Germany Berlin 52.516667 13.400000 DE Europe 8 \n", + "\n", + " next_city \n", + "1 Bern \n", + "8 Vaduz \n", + "4 Ljubljana \n", + "7 Budapest \n", + "3 Bratislava \n", + "6 Vienna \n", + "0 Warsaw \n", + "5 Berlin \n", + "2 Prague " + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "ce_cities[\"next_city\"] = ce_cities[\"capital\"].shift(-1)\n", "\n", @@ -903,7 +2323,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 42, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:06:29.695800Z", @@ -917,14 +2337,208 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 43, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:06:29.710762Z", "start_time": "2020-11-28T22:06:29.696799Z" } }, - "outputs": [], + "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", + "
Countrycapitallatloncodecontinentordernext_cityorigin_namedestination_nameduration(s)
0Czech RepublicPrague50.08333314.466667CZEurope0BernPragueBern30022.3
1SwitzerlandBern46.9166677.466667CHEurope1VaduzBernVaduz9856.0
2LiechtensteinVaduz47.1333339.516667LIEurope2LjubljanaVaduzLjubljana24837.6
3SloveniaLjubljana46.05000014.516667SIEurope3BudapestLjubljanaBudapest17635.7
4HungaryBudapest47.50000019.083333HUEurope4BratislavaBudapestBratislava7881.1
5SlovakiaBratislava48.15000017.116667SKEurope5ViennaBratislavaVienna3533.1
6AustriaVienna48.20000016.366667ATEurope6WarsawViennaWarsaw29367.0
7PolandWarsaw52.25000021.000000PLEurope7BerlinWarsawBerlin20528.8
8GermanyBerlin52.51666713.400000DEEurope8PragueBerlinPrague13651.1
\n", + "
" + ], + "text/plain": [ + " Country capital lat lon code continent order \\\n", + "0 Czech Republic Prague 50.083333 14.466667 CZ Europe 0 \n", + "1 Switzerland Bern 46.916667 7.466667 CH Europe 1 \n", + "2 Liechtenstein Vaduz 47.133333 9.516667 LI Europe 2 \n", + "3 Slovenia Ljubljana 46.050000 14.516667 SI Europe 3 \n", + "4 Hungary Budapest 47.500000 19.083333 HU Europe 4 \n", + "5 Slovakia Bratislava 48.150000 17.116667 SK Europe 5 \n", + "6 Austria Vienna 48.200000 16.366667 AT Europe 6 \n", + "7 Poland Warsaw 52.250000 21.000000 PL Europe 7 \n", + "8 Germany Berlin 52.516667 13.400000 DE Europe 8 \n", + "\n", + " next_city origin_name destination_name duration(s) \n", + "0 Bern Prague Bern 30022.3 \n", + "1 Vaduz Bern Vaduz 9856.0 \n", + "2 Ljubljana Vaduz Ljubljana 24837.6 \n", + "3 Budapest Ljubljana Budapest 17635.7 \n", + "4 Bratislava Budapest Bratislava 7881.1 \n", + "5 Vienna Bratislava Vienna 3533.1 \n", + "6 Warsaw Vienna Warsaw 29367.0 \n", + "7 Berlin Warsaw Berlin 20528.8 \n", + "8 Prague Berlin Prague 13651.1 " + ] + }, + "execution_count": 43, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "ordered_ce_cities" ] @@ -943,14 +2557,25 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 44, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:06:29.726721Z", "start_time": "2020-11-28T22:06:29.712757Z" } }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "157312.7" + ] + }, + "execution_count": 44, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "ordered_ce_cities[\"duration(s)\"].sum()" ] @@ -969,28 +2594,183 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 45, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:06:29.742713Z", "start_time": "2020-11-28T22:06:29.731708Z" } }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "30022.3" + ] + }, + "execution_count": 45, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "ordered_ce_cities[\"duration(s)\"].max()" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 46, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:08:58.531709Z", "start_time": "2020-11-28T22:08:58.513758Z" } }, - "outputs": [], + "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", + "
Country capital lat lon code continent order next_city origin_name destination_name duration(s)
0Czech RepublicPrague50.08333314.466667CZEurope0BernPragueBern30022.300000
1SwitzerlandBern46.9166677.466667CHEurope1VaduzBernVaduz9856.000000
2LiechtensteinVaduz47.1333339.516667LIEurope2LjubljanaVaduzLjubljana24837.600000
3SloveniaLjubljana46.05000014.516667SIEurope3BudapestLjubljanaBudapest17635.700000
4HungaryBudapest47.50000019.083333HUEurope4BratislavaBudapestBratislava7881.100000
5SlovakiaBratislava48.15000017.116667SKEurope5ViennaBratislavaVienna3533.100000
6AustriaVienna48.20000016.366667ATEurope6WarsawViennaWarsaw29367.000000
7PolandWarsaw52.25000021.000000PLEurope7BerlinWarsawBerlin20528.800000
8GermanyBerlin52.51666713.400000DEEurope8PragueBerlinPrague13651.100000
" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 46, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "ordered_ce_cities.style.highlight_max(color = 'lightgreen', axis = 0, subset=\"duration(s)\")" ] @@ -1004,14 +2784,25 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 47, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:08:30.868770Z", "start_time": "2020-11-28T22:08:30.858830Z" } }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "(127290.40000000001, '1 day, 11:21:30.400000')" + ] + }, + "execution_count": 47, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "duration_s = ordered_ce_cities[\"duration(s)\"].sum() - ordered_ce_cities[\"duration(s)\"].max()\n", "duration_s, str(datetime.timedelta(seconds=duration_s))" @@ -1031,7 +2822,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 48, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:06:29.993967Z", @@ -1045,17 +2836,28 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 49, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:10:26.426261Z", "start_time": "2020-11-28T22:10:26.410302Z" } }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "19958400.0" + ] + }, + "execution_count": 49, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "# There's possible (n-1)!/2 combinations; 1/2 because path 1-2-3 is the same as 3-2-1\n", - "math.factorial(length)/2" + "# There's possible (n)!/2 combinations; 1/2 because path 1-2-3 is the same as 3-2-1\n", + "math.factorial(length+2)/2" ] }, { @@ -1072,43 +2874,80 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 50, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:06:30.071939Z", "start_time": "2020-11-28T22:06:30.010174Z" } }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "362880" + ] + }, + "execution_count": 50, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "perm = [l for l in itertools.permutations(l, 9)]\n", + "perm = [l for l in itertools.permutations(range(9), 9)]\n", "len(perm)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 62, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:06:30.087911Z", "start_time": "2020-11-28T22:06:30.073062Z" } }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "[(0, 1, 2, 3, 4, 5, 6, 7, 8),\n", + " (0, 1, 2, 3, 4, 5, 6, 8, 7),\n", + " (0, 1, 2, 3, 4, 5, 7, 6, 8),\n", + " (0, 1, 2, 3, 4, 5, 7, 8, 6),\n", + " (0, 1, 2, 3, 4, 5, 8, 6, 7)]" + ] + }, + "execution_count": 62, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "perm[:5]" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 52, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:06:30.103120Z", "start_time": "2020-11-28T22:06:30.088682Z" } }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "13949.1" + ] + }, + "execution_count": 52, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "distances = {(int(d[0]), int(d[1])):d[2] for d in distances_df[[\"origin\",\"destination\",\"duration(s)\"]].values.tolist()}\n", "distances[(0,1)]" @@ -1116,14 +2955,41 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 53, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:06:30.117938Z", "start_time": "2020-11-28T22:06:30.103969Z" } }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(0, 1) 13949.1\n", + "(1, 2) 13629.7\n", + "(2, 3) 33078.6\n", + "(3, 4) 33392.4\n", + "(4, 5) 45307.4\n", + "(5, 6) 27916.9\n", + "(6, 7) 16742.8\n", + "(7, 8) 32762.8\n", + "(8, 0) 32685.3\n", + "249464.99999999997\n" + ] + }, + { + "data": { + "text/plain": [ + "249464.99999999997" + ] + }, + "execution_count": 53, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "# pick the first path\n", "path = perm[0]\n", @@ -1131,7 +2997,7 @@ "# add th first element to conclude the circular path\n", "path = path + (path[0],)\n", "\n", - "# iterate through the path and sum all the distnaces\n", + "# iterate through the path and sum all the distances\n", "total_path_distance = 0\n", "for i in range(len(path)-1):\n", " edge = (path[i], path[i+1])\n", @@ -1145,14 +3011,22 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 54, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:06:31.064417Z", "start_time": "2020-11-28T22:06:30.127909Z" } }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "157312.7 9 [(0, 5, 2, 1, 8, 4, 7, 3, 6, 0), (1, 8, 4, 7, 3, 6, 0, 5, 2, 1), (2, 1, 8, 4, 7, 3, 6, 0, 5, 2), (3, 6, 0, 5, 2, 1, 8, 4, 7, 3), (4, 7, 3, 6, 0, 5, 2, 1, 8, 4), (5, 2, 1, 8, 4, 7, 3, 6, 0, 5), (6, 0, 5, 2, 1, 8, 4, 7, 3, 6), (7, 3, 6, 0, 5, 2, 1, 8, 4, 7), (8, 4, 7, 3, 6, 0, 5, 2, 1, 8)]\n" + ] + } + ], "source": [ "mn = np.inf\n", "min_paths = []\n", @@ -1172,12 +3046,12 @@ " else:\n", " pass\n", " \n", - "print(mn, min_paths)" + "print(mn, len(min_paths), min_paths)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 55, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:06:31.080062Z", @@ -1193,9 +3067,11 @@ " cities = cities.sort_values(by=\"order\")\n", " \n", " cities[\"next_city\"] = cities[\"capital\"].shift(-1)\n", + " cities[\"prev_city\"] = cities[\"capital\"].shift(1)\n", "\n", " # the last connection is between the last city and the first one\n", " cities.loc[cities[\"order\"] == max(cities[\"order\"]), \"next_city\"] = cities.loc[cities[\"order\"] == min(cities[\"order\"]), \"capital\"].values[0]\n", + " cities.loc[cities[\"order\"] == min(cities[\"order\"]), \"prev_city\"] = cities.loc[cities[\"order\"] == max(cities[\"order\"]), \"capital\"].values[0]\n", " \n", " ordered_ce_cities = cities.merge(distances_df[[\"origin_name\",\"destination_name\",\"duration(s)\"]], left_on=[\"capital\",\"next_city\"], right_on=[\"origin_name\",\"destination_name\"], how=\"left\")\n", " \n", @@ -1204,14 +3080,167 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 56, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:12:47.699374Z", "start_time": "2020-11-28T22:12:47.664468Z" } }, - "outputs": [], + "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", + "
Country capital lat lon code continent order next_city prev_city origin_name destination_name duration(s)
0PolandWarsaw52.25000021.000000PLEurope1BerlinViennaWarsawBerlin20528.800000
1GermanyBerlin52.51666713.400000DEEurope2PragueWarsawBerlinPrague13651.100000
2Czech RepublicPrague50.08333314.466667CZEurope3BernBerlinPragueBern30022.300000
3SwitzerlandBern46.9166677.466667CHEurope4VaduzPragueBernVaduz9856.000000
4LiechtensteinVaduz47.1333339.516667LIEurope5LjubljanaBernVaduzLjubljana24837.600000
5SloveniaLjubljana46.05000014.516667SIEurope6BudapestVaduzLjubljanaBudapest17635.700000
6HungaryBudapest47.50000019.083333HUEurope7BratislavaLjubljanaBudapestBratislava7881.100000
7SlovakiaBratislava48.15000017.116667SKEurope8ViennaBudapestBratislavaVienna3533.100000
8AustriaVienna48.20000016.366667ATEurope9WarsawBratislavaViennaWarsaw29367.000000
" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 56, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "total_duration, path_df = path_to_df(min_paths, ce_cities, distances_df)\n", "path_df.style.highlight_max(color = 'lightgreen', axis = 0, subset=\"duration(s)\")" @@ -1219,14 +3248,25 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 57, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:09:56.692430Z", "start_time": "2020-11-28T22:09:56.682493Z" } }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "157312.7" + ] + }, + "execution_count": 57, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "total_duration" ] @@ -1245,18 +3285,131 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 58, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:21:37.618056Z", "start_time": "2020-11-28T22:21:37.590130Z" } }, - "outputs": [], + "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", + "
orderorigin_namedestination_nameduration(s)
56LjubljanaBudapest17635.7
67BudapestBratislava7881.1
78BratislavaVienna3533.1
89ViennaWarsaw29367.0
010WarsawBerlin20528.8
111BerlinPrague13651.1
212PragueBern30022.3
313BernVaduz9856.0
414VaduzLjubljana24837.6
\n", + "
" + ], + "text/plain": [ + " order origin_name destination_name duration(s)\n", + "5 6 Ljubljana Budapest 17635.7\n", + "6 7 Budapest Bratislava 7881.1\n", + "7 8 Bratislava Vienna 3533.1\n", + "8 9 Vienna Warsaw 29367.0\n", + "0 10 Warsaw Berlin 20528.8\n", + "1 11 Berlin Prague 13651.1\n", + "2 12 Prague Bern 30022.3\n", + "3 13 Bern Vaduz 9856.0\n", + "4 14 Vaduz Ljubljana 24837.6" + ] + }, + "execution_count": 58, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "filter_cities_before_bern = path_df[\"order\"] < path_df.loc[path_df[\"capital\"]==\"Ljubljana\",\"order\"].values[0]\n", "path_df.loc[filter_cities_before_bern, \"order\"] += path_df[\"order\"].max()\n", - "path_df.sort_values(by=\"order\")" + "path_df.sort_values(by=\"order\")[[\"order\", \"origin_name\", \"destination_name\", \"duration(s)\"]]" ] }, { @@ -1273,18 +3426,132 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 59, "metadata": { "ExecuteTime": { "end_time": "2020-11-28T22:22:03.312805Z", "start_time": "2020-11-28T22:22:03.280892Z" } }, - "outputs": [], + "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", + "
orderorigin_namedestination_nameduration(s)
814LjubljanaVaduz24837.6
713VaduzBern9856.0
612BernPrague30022.3
511PragueBerlin13651.1
410BerlinWarsaw20528.8
39WarsawVienna29367.0
28ViennaBratislava3533.1
17BratislavaBudapest7881.1
06BudapestLjubljana17635.7
\n", + "
" + ], + "text/plain": [ + " order origin_name destination_name duration(s)\n", + "8 14 Ljubljana Vaduz 24837.6\n", + "7 13 Vaduz Bern 9856.0\n", + "6 12 Bern Prague 30022.3\n", + "5 11 Prague Berlin 13651.1\n", + "4 10 Berlin Warsaw 20528.8\n", + "3 9 Warsaw Vienna 29367.0\n", + "2 8 Vienna Bratislava 3533.1\n", + "1 7 Bratislava Budapest 7881.1\n", + "0 6 Budapest Ljubljana 17635.7" + ] + }, + "execution_count": 59, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "path_df_reversed = path_df.sort_values(by=\"order\").reset_index(drop=True)\n", "path_df_reversed = path_df_reversed.reindex(index=path_df_reversed.index[::-1])\n", - "path_df_reversed" + "path_df_reversed.rename(columns={\"destination_name\":\"origin_name\", \"origin_name\":\"destination_name\"}, inplace=True)\n", + "path_df_reversed[[\"order\", \"origin_name\", \"destination_name\", \"duration(s)\"]]" ] }, { @@ -1296,7 +3563,58 @@ } }, "source": [ - "This path is exactly the same our Travelling Salesman algorithm found. You can see in the `min_paths` variable, that all combinations of these roads are the shortest (considering that we return to the place where we have started)." + "This path is exactly the same our Travelling Salesman algorithm found. You can see in the `min_paths` variable, that all combinations of these roads are the shortest (considering that we return to the place where we have started).\n", + "\n", + "Draw the capitals on the Plotly Geochart. Learn more about plotly - [link](https://towardsdatascience.com/visualization-with-plotly-express-comprehensive-guide-eb5ee4b50b57)" + ] + }, + { + "cell_type": "code", + "execution_count": 60, + "metadata": {}, + "outputs": [], + "source": [ + "import plotly.graph_objects as go" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# draw the capitals\n", + "fig = go.Figure(data=go.Scattergeo(\n", + " locationmode = 'USA-states',\n", + " lon = path_df['lon'],\n", + " lat = path_df['lat'],\n", + " text = df['capital'],\n", + " mode = 'markers',\n", + " name=\"capitals\"\n", + " ))\n", + "\n", + "# draw the paths between the capitals\n", + "for i in range(len(path_df)-1):\n", + " fig.add_trace(go.Scattergeo(\n", + " locationmode = 'USA-states',\n", + " lon=[path_df.loc[i,\"lon\"],path_df.loc[i+1,\"lon\"]], \n", + " lat=[path_df.loc[i,\"lat\"],path_df.loc[i+1,\"lat\"]], \n", + " name=\"-\".join([path_df.loc[i,\"capital\"],path_df.loc[i+1,\"capital\"]]),\n", + " mode=\"lines\"))\n", + " \n", + "# the last path\n", + "fig.add_trace(go.Scattergeo(\n", + " locationmode = 'USA-states',\n", + " lon=[path_df.loc[8,\"lon\"],path_df.loc[0,\"lon\"]], \n", + " lat=[path_df.loc[8,\"lat\"],path_df.loc[0,\"lat\"]], \n", + " name=\"-\".join([path_df.loc[8,\"capital\"],path_df.loc[0,\"capital\"]]),\n", + " mode=\"lines\"))\n", + "\n", + "fig.update_layout(\n", + " title = 'Shortest Route Between Central European Cities',\n", + " geo_scope='europe',\n", + " )\n", + "fig.show()" ] } ],