pycombinatorial 1.8.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. pycombinatorial-1.8.2/LICENSE +14 -0
  2. pycombinatorial-1.8.2/PKG-INFO +125 -0
  3. pycombinatorial-1.8.2/README.md +114 -0
  4. pycombinatorial-1.8.2/pyCombinatorial/__init__.py +0 -0
  5. pycombinatorial-1.8.2/pyCombinatorial/algorithm/__init__.py +52 -0
  6. pycombinatorial-1.8.2/pyCombinatorial/algorithm/aco.py +117 -0
  7. pycombinatorial-1.8.2/pyCombinatorial/algorithm/alns.py +148 -0
  8. pycombinatorial-1.8.2/pyCombinatorial/algorithm/bb.py +81 -0
  9. pycombinatorial-1.8.2/pyCombinatorial/algorithm/bf.py +41 -0
  10. pycombinatorial-1.8.2/pyCombinatorial/algorithm/bhk.py +54 -0
  11. pycombinatorial-1.8.2/pyCombinatorial/algorithm/brkga.py +156 -0
  12. pycombinatorial-1.8.2/pyCombinatorial/algorithm/christofides.py +128 -0
  13. pycombinatorial-1.8.2/pyCombinatorial/algorithm/conc_hull.py +214 -0
  14. pycombinatorial-1.8.2/pyCombinatorial/algorithm/conv_hull.py +96 -0
  15. pycombinatorial-1.8.2/pyCombinatorial/algorithm/cw.py +136 -0
  16. pycombinatorial-1.8.2/pyCombinatorial/algorithm/eln.py +139 -0
  17. pycombinatorial-1.8.2/pyCombinatorial/algorithm/eo.py +153 -0
  18. pycombinatorial-1.8.2/pyCombinatorial/algorithm/ga.py +257 -0
  19. pycombinatorial-1.8.2/pyCombinatorial/algorithm/gksp.py +213 -0
  20. pycombinatorial-1.8.2/pyCombinatorial/algorithm/grasp.py +115 -0
  21. pycombinatorial-1.8.2/pyCombinatorial/algorithm/hpn.py +245 -0
  22. pycombinatorial-1.8.2/pyCombinatorial/algorithm/ins_c.py +99 -0
  23. pycombinatorial-1.8.2/pyCombinatorial/algorithm/ins_f.py +112 -0
  24. pycombinatorial-1.8.2/pyCombinatorial/algorithm/ins_n.py +112 -0
  25. pycombinatorial-1.8.2/pyCombinatorial/algorithm/ins_r.py +117 -0
  26. pycombinatorial-1.8.2/pyCombinatorial/algorithm/ksp.py +248 -0
  27. pycombinatorial-1.8.2/pyCombinatorial/algorithm/lns.py +120 -0
  28. pycombinatorial-1.8.2/pyCombinatorial/algorithm/mf.py +113 -0
  29. pycombinatorial-1.8.2/pyCombinatorial/algorithm/nn.py +101 -0
  30. pycombinatorial-1.8.2/pyCombinatorial/algorithm/opt_2.py +60 -0
  31. pycombinatorial-1.8.2/pyCombinatorial/algorithm/opt_2_5.py +90 -0
  32. pycombinatorial-1.8.2/pyCombinatorial/algorithm/opt_2_5s.py +94 -0
  33. pycombinatorial-1.8.2/pyCombinatorial/algorithm/opt_2s.py +85 -0
  34. pycombinatorial-1.8.2/pyCombinatorial/algorithm/opt_3.py +108 -0
  35. pycombinatorial-1.8.2/pyCombinatorial/algorithm/opt_3s.py +109 -0
  36. pycombinatorial-1.8.2/pyCombinatorial/algorithm/opt_4.py +170 -0
  37. pycombinatorial-1.8.2/pyCombinatorial/algorithm/opt_4s.py +173 -0
  38. pycombinatorial-1.8.2/pyCombinatorial/algorithm/opt_5.py +519 -0
  39. pycombinatorial-1.8.2/pyCombinatorial/algorithm/opt_5s.py +523 -0
  40. pycombinatorial-1.8.2/pyCombinatorial/algorithm/rl_double_ql.py +126 -0
  41. pycombinatorial-1.8.2/pyCombinatorial/algorithm/rl_ql.py +121 -0
  42. pycombinatorial-1.8.2/pyCombinatorial/algorithm/rl_sarsa.py +132 -0
  43. pycombinatorial-1.8.2/pyCombinatorial/algorithm/rt.py +93 -0
  44. pycombinatorial-1.8.2/pyCombinatorial/algorithm/s_gui.py +110 -0
  45. pycombinatorial-1.8.2/pyCombinatorial/algorithm/s_itr.py +103 -0
  46. pycombinatorial-1.8.2/pyCombinatorial/algorithm/s_sct.py +116 -0
  47. pycombinatorial-1.8.2/pyCombinatorial/algorithm/s_shc.py +87 -0
  48. pycombinatorial-1.8.2/pyCombinatorial/algorithm/s_tabu.py +213 -0
  49. pycombinatorial-1.8.2/pyCombinatorial/algorithm/s_vns.py +74 -0
  50. pycombinatorial-1.8.2/pyCombinatorial/algorithm/sa.py +132 -0
  51. pycombinatorial-1.8.2/pyCombinatorial/algorithm/som.py +122 -0
  52. pycombinatorial-1.8.2/pyCombinatorial/algorithm/spfc_h.py +114 -0
  53. pycombinatorial-1.8.2/pyCombinatorial/algorithm/spfc_m.py +106 -0
  54. pycombinatorial-1.8.2/pyCombinatorial/algorithm/spfc_s.py +116 -0
  55. pycombinatorial-1.8.2/pyCombinatorial/algorithm/swp.py +121 -0
  56. pycombinatorial-1.8.2/pyCombinatorial/algorithm/tat.py +100 -0
  57. pycombinatorial-1.8.2/pyCombinatorial/algorithm/tbb.py +104 -0
  58. pycombinatorial-1.8.2/pyCombinatorial/utils/__init__.py +2 -0
  59. pycombinatorial-1.8.2/pyCombinatorial/utils/graphs.py +164 -0
  60. pycombinatorial-1.8.2/pyCombinatorial/utils/util.py +79 -0
  61. pycombinatorial-1.8.2/pycombinatorial.egg-info/PKG-INFO +125 -0
  62. pycombinatorial-1.8.2/pycombinatorial.egg-info/SOURCES.txt +65 -0
  63. pycombinatorial-1.8.2/pycombinatorial.egg-info/dependency_links.txt +1 -0
  64. pycombinatorial-1.8.2/pycombinatorial.egg-info/requires.txt +5 -0
  65. pycombinatorial-1.8.2/pycombinatorial.egg-info/top_level.txt +1 -0
  66. pycombinatorial-1.8.2/setup.cfg +4 -0
  67. pycombinatorial-1.8.2/setup.py +25 -0
