import numpy as np
# Name, latitude, and longitude of each city
cities = [
("Chicago, IL", 41.8500, -87.6500),
("Indianapolis, IN", 39.7667, -86.1500),
("Marion, OH", 40.5833, -83.1167),
("Erie, PA", 42.1167, -80.0833),
("Carlisle, PA", 40.2000, -77.1833),
("Wana, WV", 39.7000, -80.2833),
("Wilkesboro, NC", 36.1500, -81.1333),
("Chattanooga, TN", 35.0333, -85.3000),
("Barnwell, SC", 33.2333, -81.3500),
("Bainbridge, GA", 30.9000, -84.5667),
("Baton Rouge, LA", 30.4500, -91.1500),
("Little Rock, AR", 34.7333, -92.2833),
("Kansas City, MO", 39.0833, -94.5667),
("La Crosse, WI", 43.8000, -91.2333),
("Blunt, SD", 44.5000, -99.9833),
("Lincoln, NE", 40.8000, -96.6667),
("Wichita, KS", 37.6833, -97.3333),
("Amarillo, TX", 35.2167, -101.8167),
("Truth or Consequences, NM", 33.1167, -107.2500),
("Manuelito, NM", 35.4167, -108.9833),
("Colorado Springs, CO", 38.8333, -104.8167),
("Butte, MT", 46.0000, -112.5333),
("Lewiston, ID", 46.4167, -117.0167),
("Boise, ID", 43.6000, -116.2000),
("Twin Falls, ID", 42.5500, -114.4500),
("Salt Lake City, UT", 40.7500, -111.8833),
("Mexican Hat, UT", 37.1500, -109.8500),
("Marble Canyon, AZ", 36.8000, -111.6333),
("Reno, NV", 39.5167, -119.8000),
("Lone Pine, CA", 36.6000, -118.0500),
("Gustine, CA", 37.2500, -120.9833),
("Redding, CA", 40.5833, -122.3833),
("Portland, OR", 45.5167, -122.6667),
]
# Road distances in miles. Row i lists the distances from city i
# to cities 0, 1, ..., i - 1 (the lower triangle of D).
lower_triangle = [
[184],
[292, 195],
[449, 310, 215],
[670, 540, 380, 288],
[516, 357, 232, 200, 211],
[598, 514, 434, 566, 436, 381],
[618, 434, 493, 787, 814, 642, 295],
[881, 697, 719, 790, 632, 697, 224, 320],
[909, 964, 955, 1020, 974, 952, 541, 341, 318],
[978, 892, 1031, 1246, 1352, 1180, 843, 538, 747, 441],
[654, 597, 803, 1018, 1154, 1104, 766, 461, 749, 634, 380],
[504, 503, 722, 937, 1043, 806, 986, 722, 1042, 954, 784, 404],
[276, 460, 568, 725, 946, 817, 874, 894, 1214, 1185, 1218, 660, 452],
[780, 964, 1072, 1229, 1450, 1321, 1378, 1326, 1646, 1672, 1410, 1030, 626, 476],
[529, 644, 789, 1004, 1184, 1001, 1214, 950, 1270, 1213, 1043, 632, 219, 436, 419],
[805, 698, 917, 1132, 1238, 1055, 1113, 842, 1162, 1027, 779, 473, 195, 637, 634,
256],
[1181, 1007, 1226, 1441, 1547, 1364, 1375, 1080, 1134, 1138, 783, 611, 563, 1046,
759, 624, 368],
[1548, 1444, 1630, 1845, 1984, 1801, 1726, 1431, 1685, 1477, 1134, 1033, 906, 1389,
1094, 967, 711, 404],
[1547, 1454, 1668, 1883, 1994, 1811, 1879, 1584, 1776, 1632, 1267, 1053, 944, 1427,
1196, 1005, 749, 442, 251],
[1239, 1167, 1353, 1568, 1707, 1524, 1584, 1313, 1633, 1498, 1151, 979, 614, 988,
600, 525, 471, 368, 512, 507],
[1538, 1733, 1830, 2045, 2208, 2090, 2136, 2078, 2398, 2332, 2110, 1782, 1378, 1300,
760, 1229, 1382, 1319, 1163, 930, 910],
[1999, 2158, 2291, 2448, 2669, 2515, 2597, 2500, 2820, 2675, 2336, 2164, 1707, 1860,
1375, 1582, 1658, 1545, 1389, 1156, 1237, 436],
[1716, 1875, 2008, 2165, 2386, 2232, 2488, 2217, 2537, 2392, 2053, 1881, 1422, 1577,
1106, 1244, 1375, 1262, 1106, 873, 954, 483, 283],
[1580, 1738, 1872, 2029, 2250, 2095, 2352, 2081, 2401, 2256, 1917, 1745, 1286, 1473,
988, 1147, 1239, 1126, 970, 737, 818, 379, 419, 136],
[1425, 1569, 1717, 1874, 2109, 1926, 2115, 1844, 2164, 2019, 1680, 1508, 1118, 1335,
862, 913, 1002, 889, 733, 500, 581, 430, 656, 373, 237],
[1560, 1549, 1852, 2009, 2089, 1906, 2063, 1792, 2112, 1967, 1456, 1274, 1032, 1540,
1068, 1007, 944, 665, 521, 282, 491, 768, 994, 711, 575, 358],
[1918, 1744, 1963, 2178, 2284, 2101, 2174, 1879, 2071, 1892, 1562, 1348, 1239, 1722,
1258, 1300, 1044, 737, 526, 295, 802, 816, 1022, 739, 603, 386, 545],
[2065, 2102, 2357, 2514, 2642, 2459, 2626, 2355, 2675, 2530, 2191, 2019, 1673, 1905,
1432, 1570, 1507, 1320, 1109, 878, 1124, 842, 715, 432, 465, 533, 849, 739],
[2284, 2131, 2326, 2441, 2671, 2488, 2418, 2133, 2437, 2259, 1929, 1715, 1606, 1924,
1451, 1589, 1411, 1104, 893, 662, 1143, 1004, 981, 698, 599, 589, 768, 523, 266],
[2340, 2348, 2543, 2658, 2888, 2705, 2869, 2598, 2918, 2773, 2434, 2262, 1916, 2148,
1675, 1813, 1750, 1468, 1102, 871, 1367, 1085, 958, 675, 1033, 778, 1092, 982, 243,
349],
[2247, 2327, 2539, 2696, 2867, 2684, 2851, 2580, 2900, 2755, 2416, 2244, 1898, 2130,
1657, 1795, 1732, 1545, 1334, 1103, 1349, 1014, 814, 531, 1015, 760, 1047, 964,
225, 497, 266],
[2163, 2322, 2455, 2612, 2833, 2679, 2761, 2664, 2984, 2839, 2500, 2328, 1871, 2024,
1539, 1746, 1822, 1709, 1553, 1320, 1391, 693, 346, 447, 583, 820, 1158, 1355, 581,
847, 710, 444],
]
n = len(cities)
D = np.zeros((n, n), dtype=int)
for i, row in enumerate(lower_triangle, start=1):
D[i, :i] = row
D = D + D.T
# The optimal tour reported by Karg and Thompson (1964)
optimal_tour = [0, 1, 2, 3, 5, 4, 6, 8, 7, 9, 10, 11, 12, 15, 16, 17, 18,
19, 27, 29, 28, 30, 31, 32, 22, 23, 24, 21, 25, 26, 20, 14, 13]
optimal_length = tour_length(optimal_tour, D)