pycombinatorial 2.1.1__tar.gz → 2.1.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 (74) hide show
  1. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/PKG-INFO +3 -2
  2. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/README.md +2 -1
  3. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/__init__.py +1 -0
  4. pycombinatorial-2.1.2/pyCombinatorial/algorithm/ins_f.py +126 -0
  5. pycombinatorial-2.1.2/pyCombinatorial/algorithm/ssi.py +143 -0
  6. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pycombinatorial.egg-info/PKG-INFO +3 -2
  7. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pycombinatorial.egg-info/SOURCES.txt +1 -0
  8. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/setup.py +1 -1
  9. pycombinatorial-2.1.1/pyCombinatorial/algorithm/ins_f.py +0 -112
  10. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/LICENSE +0 -0
  11. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/__init__.py +0 -0
  12. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/aco.py +0 -0
  13. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/alns.py +0 -0
  14. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/bb.py +0 -0
  15. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/bf.py +0 -0
  16. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/bhk.py +0 -0
  17. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/brkga.py +0 -0
  18. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/bt.py +0 -0
  19. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/christofides.py +0 -0
  20. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/conc_hull.py +0 -0
  21. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/conv_hull.py +0 -0
  22. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/cw.py +0 -0
  23. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/eln.py +0 -0
  24. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/eo.py +0 -0
  25. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/frnn.py +0 -0
  26. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/ga.py +0 -0
  27. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/gksp.py +0 -0
  28. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/grasp.py +0 -0
  29. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/hpn.py +0 -0
  30. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/ins_c.py +0 -0
  31. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/ins_n.py +0 -0
  32. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/ins_r.py +0 -0
  33. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/ksp.py +0 -0
  34. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/lns.py +0 -0
  35. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/mf.py +0 -0
  36. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/nn.py +0 -0
  37. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/opt_2.py +0 -0
  38. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/opt_2_5.py +0 -0
  39. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/opt_2_5s.py +0 -0
  40. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/opt_2s.py +0 -0
  41. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/opt_3.py +0 -0
  42. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/opt_3s.py +0 -0
  43. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/opt_4.py +0 -0
  44. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/opt_4s.py +0 -0
  45. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/opt_5.py +0 -0
  46. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/opt_5s.py +0 -0
  47. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/opt_or.py +0 -0
  48. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/rl_double_ql.py +0 -0
  49. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/rl_ql.py +0 -0
  50. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/rl_sarsa.py +0 -0
  51. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/rr.py +0 -0
  52. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/rt.py +0 -0
  53. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/s_gui.py +0 -0
  54. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/s_itr.py +0 -0
  55. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/s_sct.py +0 -0
  56. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/s_shc.py +0 -0
  57. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/s_tabu.py +0 -0
  58. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/s_vns.py +0 -0
  59. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/sa.py +0 -0
  60. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/som.py +0 -0
  61. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/spfc_h.py +0 -0
  62. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/spfc_m.py +0 -0
  63. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/spfc_s.py +0 -0
  64. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/swp.py +0 -0
  65. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/tat.py +0 -0
  66. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/tbb.py +0 -0
  67. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/zs.py +0 -0
  68. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/utils/__init__.py +0 -0
  69. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/utils/graphs.py +0 -0
  70. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/utils/util.py +0 -0
  71. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pycombinatorial.egg-info/dependency_links.txt +0 -0
  72. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pycombinatorial.egg-info/requires.txt +0 -0
  73. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pycombinatorial.egg-info/top_level.txt +0 -0
  74. {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pycombinatorial
3
- Version: 2.1.1
3
+ Version: 2.1.2
4
4
  Summary: A library to solve TSP (Travelling Salesman Problem) using Exact Algorithms, Heuristics, Metaheuristics and Reinforcement Learning
5
5
  Home-page: https://github.com/Valdecy/pyCombinatorial
6
6
  Author: Valdecy Pereira
@@ -15,7 +15,7 @@ License-File: LICENSE
15
15
 
16
16
  **pyCombinatorial** is a Python-based library designed to tackle the classic Travelling Salesman Problem (TSP) through a diverse set of **Exact Algorithms**, **Heuristics**, **Metaheuristics** and **Reinforcement Learning**. It brings together both well-established and cutting-edge methodologies, offering end-users a flexible toolkit to generate high-quality solutions for TSP instances of various sizes and complexities.
17
17
 
18
- Techniques: **2-opt**; **2.5-opt**; **3-opt**; **4-opt**; **5-opt**; **Or-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**; **Bitonic Tour**; **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**; **FRNN** (Fixed Radius Near Neighbor); **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); **Ruin & Recreate**; **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**; **Zero Suffix Method**.
18
+ Techniques: **2-opt**; **2.5-opt**; **3-opt**; **4-opt**; **5-opt**; **Or-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**; **Bitonic Tour**; **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**; **FRNN** (Fixed Radius Near Neighbor); **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); **Ruin & Recreate**; **Scatter Search**; **Simulated Annealing**; **SOM** (Self Organizing Maps); **Space Filling Curve** (Hilbert); **Space Filling Curve** (Morton); **Space Filling Curve** (Sierpinski); **Spectral Seriation Initializer**; **Stochastic Hill Climbing**; **Sweep**; **Tabu Search**; **Truncated Branch & Bound**; **Twice-Around the Tree Algorithm** (Double Tree Algorithm); **Variable Neighborhood Search**; **Zero Suffix Method**.
19
19
 