@@ -0,0 +1,14 @@
1
+ Copyright © 2023 by Valdecy Pereira
2
+
3
+ pyCombinatorial is free software: you can redistribute it and/or modify
4
+ it under the terms of the GNU General Public License as published by
5
+ the Free Software Foundation, either version 3 of the License, or
6
+ (at your option) any later version.
7
+
8
+ pyCombinatorial is distributed in the hope that it will be useful,
9
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ GNU General Public License for more details.
12
+
13
+ You should have received a copy of the GNU General Public License
14
+ along with pyCombinatorial. If not, see <http://www.gnu.org/licenses/>.
@@ -0,0 +1,125 @@
1
+ Metadata-Version: 2.1
2
+ Name: pycombinatorial
3
+ Version: 1.8.2
4
+ Summary: A library to solve TSP (Travelling Salesman Problem) using Exact Algorithms, Heuristics and Metaheuristics
5
+ Home-page: https://github.com/Valdecy/pyCombinatorial
6
+ Author: Valdecy Pereira
7
+ Author-email: valdecy.pereira@gmail.com
8
+ License: GNU
9
+ Description-Content-Type: text/markdown
10
+ License-File: LICENSE
11
+
12
+ # pyCombinatorial
13
+
14
+ ## Introduction
15
+
16
+ A library to solve the TSP (Travelling Salesman Problem) using Exact Algorithms, Heuristics and Metaheuristics : **2-opt**; **2.5-opt**; **3-opt**; **4-opt**; **5-opt**; **2-opt Stochastic**; **2.5-opt Stochastic**; **3-opt Stochastic**; **4-opt Stochastic**; **5-opt Stochastic**; **Ant Colony Optimization**; **Adaptive Large Neighborhood Search**; **Bellman-Held-Karp Exact Algorithm**; **Branch & Bound**; **BRKGA** (Biased Random Key Genetic Algorithm); **Brute Force**; **Cheapest Insertion**; **Christofides Algorithm**; **Clarke & Wright** (Savings Heuristic); **Concave Hull Algorithm**; **Convex Hull Algorithm**; **Elastic Net**; **Extremal Optimization**; **Farthest Insertion**; **Genetic Algorithm**; **GRASP** (Greedy Randomized Adaptive Search Procedure); **Greedy Karp-Steele Patching**; **Guided Search**; **Hopfield Network**; **Iterated Search**; **Karp-Steele Patching**; **Large Neighborhood Search**; **Multifragment Heuristic**; **Nearest Insertion**; **Nearest Neighbour**; **Random Insertion**; **Random Tour**; **RL Q-Learning**; **RL Double Q-Learning**; **RL S.A.R.S.A** (State Action Reward State Action); **Scatter Search**; **Simulated Annealing**; **SOM** (Self Organizing Maps); **Space Filling Curve** (Hilbert); **Space Filling Curve** (Morton); **Space Filling Curve** (Sierpinski); **Stochastic Hill Climbing**; **Sweep**; **Tabu Search**; **Truncated Branch & Bound**; **Twice-Around the Tree Algorithm** (Double Tree Algorithm); **Variable Neighborhood Search**.
17
+
18
+ ## Usage
19
+
20
+ 1. Install
21
+
22
+ ```bash
23
+ pip install pyCombinatorial
24
+ ```
25
+
26
+ 2. Import
27
+
28
+ ```py3
29
+
30
+
31
+ # Required Libraries
32
+ import pandas as pd
33
+
34
+ # GA
35
+ from pyCombinatorial.algorithm import genetic_algorithm
36
+ from pyCombinatorial.utils import graphs, util
37
+
38
+ # Loading Coordinates # Berlin 52 (Minimum Distance = 7544.3659)
39
+ coordinates = pd.read_csv('https://bit.ly/3Oyn3hN', sep = '\t')
40
+ coordinates = coordinates.values
41
+
42
+ # Obtaining the Distance Matrix
43
+ distance_matrix = util.build_distance_matrix(coordinates)
44
+
45
+ # GA - Parameters
46
+ parameters = {
47
+ 'population_size': 15,
48
+ 'elite': 1,
49
+ 'mutation_rate': 0.1,
50
+ 'mutation_search': 8,
51
+ 'generations': 1000,
52
+ 'verbose': True
53
+ }
54
+
55
+ # GA - Algorithm
56
+ route, distance = genetic_algorithm(distance_matrix, **parameters)
57
+
58
+ # Plot Locations and Tour
59
+ graphs.plot_tour(coordinates, city_tour = route, view = 'browser', size = 10)
60
+ print('Total Distance: ', round(distance, 2))
61
+
62
+ ```
63
+
64
+ 3. Try it in **Colab**
65
+
66
+ - Using Lat Long ([ Colab Demo ](https://colab.research.google.com/drive/17jFw4z1R9gOoAfB-ZCZa6c-PukVKdrt3?usp=sharing))
67
+
68
+ - 2-opt ([ Colab Demo ](https://colab.research.google.com/drive/1SLkM8r_VdlFCpNpm-2yTfr_ynSC5WIX9?usp=sharing)) ( [ Paper ](https://www.jstor.org/stable/167074))
69
+ - 2.5-opt ([ Colab Demo ](https://colab.research.google.com/drive/17bJ-I26prnryAU8p-xf0l7R91cJzb85N?usp=sharing)) ( [ Paper ](https://doi.org/10.1007/s10955-007-9382-1))
70
+ - 3-opt ([ Colab Demo ](https://colab.research.google.com/drive/1iAZLawLBZ-7yaPCyobMtel1SvBamxtjL?usp=sharing)) ( [ Paper ](https://isd.ktu.lt/it2011//material/Proceedings/1_AI_5.pdf))
71
+ - 4-opt ([ Colab Demo ](https://colab.research.google.com/drive/1N8HKhVY4s20sfqo8IWIaCY-NHVk6gARS?usp=sharing)) ( [ Paper ](https://isd.ktu.lt/it2011//material/Proceedings/1_AI_5.pdf))
72
+ - 5-opt ([ Colab Demo ](https://colab.research.google.com/drive/15Qrk-7H4oRaTR77ADvwkiN0sLvycgFDH?usp=sharing)) ( [ Paper ](https://isd.ktu.lt/it2011//material/Proceedings/1_AI_5.pdf))
73
+ - 2-opt Stochastic ([ Colab Demo ](https://colab.research.google.com/drive/1xTm__7OwQVC_KX2b-eExLGgG1DgnJ10a?usp=sharing)) ( [ Paper ](https://doi.org/10.1016/j.trpro.2014.10.001))
74
+ - 2.5-opt Stochastic ([ Colab Demo ](https://colab.research.google.com/drive/16W_QqJ1PebVgqUx8NFOSS5kG3DsJ51UQ?usp=sharing)) ( [ Paper ](https://doi.org/10.1007/s10955-007-9382-1))
75
+ - 3-opt Stochastic ([ Colab Demo ](https://colab.research.google.com/drive/1A5lPW6BSDD2rLNDlnpQo44U8jwKcAGXL?usp=sharing)) ( [ Paper ](https://isd.ktu.lt/it2011//material/Proceedings/1_AI_5.pdf))
76
+ - 4-opt Stochastic ([ Colab Demo ](https://colab.research.google.com/drive/1igWrUMVSInzyeOdhPcGuMjyooZ6elvLY?usp=sharing)) ( [ Paper ](https://isd.ktu.lt/it2011//material/Proceedings/1_AI_5.pdf))
77
+ - 5-opt Stochastic ([ Colab Demo ](https://colab.research.google.com/drive/13vS5MCeFqb3F4ntxrw3iCsMbJTfEVyeo?usp=sharing)) ( [ Paper ](https://isd.ktu.lt/it2011//material/Proceedings/1_AI_5.pdf))
78
+ - Ant Colony Optimization ([ Colab Demo ](https://colab.research.google.com/drive/1O2qogrjE4mZUZX3nsSxw43crumlBnd-D?usp=sharing)) ( [ Paper ](https://doi.org/10.1109/4235.585892))
79
+ - Adaptive Large Neighborhood Search ([ Colab Demo ](https://colab.research.google.com/drive/1vShK5fe2xRCpMkurgd4PzmstGtn6d_LQ?usp=sharing)) ( [ Paper ](https://www.jstor.org/stable/25769321))
80
+ - Bellman-Held-Karp Exact Algorithm ([ Colab Demo ](https://colab.research.google.com/drive/1HSnArk-v8PWY4dlCvT5zcSAnT1FJEDaf?usp=sharing)) ( [ Paper ](https://dl.acm.org/doi/10.1145/321105.321111))
81
+ - Branch & Bound ([ Colab Demo ](https://colab.research.google.com/drive/1oDHrECSW3g4vBEsrO8T7qSHID4fxFiqs?usp=sharing)) ( [ Paper ](https://doi.org/10.1016/j.disopt.2016.01.005))
82
+ - BRKGA (Biased Random Key Genetic Algorithm) ([ Colab Demo ](https://colab.research.google.com/drive/1lwnpUBl1P1LIvzN1saLgEvnaKZRMWLHn?usp=sharing)) ( [ Paper ](https://doi.org/10.1007/s10732-010-9143-1))
83
+ - Brute Force ([ Colab Demo ](https://colab.research.google.com/drive/10vOkBz3Cv9UdHPlcBWkDmJO7EvDg96ar?usp=sharing)) ( [ Paper ](https://swarm.cs.pub.ro/~mbarbulescu/cripto/Understanding%20Cryptography%20by%20Christof%20Paar%20.pdf))
84
+ - Cheapest Insertion ([ Colab Demo ](https://colab.research.google.com/drive/1QOg8FDvrFUgojwLXD2BBvEuB9Mu7q88a?usp=sharing)) ( [ Paper ](https://disco.ethz.ch/courses/fs16/podc/readingAssignment/1.pdf))
85
+ - Christofides Algorithm ([ Colab Demo ](https://colab.research.google.com/drive/1Wbm-YQ9TeH2OU-IjZzVdDkWGQILv4Pj_?usp=sharing)) ( [ Paper ](https://apps.dtic.mil/dtic/tr/fulltext/u2/a025602.pdf))
86
+ - Clarke & Wright (Savings Heuristic) ([ Colab Demo ](https://colab.research.google.com/drive/1XC2yoVe6wTsjt7u2fBaL3LcKUu42FG8r?usp=sharing)) ( [ Paper ](http://dx.doi.org/10.1287/opre.12.4.568))
87
+ - Concave Hull Algorithm ([ Colab Demo ](https://colab.research.google.com/drive/1P96DerRe7CLyC9dQNr96nEkNHnxpGYY4?usp=sharing)) ( [ Paper ](http://repositorium.sdum.uminho.pt/bitstream/1822/6429/1/ConcaveHull_ACM_MYS.pdf))
88
+ - Convex Hull Algorithm ([ Colab Demo ](https://colab.research.google.com/drive/1Wn2OWccZukOfMtJuGV9laklLTc8vjOFq?usp=sharing)) ( [ Paper ](https://doi.org/10.1109/TSMC.1974.4309370))
89
+ - Elastic Net ([ Colab Demo ](https://colab.research.google.com/drive/1F7IlkKdZ3_zQ_MkhknkIPHvE5RqJG7YC?usp=sharing)) ( [ Paper ](https://doi.org/10.1038/326689a0))
90
+ - Extremal Optimization ([ Colab Demo ](https://colab.research.google.com/drive/1Y5YH0eYKjr1nj_IfhJXaILRDIXm-LWLs?usp=sharing)) ( [ Paper ](https://doi.org/10.1109/5992.881710))
91
+ - Farthest Insertion ([ Colab Demo ](https://colab.research.google.com/drive/13pWiLL_dO9Y1lvQO0zD50MXk4mD0Tn1W?usp=sharing)) ( [ Paper ](https://disco.ethz.ch/courses/fs16/podc/readingAssignment/1.pdf))
92
+ - Genetic Algorithm ([ Colab Demo ](https://colab.research.google.com/drive/1zO9rm-G6HOMeg1Q_ptMHJr48EpHcCAIS?usp=sharing)) ( [ Paper ](https://doi.org/10.1007/BF02125403))
93
+ - GRASP (Greedy Randomized Adaptive Search Procedure) ([ Colab Demo ](https://colab.research.google.com/drive/1OnRyCc6C_QL6wr6-l5RlQI4eGbMdwuhS?usp=sharing)) ( [ Paper ](https://doi.org/10.1007/BF01096763))
94
+ - Greedy Karp-Steele Patching ([ Colab Demo ](https://colab.research.google.com/drive/1to3u45QWWQK8REj1_YiF5rUqUqNjB18q?usp=sharing)) ( [ Paper ](https://doi.org/10.1016/S0377-2217(99)00468-3))
95
+ - Guided Search ([ Colab Demo ](https://colab.research.google.com/drive/1uT9mlDoo37Ni7hqziGNELEGQCGBKQ83o?usp=sharing)) ( [ Paper ](https://doi.org/10.1016/S0377-2217(98)00099-X))
96
+ - Hopfield Network ([ Colab Demo ](https://colab.research.google.com/drive/1Io20FFsndsRT3Bc1nimLBcpH5WtEt7Pe?usp=sharing)) ( [ Paper ](https://doi.org/10.1515/dema-1996-0126))
97
+ - Iterated Search ([ Colab Demo ](https://colab.research.google.com/drive/1U3sPpknulwsCUQq9mK7Ywfb8ap2GIXZv?usp=sharing)) ( [ Paper ](https://doi.org/10.1063/1.36219))
98
+ - Karp-Steele Patching ([ Colab Demo ](https://colab.research.google.com/drive/12xLLDNIk6OOSNQXqYSYtdwhupZ9Kt5xb?usp=sharing)) ( [ Paper ](https://doi.org/10.1137/0208045))
99
+ - Large Neighborhood Search ([ Colab Demo ](https://colab.research.google.com/drive/1t4cafHRRzOLN4xth96jE-2qHoPQOLsn5?usp=sharing)) ( [ Paper ](https://doi.org/10.1007/3-540-49481-2_30))
100
+ - Multifragment Heuristic ([ Colab Demo ](https://colab.research.google.com/drive/1YNHVjS6P35bAnqGZyP7ERNrTnG9tNuhF?usp=sharing)) ( [ Paper ](https://citeseerx.ist.psu.edu/viewdoc/download;jsessionid=08D176AEFA57EF1941645F2B31DF1686?doi=10.1.1.92.1635&rep=rep1&type=pdf))
101
+ - Nearest Insertion ([ Colab Demo ](https://colab.research.google.com/drive/1R4mz604EG-unKktu8ON_Hpoywi3OIRHK?usp=sharing)) ( [ Paper ](https://disco.ethz.ch/courses/fs16/podc/readingAssignment/1.pdf))
102
+ - Nearest Neighbour ([ Colab Demo ](https://colab.research.google.com/drive/1aL1kYXgSjUJYPfYSMy_0SWq4hJ3nrueJ?usp=sharing)) ( [ Paper ](https://doi.org/10.1016/S0166-218X(01)00195-0))
103
+ - Random Insertion ([ Colab Demo ](https://colab.research.google.com/drive/1RP_grqrTXyDkHOLB_L1H8TkvxdLli5hG?usp=sharing)) ( [ Paper ](https://disco.ethz.ch/courses/fs16/podc/readingAssignment/1.pdf))
104
+ - Random Tour ([ Colab Demo ](https://colab.research.google.com/drive/1DPXMJXInkGKTyVFDAQ2bKXjglhy3DaCS?usp=sharing)) ( [ Paper ](https://doi.org/10.1023/A:1011263204536))
105
+ - RL Q-Learning ([ Colab Demo ](https://colab.research.google.com/drive/1dnZhLAzQdz9kzxKrVcwMECWbyEKkZ7St?usp=sharing)) ( [ Paper ](https://doi.org/10.1049/tje2.12303))
106
+ - RL Double Q-Learning([ Colab Demo ](https://colab.research.google.com/drive/1VTv8A6Ac-LvBxsereFyGRfkiLRbJI547?usp=sharing)) ( [ Paper ](https://doi.org/10.1049/tje2.12303))
107
+ - RL S.A.R.S.A ([ Colab Demo ](https://colab.research.google.com/drive/1q9hon3jFf8xVCw4idxhu7goLREKbQ6N3?usp=sharing)) ( [ Paper ](https://doi.org/10.1049/tje2.12303))
108
+ - Scatter Search ([ Colab Demo ](https://colab.research.google.com/drive/115Ql6KegvOjlNUUfsbY4fA8Vab-db26N?usp=sharing)) ( [ Paper ](https://doi.org/10.1111/j.1540-5915.1977.tb01074.x))
109
+ - Simulated Annealing ([ Colab Demo ](https://colab.research.google.com/drive/10Th0yLaAeSqp9FhYB0H00e4sXTbg7Jp2?usp=sharing)) ( [ Paper ](https://www.jstor.org/stable/1690046))
110
+ - SOM (Self Organizing Maps) ([ Colab Demo ](https://colab.research.google.com/drive/1-ZwSFnXf1_kCeY_p3SC3N21T8QeSWsg6?usp=sharing)) ( [ Paper ](https://arxiv.org/pdf/2201.07208.pdf))
111
+ - Space Filling Curve (Hilbert) ([ Colab Demo ](https://colab.research.google.com/drive/1FXzWrUBjdbJBngRFHv66CZw5pFN3yOs8?usp=sharing)) ( [ Paper ](https://doi.org/10.1016/0960-0779(95)80046-J))
112
+ - Space Filling Curve (Morton) ([ Colab Demo ](https://colab.research.google.com/drive/1Z13kXyi7eaNQbBUmhvwuQjY4VaUfGVbs?usp=sharing)) ( [ Paper ](https://dominoweb.draco.res.ibm.com/reports/Morton1966.pdf))
113
+ - Space Filling Curve (Sierpinski) ([ Colab Demo ](https://colab.research.google.com/drive/1w-Zptd5kOryCwvQ0qSNBNhPXC61c8QXF?usp=sharing)) ( [ Paper ](https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.67.9061&rep=rep1&type=pdf))
114
+ - Stochastic Hill Climbing ([ Colab Demo ](https://colab.research.google.com/drive/1_wP6vg4JoRHGItGxEtXcf9Y9OuuoDlDl?usp=sharing)) ( [ Paper ](http://aima.cs.berkeley.edu/))
115
+ - Sweep ([ Colab Demo ](https://colab.research.google.com/drive/1AkAn4yeomAp6POBslk3Asd6OrxfBrHT7?usp=sharing)) ( [ Paper ](http://dx.doi.org/10.1287/opre.22.2.340))
116
+ - Tabu Search ([ Colab Demo ](https://colab.research.google.com/drive/1SRwQrBaxkKk18SDvQPy--0yNRWdl6Y1G?usp=sharing)) ( [ Paper ](https://doi.org/10.1287/ijoc.1.3.190))
117
+ - Truncated Branch & Bound ([ Colab Demo ](https://colab.research.google.com/drive/16m72PrBZN8mWMCer12dgsStcNGs4DVdQ?usp=sharing)) ( [ Paper ](https://research.ijcaonline.org/volume65/number5/pxc3885866.pdf))
118
+ - Twice-Around the Tree Algorithm ([ Colab Demo ](https://colab.research.google.com/drive/1tf5tc5DxvEUc89JaaFgzmK1TtD1e4fkc?usp=sharing)) ( [ Paper ](https://doi.org/10.1016/0196-6774(84)90029-4))
119
+ - Variable Neighborhood Search ([ Colab Demo ](https://colab.research.google.com/drive/1yMWjYuurzpcijsCFDTA76fAwJmSaDkZq?usp=sharing)) ( [ Paper ](https://doi.org/10.1016/S0305-0548(97)00031-2))
120
+
121
+ # Single Objective Optimization
122
+ For Single Objective Optimization try [pyMetaheuristic](https://github.com/Valdecy/pyMetaheuristic)
123
+
124
+ # Multiobjective Optimization or Many Objectives Optimization
125
+ For Multiobjective Optimization or Many Objectives Optimization try [pyMultiobjective](https://github.com/Valdecy/pyMultiobjective)
@@ -0,0 +1,114 @@
1
+ # pyCombinatorial
2
+
3
+ ## Introduction
4
+
5
+ A library to solve the TSP (Travelling Salesman Problem) using Exact Algorithms, Heuristics and Metaheuristics : **2-opt**; **2.5-opt**; **3-opt**; **4-opt**; **5-opt**; **2-opt Stochastic**; **2.5-opt Stochastic**; **3-opt Stochastic**; **4-opt Stochastic**; **5-opt Stochastic**; **Ant Colony Optimization**; **Adaptive Large Neighborhood Search**; **Bellman-Held-Karp Exact Algorithm**; **Branch & Bound**; **BRKGA** (Biased Random Key Genetic Algorithm); **Brute Force**; **Cheapest Insertion**; **Christofides Algorithm**; **Clarke & Wright** (Savings Heuristic); **Concave Hull Algorithm**; **Convex Hull Algorithm**; **Elastic Net**; **Extremal Optimization**; **Farthest Insertion**; **Genetic Algorithm**; **GRASP** (Greedy Randomized Adaptive Search Procedure); **Greedy Karp-Steele Patching**; **Guided Search**; **Hopfield Network**; **Iterated Search**; **Karp-Steele Patching**; **Large Neighborhood Search**; **Multifragment Heuristic**; **Nearest Insertion**; **Nearest Neighbour**; **Random Insertion**; **Random Tour**; **RL Q-Learning**; **RL Double Q-Learning**; **RL S.A.R.S.A** (State Action Reward State Action); **Scatter Search**; **Simulated Annealing**; **SOM** (Self Organizing Maps); **Space Filling Curve** (Hilbert); **Space Filling Curve** (Morton); **Space Filling Curve** (Sierpinski); **Stochastic Hill Climbing**; **Sweep**; **Tabu Search**; **Truncated Branch & Bound**; **Twice-Around the Tree Algorithm** (Double Tree Algorithm); **Variable Neighborhood Search**.
6
+
7
+ ## Usage
8
+
9
+ 1. Install
10
+
11
+ ```bash
12
+ pip install pyCombinatorial
13
+ ```
14
+
15
+ 2. Import
16
+
17
+ ```py3
18
+
19
+
20
+ # Required Libraries
21
+ import pandas as pd
22
+
23
+ # GA
24
+ from pyCombinatorial.algorithm import genetic_algorithm
25
+ from pyCombinatorial.utils import graphs, util
26
+
27
+ # Loading Coordinates # Berlin 52 (Minimum Distance = 7544.3659)
28
+ coordinates = pd.read_csv('https://bit.ly/3Oyn3hN', sep = '\t')
29
+ coordinates = coordinates.values
30
+
31
+ # Obtaining the Distance Matrix
32
+ distance_matrix = util.build_distance_matrix(coordinates)
33
+
34
+ # GA - Parameters
35
+ parameters = {
36
+ 'population_size': 15,
37
+ 'elite': 1,
38
+ 'mutation_rate': 0.1,
39
+ 'mutation_search': 8,
40
+ 'generations': 1000,
41
+ 'verbose': True
42
+ }
43
+
44
+ # GA - Algorithm
45
+ route, distance = genetic_algorithm(distance_matrix, **parameters)
46
+
47
+ # Plot Locations and Tour
48
+ graphs.plot_tour(coordinates, city_tour = route, view = 'browser', size = 10)
49
+ print('Total Distance: ', round(distance, 2))
50
+
51
+ ```
52
+
53
+ 3. Try it in **Colab**
54
+
55
+ - Using Lat Long ([ Colab Demo ](https://colab.research.google.com/drive/17jFw4z1R9gOoAfB-ZCZa6c-PukVKdrt3?usp=sharing))
56
+
57
+ - 2-opt ([ Colab Demo ](https://colab.research.google.com/drive/1SLkM8r_VdlFCpNpm-2yTfr_ynSC5WIX9?usp=sharing)) ( [ Paper ](https://www.jstor.org/stable/167074))
58
+ - 2.5-opt ([ Colab Demo ](https://colab.research.google.com/drive/17bJ-I26prnryAU8p-xf0l7R91cJzb85N?usp=sharing)) ( [ Paper ](https://doi.org/10.1007/s10955-007-9382-1))
59
+ - 3-opt ([ Colab Demo ](https://colab.research.google.com/drive/1iAZLawLBZ-7yaPCyobMtel1SvBamxtjL?usp=sharing)) ( [ Paper ](https://isd.ktu.lt/it2011//material/Proceedings/1_AI_5.pdf))
60
+ - 4-opt ([ Colab Demo ](https://colab.research.google.com/drive/1N8HKhVY4s20sfqo8IWIaCY-NHVk6gARS?usp=sharing)) ( [ Paper ](https://isd.ktu.lt/it2011//material/Proceedings/1_AI_5.pdf))
61
+ - 5-opt ([ Colab Demo ](https://colab.research.google.com/drive/15Qrk-7H4oRaTR77ADvwkiN0sLvycgFDH?usp=sharing)) ( [ Paper ](https://isd.ktu.lt/it2011//material/Proceedings/1_AI_5.pdf))
62
+ - 2-opt Stochastic ([ Colab Demo ](https://colab.research.google.com/drive/1xTm__7OwQVC_KX2b-eExLGgG1DgnJ10a?usp=sharing)) ( [ Paper ](https://doi.org/10.1016/j.trpro.2014.10.001))
63
+ - 2.5-opt Stochastic ([ Colab Demo ](https://colab.research.google.com/drive/16W_QqJ1PebVgqUx8NFOSS5kG3DsJ51UQ?usp=sharing)) ( [ Paper ](https://doi.org/10.1007/s10955-007-9382-1))
64
+ - 3-opt Stochastic ([ Colab Demo ](https://colab.research.google.com/drive/1A5lPW6BSDD2rLNDlnpQo44U8jwKcAGXL?usp=sharing)) ( [ Paper ](https://isd.ktu.lt/it2011//material/Proceedings/1_AI_5.pdf))
65
+ - 4-opt Stochastic ([ Colab Demo ](https://colab.research.google.com/drive/1igWrUMVSInzyeOdhPcGuMjyooZ6elvLY?usp=sharing)) ( [ Paper ](https://isd.ktu.lt/it2011//material/Proceedings/1_AI_5.pdf))
66
+ - 5-opt Stochastic ([ Colab Demo ](https://colab.research.google.com/drive/13vS5MCeFqb3F4ntxrw3iCsMbJTfEVyeo?usp=sharing)) ( [ Paper ](https://isd.ktu.lt/it2011//material/Proceedings/1_AI_5.pdf))
67
+ - Ant Colony Optimization ([ Colab Demo ](https://colab.research.google.com/drive/1O2qogrjE4mZUZX3nsSxw43crumlBnd-D?usp=sharing)) ( [ Paper ](https://doi.org/10.1109/4235.585892))
68
+ - Adaptive Large Neighborhood Search ([ Colab Demo ](https://colab.research.google.com/drive/1vShK5fe2xRCpMkurgd4PzmstGtn6d_LQ?usp=sharing)) ( [ Paper ](https://www.jstor.org/stable/25769321))
69
+ - Bellman-Held-Karp Exact Algorithm ([ Colab Demo ](https://colab.research.google.com/drive/1HSnArk-v8PWY4dlCvT5zcSAnT1FJEDaf?usp=sharing)) ( [ Paper ](https://dl.acm.org/doi/10.1145/321105.321111))
70
+ - Branch & Bound ([ Colab Demo ](https://colab.research.google.com/drive/1oDHrECSW3g4vBEsrO8T7qSHID4fxFiqs?usp=sharing)) ( [ Paper ](https://doi.org/10.1016/j.disopt.2016.01.005))
71
+ - BRKGA (Biased Random Key Genetic Algorithm) ([ Colab Demo ](https://colab.research.google.com/drive/1lwnpUBl1P1LIvzN1saLgEvnaKZRMWLHn?usp=sharing)) ( [ Paper ](https://doi.org/10.1007/s10732-010-9143-1))
72
+ - Brute Force ([ Colab Demo ](https://colab.research.google.com/drive/10vOkBz3Cv9UdHPlcBWkDmJO7EvDg96ar?usp=sharing)) ( [ Paper ](https://swarm.cs.pub.ro/~mbarbulescu/cripto/Understanding%20Cryptography%20by%20Christof%20Paar%20.pdf))
73
+ - Cheapest Insertion ([ Colab Demo ](https://colab.research.google.com/drive/1QOg8FDvrFUgojwLXD2BBvEuB9Mu7q88a?usp=sharing)) ( [ Paper ](https://disco.ethz.ch/courses/fs16/podc/readingAssignment/1.pdf))
74
+ - Christofides Algorithm ([ Colab Demo ](https://colab.research.google.com/drive/1Wbm-YQ9TeH2OU-IjZzVdDkWGQILv4Pj_?usp=sharing)) ( [ Paper ](https://apps.dtic.mil/dtic/tr/fulltext/u2/a025602.pdf))
75
+ - Clarke & Wright (Savings Heuristic) ([ Colab Demo ](https://colab.research.google.com/drive/1XC2yoVe6wTsjt7u2fBaL3LcKUu42FG8r?usp=sharing)) ( [ Paper ](http://dx.doi.org/10.1287/opre.12.4.568))
76
+ - Concave Hull Algorithm ([ Colab Demo ](https://colab.research.google.com/drive/1P96DerRe7CLyC9dQNr96nEkNHnxpGYY4?usp=sharing)) ( [ Paper ](http://repositorium.sdum.uminho.pt/bitstream/1822/6429/1/ConcaveHull_ACM_MYS.pdf))
77
+ - Convex Hull Algorithm ([ Colab Demo ](https://colab.research.google.com/drive/1Wn2OWccZukOfMtJuGV9laklLTc8vjOFq?usp=sharing)) ( [ Paper ](https://doi.org/10.1109/TSMC.1974.4309370))
78
+ - Elastic Net ([ Colab Demo ](https://colab.research.google.com/drive/1F7IlkKdZ3_zQ_MkhknkIPHvE5RqJG7YC?usp=sharing)) ( [ Paper ](https://doi.org/10.1038/326689a0))
79
+ - Extremal Optimization ([ Colab Demo ](https://colab.research.google.com/drive/1Y5YH0eYKjr1nj_IfhJXaILRDIXm-LWLs?usp=sharing)) ( [ Paper ](https://doi.org/10.1109/5992.881710))
80
+ - Farthest Insertion ([ Colab Demo ](https://colab.research.google.com/drive/13pWiLL_dO9Y1lvQO0zD50MXk4mD0Tn1W?usp=sharing)) ( [ Paper ](https://disco.ethz.ch/courses/fs16/podc/readingAssignment/1.pdf))
81
+ - Genetic Algorithm ([ Colab Demo ](https://colab.research.google.com/drive/1zO9rm-G6HOMeg1Q_ptMHJr48EpHcCAIS?usp=sharing)) ( [ Paper ](https://doi.org/10.1007/BF02125403))
82
+ - GRASP (Greedy Randomized Adaptive Search Procedure) ([ Colab Demo ](https://colab.research.google.com/drive/1OnRyCc6C_QL6wr6-l5RlQI4eGbMdwuhS?usp=sharing)) ( [ Paper ](https://doi.org/10.1007/BF01096763))
83
+ - Greedy Karp-Steele Patching ([ Colab Demo ](https://colab.research.google.com/drive/1to3u45QWWQK8REj1_YiF5rUqUqNjB18q?usp=sharing)) ( [ Paper ](https://doi.org/10.1016/S0377-2217(99)00468-3))
84
+ - Guided Search ([ Colab Demo ](https://colab.research.google.com/drive/1uT9mlDoo37Ni7hqziGNELEGQCGBKQ83o?usp=sharing)) ( [ Paper ](https://doi.org/10.1016/S0377-2217(98)00099-X))
85
+ - Hopfield Network ([ Colab Demo ](https://colab.research.google.com/drive/1Io20FFsndsRT3Bc1nimLBcpH5WtEt7Pe?usp=sharing)) ( [ Paper ](https://doi.org/10.1515/dema-1996-0126))
86
+ - Iterated Search ([ Colab Demo ](https://colab.research.google.com/drive/1U3sPpknulwsCUQq9mK7Ywfb8ap2GIXZv?usp=sharing)) ( [ Paper ](https://doi.org/10.1063/1.36219))
87
+ - Karp-Steele Patching ([ Colab Demo ](https://colab.research.google.com/drive/12xLLDNIk6OOSNQXqYSYtdwhupZ9Kt5xb?usp=sharing)) ( [ Paper ](https://doi.org/10.1137/0208045))
88
+ - Large Neighborhood Search ([ Colab Demo ](https://colab.research.google.com/drive/1t4cafHRRzOLN4xth96jE-2qHoPQOLsn5?usp=sharing)) ( [ Paper ](https://doi.org/10.1007/3-540-49481-2_30))
89
+ - Multifragment Heuristic ([ Colab Demo ](https://colab.research.google.com/drive/1YNHVjS6P35bAnqGZyP7ERNrTnG9tNuhF?usp=sharing)) ( [ Paper ](https://citeseerx.ist.psu.edu/viewdoc/download;jsessionid=08D176AEFA57EF1941645F2B31DF1686?doi=10.1.1.92.1635&rep=rep1&type=pdf))
90
+ - Nearest Insertion ([ Colab Demo ](https://colab.research.google.com/drive/1R4mz604EG-unKktu8ON_Hpoywi3OIRHK?usp=sharing)) ( [ Paper ](https://disco.ethz.ch/courses/fs16/podc/readingAssignment/1.pdf))
91
+ - Nearest Neighbour ([ Colab Demo ](https://colab.research.google.com/drive/1aL1kYXgSjUJYPfYSMy_0SWq4hJ3nrueJ?usp=sharing)) ( [ Paper ](https://doi.org/10.1016/S0166-218X(01)00195-0))
92
+ - Random Insertion ([ Colab Demo ](https://colab.research.google.com/drive/1RP_grqrTXyDkHOLB_L1H8TkvxdLli5hG?usp=sharing)) ( [ Paper ](https://disco.ethz.ch/courses/fs16/podc/readingAssignment/1.pdf))
93
+ - Random Tour ([ Colab Demo ](https://colab.research.google.com/drive/1DPXMJXInkGKTyVFDAQ2bKXjglhy3DaCS?usp=sharing)) ( [ Paper ](https://doi.org/10.1023/A:1011263204536))
94
+ - RL Q-Learning ([ Colab Demo ](https://colab.research.google.com/drive/1dnZhLAzQdz9kzxKrVcwMECWbyEKkZ7St?usp=sharing)) ( [ Paper ](https://doi.org/10.1049/tje2.12303))
95
+ - RL Double Q-Learning([ Colab Demo ](https://colab.research.google.com/drive/1VTv8A6Ac-LvBxsereFyGRfkiLRbJI547?usp=sharing)) ( [ Paper ](https://doi.org/10.1049/tje2.12303))
96
+ - RL S.A.R.S.A ([ Colab Demo ](https://colab.research.google.com/drive/1q9hon3jFf8xVCw4idxhu7goLREKbQ6N3?usp=sharing)) ( [ Paper ](https://doi.org/10.1049/tje2.12303))
97
+ - Scatter Search ([ Colab Demo ](https://colab.research.google.com/drive/115Ql6KegvOjlNUUfsbY4fA8Vab-db26N?usp=sharing)) ( [ Paper ](https://doi.org/10.1111/j.1540-5915.1977.tb01074.x))
98
+ - Simulated Annealing ([ Colab Demo ](https://colab.research.google.com/drive/10Th0yLaAeSqp9FhYB0H00e4sXTbg7Jp2?usp=sharing)) ( [ Paper ](https://www.jstor.org/stable/1690046))
99
+ - SOM (Self Organizing Maps) ([ Colab Demo ](https://colab.research.google.com/drive/1-ZwSFnXf1_kCeY_p3SC3N21T8QeSWsg6?usp=sharing)) ( [ Paper ](https://arxiv.org/pdf/2201.07208.pdf))
100
+ - Space Filling Curve (Hilbert) ([ Colab Demo ](https://colab.research.google.com/drive/1FXzWrUBjdbJBngRFHv66CZw5pFN3yOs8?usp=sharing)) ( [ Paper ](https://doi.org/10.1016/0960-0779(95)80046-J))
101
+ - Space Filling Curve (Morton) ([ Colab Demo ](https://colab.research.google.com/drive/1Z13kXyi7eaNQbBUmhvwuQjY4VaUfGVbs?usp=sharing)) ( [ Paper ](https://dominoweb.draco.res.ibm.com/reports/Morton1966.pdf))
102
+ - Space Filling Curve (Sierpinski) ([ Colab Demo ](https://colab.research.google.com/drive/1w-Zptd5kOryCwvQ0qSNBNhPXC61c8QXF?usp=sharing)) ( [ Paper ](https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.67.9061&rep=rep1&type=pdf))
103
+ - Stochastic Hill Climbing ([ Colab Demo ](https://colab.research.google.com/drive/1_wP6vg4JoRHGItGxEtXcf9Y9OuuoDlDl?usp=sharing)) ( [ Paper ](http://aima.cs.berkeley.edu/))
104
+ - Sweep ([ Colab Demo ](https://colab.research.google.com/drive/1AkAn4yeomAp6POBslk3Asd6OrxfBrHT7?usp=sharing)) ( [ Paper ](http://dx.doi.org/10.1287/opre.22.2.340))
105
+ - Tabu Search ([ Colab Demo ](https://colab.research.google.com/drive/1SRwQrBaxkKk18SDvQPy--0yNRWdl6Y1G?usp=sharing)) ( [ Paper ](https://doi.org/10.1287/ijoc.1.3.190))
106
+ - Truncated Branch & Bound ([ Colab Demo ](https://colab.research.google.com/drive/16m72PrBZN8mWMCer12dgsStcNGs4DVdQ?usp=sharing)) ( [ Paper ](https://research.ijcaonline.org/volume65/number5/pxc3885866.pdf))
107
+ - Twice-Around the Tree Algorithm ([ Colab Demo ](https://colab.research.google.com/drive/1tf5tc5DxvEUc89JaaFgzmK1TtD1e4fkc?usp=sharing)) ( [ Paper ](https://doi.org/10.1016/0196-6774(84)90029-4))
108
+ - Variable Neighborhood Search ([ Colab Demo ](https://colab.research.google.com/drive/1yMWjYuurzpcijsCFDTA76fAwJmSaDkZq?usp=sharing)) ( [ Paper ](https://doi.org/10.1016/S0305-0548(97)00031-2))
109
+
110
+ # Single Objective Optimization
111
+ For Single Objective Optimization try [pyMetaheuristic](https://github.com/Valdecy/pyMetaheuristic)
112
+
113
+ # Multiobjective Optimization or Many Objectives Optimization
114
+ For Multiobjective Optimization or Many Objectives Optimization try [pyMultiobjective](https://github.com/Valdecy/pyMultiobjective)
File without changes
@@ -0,0 +1,52 @@
1
+ from .aco import ant_colony_optimization
2
+ from .alns import adaptive_large_neighborhood_search
3
+ from .bb import branch_and_bound
4
+ from .bf import brute_force_analysis
5
+ from .bhk import bellman_held_karp_exact_algorithm
6
+ from .brkga import biased_random_key_genetic_algorithm
7
+ from .christofides import christofides_algorithm
8
+ from .conc_hull import concave_hull_algorithm
9
+ from .conv_hull import convex_hull_algorithm
10
+ from .cw import clarke_wright_savings
11
+ from .eln import elastic_net_tsp
12
+ from .eo import extremal_optimization
13
+ from .ga import genetic_algorithm
14
+ from .grasp import greedy_randomized_adaptive_search_procedure
15
+ from .gksp import greedy_karp_steele_patching
16
+ from .hpn import hopfield_network_tsp
17
+ from .ins_c import cheapest_insertion
18
+ from .ins_f import farthest_insertion
19
+ from .ins_n import nearest_insertion
20
+ from .ins_r import random_insertion
21
+ from .ksp import karp_steele_patching
22
+ from .lns import large_neighborhood_search
23
+ from .mf import multifragment_heuristic
24
+ from .nn import nearest_neighbour
25
+ from .opt_2 import local_search_2_opt
26
+ from .opt_2_5 import local_search_2h_opt
27
+ from .opt_3 import local_search_3_opt
28
+ from .opt_4 import local_search_4_opt
29
+ from .opt_5 import local_search_5_opt
30
+ from .opt_2s import local_search_2_opt_stochastic
31
+ from .opt_2_5s import local_search_2h_opt_stochastic
32
+ from .opt_3s import local_search_3_opt_stochastic
33
+ from .opt_4s import local_search_4_opt_stochastic
34
+ from .opt_5s import local_search_5_opt_stochastic
35
+ from .rt import random_tour
36
+ from .rl_ql import q_learning
37
+ from .rl_double_ql import double_q_learning
38
+ from .rl_sarsa import sarsa
39
+ from .s_gui import guided_search
40
+ from .s_itr import iterated_search
41
+ from .s_sct import scatter_search
42
+ from .s_shc import stochastic_hill_climbing
43
+ from .s_tabu import tabu_search
44
+ from .s_vns import variable_neighborhood_search
45
+ from .sa import simulated_annealing_tsp
46
+ from .som import self_organizing_maps
47
+ from .spfc_h import space_filling_curve_h
48
+ from .spfc_m import space_filling_curve_m
49
+ from .spfc_s import space_filling_curve_s
50
+ from .swp import sweep
51
+ from .tat import tat_algorithm
52
+ from .tbb import truncated_branch_and_bound
@@ -0,0 +1,117 @@
1
+ ############################################################################
2
+
3
+ # Created by: Prof. Valdecy Pereira, D.Sc.
4
+ # UFF - Universidade Federal Fluminense (Brazil)
5
+ # email: valdecy.pereira@gmail.com
6
+ # Lesson: pyCombinatorial - Ant Colony Optimization
7
+
8
+ # GitHub Repository: <https://github.com/Valdecy>
9
+
10
+ ############################################################################
11
+
12
+ # Required Libraries
13
+ import copy
14
+ import numpy as np
15
+
16
+ ############################################################################
17
+
18
+ # Helper: Calculate Path Distance
19
+ def calculate_distance(distance_matrix, city_list):
20
+ path_distance = 0
21
+ for i in range(0, len(city_list) - 1):
22
+ path_distance = path_distance + distance_matrix[city_list[i]-1, city_list[i+1]-1]
23
+ path_distance = path_distance + distance_matrix[city_list[-1]-1, city_list[0]-1]
24
+ return path_distance
25
+
26
+ # Helper: Perform Local Search (Optional)
27
+ def local_search_2_opt(distance_matrix, city_tour, recursive_seeding = -1):
28
+ city_list, best_path_distance = city_tour[0], city_tour[1]
29
+ improved = True
30
+ while (improved == True):
31
+ improved = False
32
+ for i in range(1, len(city_list) - 2):
33
+ for j in range(i + 1, len(city_list) - 1):
34
+ new_city_list = city_list[:]
35
+ new_city_list[i:j] = city_list[i:j][::-1]
36
+ new_distance = calculate_distance(distance_matrix, new_city_list)
37
+ if (new_distance < best_path_distance):
38
+ best_path_distance = new_distance
39
+ city_list = new_city_list
40
+ improved = True
41
+ return city_list, best_path_distance
42
+
43
+ ############################################################################
44
+
45
+ # Helper: Calculate Attractiveness
46
+ def attractiveness(distance_matrix):
47
+ h = 1 / (distance_matrix + 1e-10)
48
+ np.fill_diagonal(h, 0)
49
+ return h
50
+
51
+ # Helper: Update Pheromone Matrix
52
+ def update_thau(distance_matrix, thau, city_list):
53
+ path_distance = 0
54
+ for i in range(len(city_list) - 1):
55
+ path_distance = path_distance + distance_matrix[city_list[i]-1, city_list[i+1]-1]
56
+ path_distance = path_distance + distance_matrix[city_list[-1]-1, city_list[0]-1]
57
+ for i in range(len(city_list) - 1):
58
+ thau[city_list[ i ]-1, city_list[i+1]-1] = thau[city_list[ i ]-1, city_list[i+1]-1] + 1 / path_distance
59
+ thau[city_list[i+1]-1, city_list[ i ]-1] = thau[city_list[i+1]-1, city_list[ i ]-1] + 1 / path_distance
60
+ thau[city_list[-1]-1, city_list[ 0]-1] = thau[city_list[-1]-1, city_list[ 0]-1] + 1 / path_distance
61
+ thau[city_list[ 0]-1, city_list[-1]-1] = thau[city_list[ 0]-1, city_list[-1]-1] + 1 / path_distance
62
+ return thau
63
+
64
+ # Helper: Generate Ant Paths
65
+ def ants_path(distance_matrix, h, thau, alpha, beta, full_list, ants, local_search):
66
+ best_path_distance = float('inf')
67
+ best_city_list = None
68
+ for _ in range(0, ants):
69
+ city_list = [np.random.choice(full_list)]
70
+ while (len(city_list) < len(full_list)):
71
+ current_city = city_list[-1]
72
+ probabilities = []
73
+ for next_city in full_list:
74
+ if (next_city not in city_list):
75
+ p = (thau[current_city-1, next_city-1] ** alpha) * (h[current_city-1, next_city-1] ** beta)
76
+ probabilities.append(p)
77
+ else:
78
+ probabilities.append(0)
79
+ probabilities = np.array(probabilities) / np.sum(probabilities)
80
+ next_city = np.random.choice(full_list, p = probabilities)
81
+ city_list.append(next_city)
82
+ path_distance = calculate_distance(distance_matrix, city_list)
83
+ if (path_distance < best_path_distance):
84
+ best_city_list = copy.deepcopy(city_list)
85
+ best_path_distance = path_distance
86
+
87
+ if (local_search == True):
88
+ best_city_list, best_path_distance = local_search_2_opt(distance_matrix, city_tour = [best_city_list, best_path_distance])
89
+ thau = update_thau(distance_matrix, thau, city_list = best_city_list)
90
+ return best_city_list, best_path_distance, thau
91
+
92
+ ############################################################################
93
+
94
+ # ACO Function
95
+ def ant_colony_optimization(distance_matrix, ants = 5, iterations = 50, alpha = 1, beta = 2, decay = 0.05, local_search = True, verbose = True):
96
+ count = 0
97
+ best_route = []
98
+ full_list = list(range(1, distance_matrix.shape[0] + 1))
99
+ distance = np.sum(distance_matrix.sum())
100
+ h = attractiveness(distance_matrix)
101
+ thau = np.ones((distance_matrix.shape[0], distance_matrix.shape[0]))
102
+ while (count <= iterations):
103
+ if (verbose == True and count > 0):
104
+ print(f'Iteration = {count}, Distance = {round(best_route[1], 2)}')
105
+ city_list, path_distance, thau = ants_path(distance_matrix, h, thau, alpha, beta, full_list, ants, local_search)
106
+ thau = thau*(1 - decay)
107
+ if (distance > path_distance):
108
+ best_route = copy.deepcopy([city_list])
109
+ best_route.append(path_distance)
110
+ distance = best_route[1]
111
+ count = count + 1
112
+ init_city = best_route[0][0]
113
+ best_route[0].append(init_city)
114
+ return best_route[0], best_route[1]
115
+
116
+ ############################################################################
117
+
@@ -0,0 +1,148 @@
1
+ ############################################################################
2
+
3
+ # Created by: Prof. Valdecy Pereira, D.Sc.
4
+ # UFF - Universidade Federal Fluminense (Brazil)
5
+ # email: valdecy.pereira@gmail.com
6
+ # Lesson: pyCombinatorial - ALNS - Adaptive Large Neighborhood Search
7
+
8
+ # GitHub Repository: <https://github.com/Valdecy>
9
+
10
+ ############################################################################
11
+
12
+ # Required Libraries
13
+ import copy
14
+ import numpy as np
15
+ import random
16
+
17
+ ############################################################################
18
+
19
+ # Function: Euclidean Distance
20
+ def euclidean_distance(point1, point2):
21
+ return np.sqrt((point1[0] - point2[0])**2 + (point1[1] - point2[1])**2)
22
+
23
+ # Function: Tour Distance
24
+ def distance_calc(distance_matrix, city_tour):
25
+ distance = 0
26
+ for k in range(0, len(city_tour[0])-1):
27
+ m = k + 1
28
+ distance = distance + distance_matrix[city_tour[0][k]-1, city_tour[0][m]-1]
29
+ return distance
30
+
31
+ # Function: Tour Distance
32
+ def distance_point(distance_matrix, city_tour):
33
+ distance = 0
34
+ for i in range(0, len(city_tour) - 1):
35
+ distance = distance + distance_matrix[city_tour[i]][city_tour[i + 1]]
36
+ distance = distance + distance_matrix[city_tour[-1]][city_tour[0]]
37
+ return distance
38
+
39
+ ############################################################################
40
+
41
+ # Function: 2_opt
42
+ def local_search_2_opt(distance_matrix, city_tour, recursive_seeding = -1, verbose = True):
43
+ if (recursive_seeding < 0):
44
+ count = -2
45
+ else:
46
+ count = 0
47
+ city_list = copy.deepcopy(city_tour)
48
+ distance = city_list[1]*2
49
+ iteration = 0
50
+ if (verbose == True):
51
+ print('')
52
+ print('Local Search')
53
+ print('')
54
+ while (count < recursive_seeding):
55
+ if (verbose == True):
56
+ print('Iteration = ', iteration, 'Distance = ', round(city_list[1], 2))
57
+ best_route = copy.deepcopy(city_list)
58
+ seed = copy.deepcopy(city_list)
59
+ for i in range(0, len(city_list[0]) - 2):
60
+ for j in range(i+1, len(city_list[0]) - 1):
61
+ best_route[0][i:j+1] = list(reversed(best_route[0][i:j+1]))
62
+ best_route[0][-1] = best_route[0][0]
63
+ best_route[1] = distance_calc(distance_matrix, best_route)
64
+ if (city_list[1] > best_route[1]):
65
+ city_list = copy.deepcopy(best_route)
66
+ best_route = copy.deepcopy(seed)
67
+ count = count + 1
68
+ iteration = iteration + 1
69
+ if (distance > city_list[1] and recursive_seeding < 0):
70
+ distance = city_list[1]
71
+ count = -2
72
+ recursive_seeding = -1
73
+ elif(city_list[1] >= distance and recursive_seeding < 0):
74
+ count = -1
75
+ recursive_seeding = -2
76
+ return city_list[0], city_list[1]
77
+
78
+ ############################################################################
79
+
80
+ # Function: Removal
81
+ def removal_operators():
82
+ def random_removal(city_tour, num_removals):
83
+ removed = set()
84
+ while (len(removed) < num_removals):
85
+ removed.add(random.choice(city_tour[1:]))
86
+ return list(removed)
87
+ return [random_removal]
88
+
89
+ # Function: Insertion
90
+ def insertion_operators():
91
+ def cheapest_insertion(removed_nodes, city_tour, distance_matrix):
92
+ for node in removed_nodes:
93
+ best_insertion_cost = float('inf')
94
+ best_insertion_index = -1
95
+ for i in range(1, len(city_tour) + 1):
96
+ insertion_cost = (distance_matrix[city_tour[i - 1]][node] + distance_matrix[node][city_tour[i % len(city_tour)]] - distance_matrix[city_tour[i - 1]][city_tour[i % len(city_tour)]])
97
+ if (insertion_cost < best_insertion_cost):
98
+ best_insertion_cost = insertion_cost
99
+ best_insertion_index = i
100
+ city_tour.insert(best_insertion_index, node)
101
+ return city_tour
102
+ return [cheapest_insertion]
103
+
104
+ ############################################################################
105
+
106
+ # Function: Adaptive Large Neighborhood Search
107
+ def adaptive_large_neighborhood_search(distance_matrix, iterations = 100, removal_fraction = 0.2, rho = 0.1, local_search = True, verbose = True):
108
+ initial_tour = list(range(0, distance_matrix.shape[0]))
109
+ random.shuffle(initial_tour)
110
+ route = initial_tour.copy()
111
+ distance = distance_point(distance_matrix, route)
112
+ removal_ops = removal_operators()
113
+ insertion_ops = insertion_operators()
114
+ weights_removal = [1.0] * len(removal_ops)
115
+ weights_insertion = [1.0] * len(insertion_ops)
116
+ count = 0
117
+ while (count <= iterations):
118
+ if (verbose == True and count > 0):
119
+ print('Iteration = ', count, 'Distance = ', round(distance, 2))
120
+ city_tour = route.copy()
121
+ removal_op = random.choices(removal_ops, weights = weights_removal)[0]
122
+ insertion_op = random.choices(insertion_ops, weights = weights_insertion)[0]
123
+ num_removals = int(removal_fraction * distance_matrix.shape[0])
124
+ removed_nodes = removal_op(city_tour, num_removals)
125
+ for node in removed_nodes:
126
+ city_tour.remove(node)
127
+ new_tour = insertion_op(removed_nodes, city_tour, distance_matrix)
128
+ new_tour_distance = distance_point(distance_matrix, new_tour)
129
+ if (new_tour_distance < distance):
130
+ route = new_tour
131
+ distance = new_tour_distance
132
+ weights_removal[removal_ops.index(removal_op)] = weights_removal[removal_ops.index(removal_op)] * (1 + rho)
133
+ weights_insertion[insertion_ops.index(insertion_op)] = weights_insertion[insertion_ops.index(insertion_op)] * (1 + rho)
134
+ else:
135
+ weights_removal[removal_ops.index(removal_op)] = weights_removal[removal_ops.index(removal_op)] * (1 - rho)
136
+ weights_insertion[insertion_ops.index(insertion_op)] = weights_insertion[insertion_ops.index(insertion_op)] * (1 - rho)
137
+ total_weight_removal = sum(weights_removal)
138
+ total_weight_insertion = sum(weights_insertion)
139
+ weights_removal = [w / total_weight_removal for w in weights_removal]
140
+ weights_insertion = [w / total_weight_insertion for w in weights_insertion]
141
+ count = count + 1
142
+ route = route + [route[0]]
143
+ route = [item + 1 for item in route]
144
+ if (local_search == True):
145
+ route, distance = local_search_2_opt(distance_matrix, [route, distance], -1, verbose)
146
+ return route, distance
147
+
148
+ ############################################################################