20
20
  ## Usage
21
21
 
@@ -121,6 +121,7 @@ print('Total Distance: ', round(distance, 2))
121
121
  - 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))
122
122
  - 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))
123
123
  - 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))
124
+ - Spectral Seriation Initializer ([ Colab Demo ](https://colab.research.google.com/drive/1lG0pYxASU75qh0jK-A_eMCoPpCWv0I4V?usp=sharing)) ( [ Paper ](https://doi.org/10.1137/S009753979528577))
124
125
  - Stochastic Hill Climbing ([ Colab Demo ](https://colab.research.google.com/drive/1_wP6vg4JoRHGItGxEtXcf9Y9OuuoDlDl?usp=sharing)) ( [ Paper ](http://aima.cs.berkeley.edu/))
125
126
  - Sweep ([ Colab Demo ](https://colab.research.google.com/drive/1AkAn4yeomAp6POBslk3Asd6OrxfBrHT7?usp=sharing)) ( [ Paper ](http://dx.doi.org/10.1287/opre.22.2.340))
126
127
  - Tabu Search ([ Colab Demo ](https://colab.research.google.com/drive/1SRwQrBaxkKk18SDvQPy--0yNRWdl6Y1G?usp=sharing)) ( [ Paper ](https://doi.org/10.1287/ijoc.1.3.190))
@@ -4,7 +4,7 @@
4
4
 
5
5
  **pyCombinatorial** is a Python-based library designed to tackle the classic Travelling Salesman Problem (TSP) through a diverse set of **Exact Algorithms**, **Heuristics**, **Metaheuristics** and **Reinforcement Learning**. It brings together both well-established and cutting-edge methodologies, offering end-users a flexible toolkit to generate high-quality solutions for TSP instances of various sizes and complexities.
6
6
 
7
- Techniques: **2-opt**; **2.5-opt**; **3-opt**; **4-opt**; **5-opt**; **Or-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**; **Bitonic Tour**; **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**; **FRNN** (Fixed Radius Near Neighbor); **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); **Ruin & Recreate**; **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**; **Zero Suffix Method**.
7
+ Techniques: **2-opt**; **2.5-opt**; **3-opt**; **4-opt**; **5-opt**; **Or-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**; **Bitonic Tour**; **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**; **FRNN** (Fixed Radius Near Neighbor); **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); **Ruin & Recreate**; **Scatter Search**; **Simulated Annealing**; **SOM** (Self Organizing Maps); **Space Filling Curve** (Hilbert); **Space Filling Curve** (Morton); **Space Filling Curve** (Sierpinski); **Spectral Seriation Initializer**; **Stochastic Hill Climbing**; **Sweep**; **Tabu Search**; **Truncated Branch & Bound**; **Twice-Around the Tree Algorithm** (Double Tree Algorithm); **Variable Neighborhood Search**; **Zero Suffix Method**.
8
8
 
9
9
  ## Usage
10
10
 
@@ -110,6 +110,7 @@ print('Total Distance: ', round(distance, 2))
110
110
  - 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))
111
111
  - 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))
112
112
  - 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))
113
+ - Spectral Seriation Initializer ([ Colab Demo ](https://colab.research.google.com/drive/1lG0pYxASU75qh0jK-A_eMCoPpCWv0I4V?usp=sharing)) ( [ Paper ](https://doi.org/10.1137/S009753979528577))
113
114
  - Stochastic Hill Climbing ([ Colab Demo ](https://colab.research.google.com/drive/1_wP6vg4JoRHGItGxEtXcf9Y9OuuoDlDl?usp=sharing)) ( [ Paper ](http://aima.cs.berkeley.edu/))
114
115
  - Sweep ([ Colab Demo ](https://colab.research.google.com/drive/1AkAn4yeomAp6POBslk3Asd6OrxfBrHT7?usp=sharing)) ( [ Paper ](http://dx.doi.org/10.1287/opre.22.2.340))
115
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))
@@ -51,6 +51,7 @@ from .som import self_organizing_maps
51
51
  from .spfc_h import space_filling_curve_h
52
52
  from .spfc_m import space_filling_curve_m
53
53
  from .spfc_s import space_filling_curve_s
54
+ from .ssi import spectral_seriation_initializer
54
55
  from .swp import sweep
55
56
  from .tat import tat_algorithm
56
57
  from .tbb import truncated_branch_and_bound
@@ -0,0 +1,126 @@
1
+ ############################################################################
2
+ # Created by: Prof. Valdecy Pereira, D.Sc.
3
+ # UFF - Universidade Federal Fluminense (Brazil)
4
+ # email: valdecy.pereira@gmail.com
5
+
6
+ # Lesson: pyCombinatorial - Farthest Insertion
7
+
8
+ # GitHub Repository: <https://github.com/Valdecy>
9
+
10
+ ############################################################################
11
+
12
+ import copy
13
+ import numpy as np
14
+
15
+ ############################################################################
16
+
17
+ # Function: Tour Distance
18
+ def distance_calc(distance_matrix, city_tour):
19
+ distance = 0
20
+ for k in range(0, len(city_tour[0]) - 1):
21
+ m = k + 1
22
+ distance = distance + distance_matrix[city_tour[0][k] - 1, city_tour[0][m] - 1]
23
+ return distance
24
+
25
+ ############################################################################
26
+
27
+ # Function: 2_opt
28
+ def local_search_2_opt(distance_matrix, city_tour, recursive_seeding = -1, verbose = True):
29
+ if (recursive_seeding < 0):
30
+ count = -2
31
+ else:
32
+ count = 0
33
+ city_list = copy.deepcopy(city_tour)
34
+ distance = city_list[1] * 2
35
+ iteration = 0
36
+ while (count < recursive_seeding):
37
+ if (verbose == True):
38
+ print('Iteration = ', iteration, 'Distance = ', round(city_list[1], 2))
39
+ best_route = copy.deepcopy(city_list)
40
+ seed = copy.deepcopy(city_list)
41
+ for i in range(0, len(city_list[0]) - 2):
42
+ for j in range(i + 1, len(city_list[0]) - 1):
43
+ best_route[0][i:j + 1] = list(reversed(best_route[0][i:j + 1]))
44
+ best_route[0][-1] = best_route[0][0]
45
+ best_route[1] = distance_calc(distance_matrix, best_route)
46
+ if (city_list[1] > best_route[1]):
47
+ city_list = copy.deepcopy(best_route)
48
+ best_route = copy.deepcopy(seed)
49
+ count = count + 1
50
+ iteration = iteration + 1
51
+ if (distance > city_list[1] and recursive_seeding < 0):
52
+ distance = city_list[1]
53
+ count = -2
54
+ recursive_seeding = -1
55
+ elif (city_list[1] >= distance and recursive_seeding < 0):
56
+ count = -1
57
+ recursive_seeding = -2
58
+ return city_list[0], city_list[1]
59
+
60
+ ############################################################################
61
+
62
+ # Function: Cheapest insertion Position
63
+ def best_insertion(distance_matrix, temp):
64
+ if len(temp) <= 2:
65
+ return temp
66
+ new_node = temp[-1]
67
+ base = temp[:-1]
68
+ base_closed = base + [base[0]]
69
+ best_pos = None
70
+ best_delta = float('+inf')
71
+ for i in range(0, len(base)):
72
+ a = base_closed[i]
73
+ b = base_closed[i + 1]
74
+ delta = (distance_matrix[a, new_node] + distance_matrix[new_node, b] - distance_matrix[a, b])
75
+ if delta < best_delta:
76
+ best_delta = delta
77
+ best_pos = i + 1
78
+ out = base[:]
79
+ out.insert(best_pos, new_node)
80
+ return out
81
+
82
+ ############################################################################
83
+
84
+ # Function: Farthest Insertion
85
+ def farthest_insertion(distance_matrix, local_search = True, verbose = True):
86
+ best_val = float('+inf')
87
+ best_route = []
88
+ n = distance_matrix.shape[0]
89
+ initial_location = -1
90
+ for i1 in range(0, n):
91
+ if (initial_location != -1):
92
+ i1 = initial_location - 1
93
+ dist = np.copy(distance_matrix).astype(float)
94
+ np.fill_diagonal(dist, float('-inf'))
95
+ idx = dist[i1, :].argmax()
96
+ temp = [i1, idx]
97
+ in_tour = set(temp)
98
+ for _ in range(0, n - 2):
99
+ remaining = [u for u in range(0, n) if u not in in_tour]
100
+ best_u = None
101
+ best_score = float('-inf')
102
+ for u in remaining:
103
+ score = min(distance_matrix[u, t] for t in temp)
104
+ if score > best_score:
105
+ best_score = score
106
+ best_u = u
107
+ temp.append(best_u)
108
+ in_tour.add(best_u)
109
+ temp = best_insertion(distance_matrix, temp)
110
+ route = temp + [temp[0]]
111
+ route = [x + 1 for x in route]
112
+ val = distance_calc(distance_matrix, [route, 1])
113
+ if local_search:
114
+ seed = [route, val]
115
+ route2, val2 = local_search_2_opt(distance_matrix, seed, -1, True)
116
+ route, val = route2, val2
117
+ if (val < best_val):
118
+ best_val = val
119
+ best_route = [item for item in route]
120
+ if (verbose == True):
121
+ print('Iteration = ', i1 + 1, 'Distance = ', round(best_val, 2))
122
+ if (initial_location != -1):
123
+ break
124
+ return best_route, best_val
125
+
126
+ ############################################################################
@@ -0,0 +1,143 @@
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 - SSI (Spectral Seriation Initializer)
7
+
8
+ # GitHub Repository: <https://github.com/Valdecy>
9
+
10
+ ############################################################################
11
+
12
+ # Required Libraries
13
+ import numpy as np
14
+
15
+ from numba import njit
16
+ from scipy.sparse import coo_matrix, diags
17
+ from scipy.sparse.linalg import eigsh
18
+
19
+ ############################################################################
20
+
21
+ # Function: Tour Lenght
22
+ @njit(fastmath = True)
23
+ def tour_length(tour, D):
24
+ n = len(tour)
25
+ L = 0.0
26
+ for i in range(n):
27
+ L = L + D[tour[i], tour[(i + 1) % n]]
28
+ return L
29
+
30
+ # Function: 2-opt Passes
31
+ @njit(fastmath = True)
32
+ def two_opt(tour, D, max_passes):
33
+ n = len(tour)
34
+ improved = True
35
+ passes = 0
36
+ while improved and passes < max_passes:
37
+ improved = False
38
+ passes = passes + 1
39
+ for i in range(0, n - 1):
40
+ a_idx = tour[i]
41
+ b_idx = tour[(i + 1)]
42
+ k_end = n - 1 if i == 0 else n
43
+ for k in range(i + 2, k_end):
44
+ c_idx = tour[k]
45
+ d_idx = tour[(k + 1) % n]
46
+ current_cost = D[a_idx, b_idx] + D[c_idx, d_idx]
47
+ new_cost = D[a_idx, c_idx] + D[b_idx, d_idx]
48
+ if new_cost < current_cost:
49
+ p1 = i + 1
50
+ p2 = k
51
+ while p1 < p2:
52
+ temp = tour[p1]
53
+ tour[p1] = tour[p2]
54
+ tour[p2] = temp
55
+ p1 = p1 + 1
56
+ p2 = p2 - 1
57
+ improved = True
58
+ return tour
59
+
60
+ ############################################################################
61
+
62
+ # Function: KNN
63
+ def knn_indices(D, k):
64
+ return np.argsort(D, axis=1)[:, 1 : k + 1]
65
+
66
+ # Function: Affinity
67
+ def build_affinity_sparse(D, k, sigma_mode, sigma_fixed):
68
+ n = D.shape[0]
69
+ nbrs = knn_indices(D.astype(float), k)
70
+ if sigma_mode == 'adaptive':
71
+ sig = D[np.arange(n), nbrs[:, -1]].astype(float) + 1e-12
72
+ else:
73
+ sig = np.full(n, sigma_fixed, dtype = float)
74
+ rows, cols, vals = [], [], []
75
+ for i in range(n):
76
+ si = sig[i]
77
+ for j in nbrs[i]:
78
+ sj = sig[j]
79
+ dij = float(D[i, j])
80
+ if sigma_mode == 'adaptive':
81
+ w = np.exp(-(dij * dij) / (si * sj + 1e-12))
82
+ else:
83
+ w = np.exp(-(dij * dij) / (2.0 * sigma_fixed * sigma_fixed + 1e-12))
84
+ rows.append(i); cols.append(j); vals.append(w)
85
+ W = coo_matrix((vals, (rows, cols)), shape = (n, n)).tocsr()
86
+ W = (W + W.T).tocsr()
87
+ W = W.tolil()
88
+ W.setdiag(0.0)
89
+ W = W.tocsr()
90
+ W.eliminate_zeros()
91
+ return W
92
+
93
+ # Function: Laplacian
94
+ def laplacian_from_W(W):
95
+ d = np.array(W.sum(axis = 1)).reshape(-1)
96
+ return (diags(d) - W).tocsr()
97
+
98
+ # Function: Fiedler Vector
99
+ def fiedler_vector(L):
100
+ vals, vecs = eigsh(L, k = 4, which = 'SM')
101
+ idx = np.argsort(vals)
102
+ vals = vals[idx]
103
+ vecs = vecs[:, idx]
104
+ eps = 1e-10
105
+ j = 0
106
+ while j < len(vals) and vals[j] < eps:
107
+ j = j + 1
108
+ if j == 0 and len(vals) > 1:
109
+ j = 1
110
+ j = min(j, len(vals) - 1)
111
+ return vecs[:, j].copy()
112
+
113
+ ############################################################################
114
+
115
+ # Spectral Seriation Initializer
116
+ def spectral_seriation_initializer(D, k = 12, iterations = 800, sigma_noise = 0.003, sigma_mode = 'adaptive', sigma_fixed = 250.0, two_opt_passes = 10, rnd = 7, verbose = True):
117
+ D = np.asarray(D)
118
+ n = D.shape[0]
119
+ rng = np.random.default_rng(rnd)
120
+ W = build_affinity_sparse(D, k, sigma_mode, sigma_fixed)
121
+ L = laplacian_from_W(W)
122
+ x = fiedler_vector(L)
123
+ best_L = float("inf")
124
+ best_tour = None
125
+ for nt in range(0, iterations):
126
+ x_noisy = x + rng.normal(0.0, sigma_noise, size = n)
127
+ tour = np.argsort(x_noisy).astype(np.int32)
128
+ if rng.random() < 0.5:
129
+ tour = tour[::-1]
130
+ shift = int(rng.integers(0, n))
131
+ tour = np.roll(tour, shift)
132
+ tour = two_opt(tour, D, two_opt_passes)
133
+ Lc = tour_length(tour, D)
134
+ if Lc < best_L:
135
+ best_L = Lc
136
+ best_tour = tour
137
+ if verbose:
138
+ print('Iteration = ', nt, 'Distance = ', best_L)
139
+ best_tour = [item + 1 for item in best_tour]
140
+ best_tour.append(best_tour[0])
141
+ return best_tour, int(best_L)
142
+
143
+ ############################################################################
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pycombinatorial
3
- Version: 2.1.1
3
+ Version: 2.1.2
4
4
  Summary: A library to solve TSP (Travelling Salesman Problem) using Exact Algorithms, Heuristics, Metaheuristics and Reinforcement Learning
5
5
  Home-page: https://github.com/Valdecy/pyCombinatorial
6
6
  Author: Valdecy Pereira
@@ -15,7 +15,7 @@ License-File: LICENSE
15
15
 
16
16
  **pyCombinatorial** is a Python-based library designed to tackle the classic Travelling Salesman Problem (TSP) through a diverse set of **Exact Algorithms**, **Heuristics**, **Metaheuristics** and **Reinforcement Learning**. It brings together both well-established and cutting-edge methodologies, offering end-users a flexible toolkit to generate high-quality solutions for TSP instances of various sizes and complexities.
17
17
 
18
- Techniques: **2-opt**; **2.5-opt**; **3-opt**; **4-opt**; **5-opt**; **Or-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**; **Bitonic Tour**; **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**; **FRNN** (Fixed Radius Near Neighbor); **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); **Ruin & Recreate**; **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**; **Zero Suffix Method**.
18
+ Techniques: **2-opt**; **2.5-opt**; **3-opt**; **4-opt**; **5-opt**; **Or-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**; **Bitonic Tour**; **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**; **FRNN** (Fixed Radius Near Neighbor); **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); **Ruin & Recreate**; **Scatter Search**; **Simulated Annealing**; **SOM** (Self Organizing Maps); **Space Filling Curve** (Hilbert); **Space Filling Curve** (Morton); **Space Filling Curve** (Sierpinski); **Spectral Seriation Initializer**; **Stochastic Hill Climbing**; **Sweep**; **Tabu Search**; **Truncated Branch & Bound**; **Twice-Around the Tree Algorithm** (Double Tree Algorithm); **Variable Neighborhood Search**; **Zero Suffix Method**.
19
19
 
20
20
  ## Usage
21
21
 
@@ -121,6 +121,7 @@ print('Total Distance: ', round(distance, 2))
121
121
  - 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))
122
122
  - 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))
123
123
  - 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))
124
+ - Spectral Seriation Initializer ([ Colab Demo ](https://colab.research.google.com/drive/1lG0pYxASU75qh0jK-A_eMCoPpCWv0I4V?usp=sharing)) ( [ Paper ](https://doi.org/10.1137/S009753979528577))
124
125
  - Stochastic Hill Climbing ([ Colab Demo ](https://colab.research.google.com/drive/1_wP6vg4JoRHGItGxEtXcf9Y9OuuoDlDl?usp=sharing)) ( [ Paper ](http://aima.cs.berkeley.edu/))
125
126
  - Sweep ([ Colab Demo ](https://colab.research.google.com/drive/1AkAn4yeomAp6POBslk3Asd6OrxfBrHT7?usp=sharing)) ( [ Paper ](http://dx.doi.org/10.1287/opre.22.2.340))
126
127
  - Tabu Search ([ Colab Demo ](https://colab.research.google.com/drive/1SRwQrBaxkKk18SDvQPy--0yNRWdl6Y1G?usp=sharing)) ( [ Paper ](https://doi.org/10.1287/ijoc.1.3.190))
@@ -56,6 +56,7 @@ pyCombinatorial/algorithm/som.py
56
56
  pyCombinatorial/algorithm/spfc_h.py
57
57
  pyCombinatorial/algorithm/spfc_m.py
58
58
  pyCombinatorial/algorithm/spfc_s.py
59
+ pyCombinatorial/algorithm/ssi.py
59
60
  pyCombinatorial/algorithm/swp.py
60
61
  pyCombinatorial/algorithm/tat.py
61
62
  pyCombinatorial/algorithm/tbb.py
@@ -6,7 +6,7 @@ long_description = (this_directory / 'README.md').read_text()
6
6
 
7
7
  setup(
8
8
  name='pycombinatorial',
9
- version='2.1.1',
9
+ version='2.1.2',
10
10
  license='GNU',
11
11
  author='Valdecy Pereira',
12
12
  author_email='valdecy.pereira@gmail.com',
@@ -1,112 +0,0 @@
1
- ############################################################################
2
-
3
- # Created by: Prof. Valdecy Pereira, D.Sc.
4
- # UFF - Universidade Federal Fluminense (Brazil)
5
- # email: valdecy.pereira@gmail.com
6
- # Lesson: Farthest Insertion
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
- # Function: Tour Distance
19
- def distance_calc(distance_matrix, city_tour):
20
- distance = 0
21
- for k in range(0, len(city_tour[0])-1):
22
- m = k + 1
23
- distance = distance + distance_matrix[city_tour[0][k]-1, city_tour[0][m]-1]
24
- return distance
25
-
26
- # Function: 2_opt
27
- def local_search_2_opt(distance_matrix, city_tour, recursive_seeding = -1, verbose = True):
28
- if (recursive_seeding < 0):
29
- count = -2
30
- else:
31
- count = 0
32
- city_list = copy.deepcopy(city_tour)
33
- distance = city_list[1]*2
34
- iteration = 0
35
- while (count < recursive_seeding):
36
- if (verbose == True):
37
- print('Iteration = ', iteration, 'Distance = ', round(city_list[1], 2))
38
- best_route = copy.deepcopy(city_list)
39
- seed = copy.deepcopy(city_list)
40
- for i in range(0, len(city_list[0]) - 2):
41
- for j in range(i+1, len(city_list[0]) - 1):
42
- best_route[0][i:j+1] = list(reversed(best_route[0][i:j+1]))
43
- best_route[0][-1] = best_route[0][0]
44
- best_route[1] = distance_calc(distance_matrix, best_route)
45
- if (city_list[1] > best_route[1]):
46
- city_list = copy.deepcopy(best_route)
47
- best_route = copy.deepcopy(seed)
48
- count = count + 1
49
- iteration = iteration + 1
50
- if (distance > city_list[1] and recursive_seeding < 0):
51
- distance = city_list[1]
52
- count = -2
53
- recursive_seeding = -1
54
- elif(city_list[1] >= distance and recursive_seeding < 0):
55
- count = -1
56
- recursive_seeding = -2
57
- return city_list[0], city_list[1]
58
-
59
- ############################################################################
60
-
61
- # Function: Best Insertion
62
- def best_insertion(distance_matrix, temp):
63
- temp_ = [item+1 for item in temp]
64
- temp_ = temp_ + [temp_[0]]
65
- d = distance_calc(distance_matrix, [temp_, 1])
66
- seed = [temp_, d]
67
- temp_, _ = local_search_2_opt(distance_matrix, seed, recursive_seeding = -1, verbose = False)
68
- temp = [item-1 for item in temp_[:-1]]
69
- return temp
70
-
71
- ############################################################################
72
-
73
- # Function: Farthest Insertion
74
- def farthest_insertion(distance_matrix, initial_location = -1, verbose = True):
75
- maximum = float('+inf')
76
- distance = float('+inf')
77
- route = []
78
- for i1 in range(0, distance_matrix.shape[0]):
79
- if (initial_location != -1):
80
- i1 = initial_location-1
81
- temp = []
82
- dist = np.copy(distance_matrix)
83
- dist = dist.astype(float)
84
- np.fill_diagonal(dist, float('-inf'))
85
- idx = dist[i1,:].argmax()
86
- dist[i1,:] = float('-inf')
87
- dist[:,i1] = float('-inf')
88
- temp.append(i1)
89
- temp.append(idx)
90
- for j in range(0, distance_matrix.shape[0]-2):
91
- i2 = idx
92
- idx = dist[i2,:].argmax()
93
- dist[i2,:] = float('-inf')
94
- dist[:,i2] = float('-inf')
95
- temp.append(idx)
96
- temp = best_insertion(distance_matrix, temp)
97
- temp = temp + [temp[0]]
98
- temp = [item + 1 for item in temp]
99
- val = distance_calc(distance_matrix, [temp, 1])
100
- if (val < maximum):
101
- maximum = val
102
- distance = val
103
- route = [item for item in temp]
104
- if (verbose == True):
105
- print('Iteration = ', i1, 'Distance = ', round(distance, 2))
106
- if (initial_location == -1):
107
- continue
108
- else:
109
- break
110
- return route, distance
111
-
112
- ############################################################################
File without changes