pycombinatorial 2.1.0__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.0 → pycombinatorial-2.1.2}/PKG-INFO +4 -2
  2. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/README.md +3 -1
  3. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/__init__.py +3 -1
  4. pycombinatorial-2.1.2/pyCombinatorial/algorithm/ins_f.py +126 -0
  5. pycombinatorial-2.1.2/pyCombinatorial/algorithm/opt_or.py +192 -0
  6. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/rr.py +2 -4
  7. pycombinatorial-2.1.2/pyCombinatorial/algorithm/ssi.py +143 -0
  8. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pycombinatorial.egg-info/PKG-INFO +4 -2
  9. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pycombinatorial.egg-info/SOURCES.txt +2 -0
  10. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/setup.py +1 -1
  11. pycombinatorial-2.1.0/pyCombinatorial/algorithm/ins_f.py +0 -112
  12. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/LICENSE +0 -0
  13. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/__init__.py +0 -0
  14. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/aco.py +0 -0
  15. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/alns.py +0 -0
  16. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/bb.py +0 -0
  17. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/bf.py +0 -0
  18. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/bhk.py +0 -0
  19. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/brkga.py +0 -0
  20. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/bt.py +0 -0
  21. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/christofides.py +0 -0
  22. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/conc_hull.py +0 -0
  23. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/conv_hull.py +0 -0
  24. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/cw.py +0 -0
  25. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/eln.py +0 -0
  26. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/eo.py +0 -0
  27. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/frnn.py +0 -0
  28. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/ga.py +0 -0
  29. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/gksp.py +0 -0
  30. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/grasp.py +0 -0
  31. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/hpn.py +0 -0
  32. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/ins_c.py +0 -0
  33. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/ins_n.py +0 -0
  34. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/ins_r.py +0 -0
  35. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/ksp.py +0 -0
  36. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/lns.py +0 -0
  37. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/mf.py +0 -0
  38. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/nn.py +0 -0
  39. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/opt_2.py +0 -0
  40. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/opt_2_5.py +0 -0
  41. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/opt_2_5s.py +0 -0
  42. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/opt_2s.py +0 -0
  43. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/opt_3.py +0 -0
  44. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/opt_3s.py +0 -0
  45. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/opt_4.py +0 -0
  46. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/opt_4s.py +0 -0
  47. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/opt_5.py +0 -0
  48. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/opt_5s.py +0 -0
  49. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/rl_double_ql.py +0 -0
  50. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/rl_ql.py +0 -0
  51. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/rl_sarsa.py +0 -0
  52. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/rt.py +0 -0
  53. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/s_gui.py +0 -0
  54. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/s_itr.py +0 -0
  55. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/s_sct.py +0 -0
  56. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/s_shc.py +0 -0
  57. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/s_tabu.py +0 -0
  58. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/s_vns.py +0 -0
  59. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/sa.py +0 -0
  60. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/som.py +0 -0
  61. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/spfc_h.py +0 -0
  62. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/spfc_m.py +0 -0
  63. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/spfc_s.py +0 -0
  64. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/swp.py +0 -0
  65. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/tat.py +0 -0
  66. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/tbb.py +0 -0
  67. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/zs.py +0 -0
  68. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/utils/__init__.py +0 -0
  69. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/utils/graphs.py +0 -0
  70. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pyCombinatorial/utils/util.py +0 -0
  71. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pycombinatorial.egg-info/dependency_links.txt +0 -0
  72. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pycombinatorial.egg-info/requires.txt +0 -0
  73. {pycombinatorial-2.1.0 → pycombinatorial-2.1.2}/pycombinatorial.egg-info/top_level.txt +0 -0
  74. {pycombinatorial-2.1.0 → 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.0
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**; **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
 
@@ -76,6 +76,7 @@ print('Total Distance: ', round(distance, 2))
76
76
  - 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))
77
77
  - 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))
78
78
  - 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))
79
+ - Or-opt ([ Colab Demo ](https://colab.research.google.com/drive/1p7JwrFLH83ZroCzIweXLCAXYgA3FKAI0?usp=sharing)) ( [ Paper ](https://doi.org/10.1057/palgrave.jors.2602160))
79
80
  - 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))
80
81
  - 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))
81
82
  - 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))
@@ -120,6 +121,7 @@ print('Total Distance: ', round(distance, 2))
120
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))
121
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))
122
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))
123
125
  - Stochastic Hill Climbing ([ Colab Demo ](https://colab.research.google.com/drive/1_wP6vg4JoRHGItGxEtXcf9Y9OuuoDlDl?usp=sharing)) ( [ Paper ](http://aima.cs.berkeley.edu/))
124
126
  - Sweep ([ Colab Demo ](https://colab.research.google.com/drive/1AkAn4yeomAp6POBslk3Asd6OrxfBrHT7?usp=sharing)) ( [ Paper ](http://dx.doi.org/10.1287/opre.22.2.340))
125
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**; **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
 
@@ -65,6 +65,7 @@ print('Total Distance: ', round(distance, 2))
65
65
  - 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))
66
66
  - 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))
67
67
  - 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))
68
+ - Or-opt ([ Colab Demo ](https://colab.research.google.com/drive/1p7JwrFLH83ZroCzIweXLCAXYgA3FKAI0?usp=sharing)) ( [ Paper ](https://doi.org/10.1057/palgrave.jors.2602160))
68
69
  - 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))
69
70
  - 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))
70
71
  - 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))
@@ -109,6 +110,7 @@ print('Total Distance: ', round(distance, 2))
109
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))
110
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))
111
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))
112
114
  - Stochastic Hill Climbing ([ Colab Demo ](https://colab.research.google.com/drive/1_wP6vg4JoRHGItGxEtXcf9Y9OuuoDlDl?usp=sharing)) ( [ Paper ](http://aima.cs.berkeley.edu/))
113
115
  - Sweep ([ Colab Demo ](https://colab.research.google.com/drive/1AkAn4yeomAp6POBslk3Asd6OrxfBrHT7?usp=sharing)) ( [ Paper ](http://dx.doi.org/10.1287/opre.22.2.340))
114
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))
@@ -29,6 +29,7 @@ from .opt_2_5 import local_search_2h_opt
29
29
  from .opt_3 import local_search_3_opt
30
30
  from .opt_4 import local_search_4_opt
31
31
  from .opt_5 import local_search_5_opt
32
+ from .opt_or import local_search_or_opt
32
33
  from .opt_2s import local_search_2_opt_stochastic
33
34
  from .opt_2_5s import local_search_2h_opt_stochastic
34
35
  from .opt_3s import local_search_3_opt_stochastic
@@ -37,8 +38,8 @@ from .opt_5s import local_search_5_opt_stochastic
37
38
  from .rl_double_ql import double_q_learning
38
39
  from .rl_ql import q_learning
39
40
  from .rl_sarsa import sarsa
40
- from .rt import random_tour
41
41
  from .rr import ruin_and_recreate
42
+ from .rt import random_tour
42
43
  from .s_gui import guided_search
43
44
  from .s_itr import iterated_search
44
45
  from .s_sct import scatter_search
@@ -50,6 +51,7 @@ from .som import self_organizing_maps
50
51
  from .spfc_h import space_filling_curve_h
51
52
  from .spfc_m import space_filling_curve_m
52
53
  from .spfc_s import space_filling_curve_s
54
+ from .ssi import spectral_seriation_initializer
53
55
  from .swp import sweep
54
56
  from .tat import tat_algorithm
55
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,192 @@
1
+ ############################################################################
2
+
3
+ # Created by: Prof. Valdecy Pereira, D.Sc.
4
+ # UFF - Universidade Federal Fluminense (Brazil)
5
+ # email: valdecy.pereira@gmail.com
6
+ # Lesson: Or-Opt
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: Insertion
62
+ def insertion(city_tour, distance_matrix, chain_length = 5, k_min = 1, k_max = 10, lambda_val = 0.1, vf_mode = True):
63
+
64
+ # -------------------------------------------------------------------------
65
+
66
+ def total_distance(dist_mat, route_idxs):
67
+ total = 0.0
68
+ for idx in range(1, len(route_idxs)):
69
+ total = total + dist_mat[route_idxs[idx - 1]][route_idxs[idx]]
70
+ return total
71
+
72
+ # -------------------------------------------------------------------------
73
+
74
+ route = copy.deepcopy(city_tour[0])
75
+ if route[0] != route[-1]:
76
+ route = route + [route[0]]
77
+ current_distance = total_distance(distance_matrix, route)
78
+ n = len(route) - 1
79
+ if isinstance(distance_matrix, np.ndarray):
80
+ if distance_matrix.ndim != 2 or distance_matrix.shape[0] != distance_matrix.shape[1]:
81
+ raise ValueError("distance_matrix must be a square 2D array.")
82
+ if n <= 1:
83
+ avg_graph_cost = 1.0
84
+ else:
85
+ avg_graph_cost = distance_matrix[np.triu_indices(n, k=1)].mean()
86
+ if not np.isfinite(avg_graph_cost) or avg_graph_cost <= 0:
87
+ avg_graph_cost = 1.0
88
+ else:
89
+ if n <= 1:
90
+ avg_graph_cost = 1.0
91
+ else:
92
+ s = 0.0
93
+ cnt = 0
94
+ for a in range(n):
95
+ for b in range(a + 1, n):
96
+ s = s + distance_matrix[a][b]
97
+ cnt = cnt + 1
98
+ avg_graph_cost = s / cnt if cnt else 1.0
99
+
100
+ k_sequence = list(range(int(k_max), int(k_min) - 1, -1))
101
+ max_passes = max(1, int(chain_length))
102
+ for _pass in range(0, max_passes):
103
+ improved_any = False
104
+ if vf_mode:
105
+ for i in range(1, len(route) - 1):
106
+ for k in k_sequence:
107
+ if i + k >= len(route):
108
+ continue
109
+ i1, i2 = route[i - 1], route[i]
110
+ i3, i4 = route[i + k - 1], route[i + k]
111
+ g = (distance_matrix[i1][i2] +
112
+ distance_matrix[i3][i4] -
113
+ distance_matrix[i1][i4])
114
+ d_bar = current_distance / max(1, n)
115
+ l_bar = (2.0 * avg_graph_cost) - d_bar
116
+ if g <= lambda_val * l_bar:
117
+ continue
118
+ segment = route[i:i + k]
119
+ rem = route[:i] + route[i + k:]
120
+ moved = False
121
+ for j in range(1, len(rem)):
122
+ temp = rem[:j] + segment + rem[j:]
123
+ cost = total_distance(distance_matrix, temp)
124
+ if cost + 1e-12 < current_distance:
125
+ route = temp
126
+ current_distance = cost
127
+ improved_any = True
128
+ moved = True
129
+ break
130
+ if moved:
131
+ break
132
+ else:
133
+ for k in k_sequence:
134
+ improved_k = True
135
+ while improved_k:
136
+ improved_k = False
137
+ last_idx = len(route) - 1
138
+ for i in range(1, last_idx):
139
+ if i + k > last_idx:
140
+ continue
141
+ i1, i2 = route[i - 1], route[i]
142
+ i3, i4 = route[i + k - 1], route[i + k]
143
+ g = (distance_matrix[i1][i2] +
144
+ distance_matrix[i3][i4] -
145
+ distance_matrix[i1][i4])
146
+ d_bar = current_distance / max(1, n)
147
+ l_bar = (2.0 * avg_graph_cost) - d_bar
148
+ if g <= lambda_val * l_bar:
149
+ continue
150
+ segment = route[i:i + k]
151
+ rem = route[:i] + route[i + k:]
152
+ for j in range(1, len(rem)):
153
+ temp = rem[:j] + segment + rem[j:]
154
+ cost = total_distance(distance_matrix, temp)
155
+ if cost + 1e-12 < current_distance:
156
+ route = temp
157
+ current_distance = cost
158
+ improved_k = True
159
+ improved_any = True
160
+ break
161
+ if improved_k:
162
+ break
163
+ if not improved_any:
164
+ break
165
+ return route, current_distance
166
+
167
+ # Function: Or - Opt
168
+ def local_search_or_opt(city_tour, distance_matrix, iterations = 100, chain_length = 3, k1 = 1, k2 = 5, lbd = 0.1, vf = True, local_search = True, verbose = True):
169
+ route = city_tour[0]
170
+ distance = city_tour[1]
171
+ route = [item - 1 for item in route]
172
+ no_improve = 0
173
+ for i in range(0, iterations):
174
+ new_route, new_distance = insertion([route, distance], distance_matrix, chain_length, k1, k2, lbd, vf)
175
+ if new_distance < distance:
176
+ route = copy.deepcopy(new_route)
177
+ distance = new_distance
178
+ no_improve = 0
179
+ else:
180
+ no_improve = no_improve + 1
181
+ if no_improve >= 2:
182
+ break
183
+ if (verbose == True):
184
+ print('Iteration = ', i, 'Distance = ', round(distance, 2))
185
+ route = [item + 1 for item in route]
186
+ if (local_search == True):
187
+ print('')
188
+ print('Local Search:')
189
+ route, distance = local_search_2_opt(distance_matrix, [route, distance], recursive_seeding = -1, verbose = verbose)
190
+ return route, distance
191
+
192
+ ############################################################################
@@ -97,8 +97,7 @@ def ruin_and_recreate(city_tour, distance_matrix, iterations = 100, ruin_rate =
97
97
  distance = city_list[1]
98
98
  best_r = copy.deepcopy(route)
99
99
  best_d = distance
100
- iteration = 0
101
- for _ in range(0, iterations):
100
+ for i in range(0, iterations):
102
101
  n_remove = max(1, int(len(removable) * ruin_rate))
103
102
  to_remove = set(np.random.choice(removable, min(n_remove, len(removable)), replace = False))
104
103
  route = [city for city in route if city not in to_remove]
@@ -107,11 +106,10 @@ def ruin_and_recreate(city_tour, distance_matrix, iterations = 100, ruin_rate =
107
106
  route = regret2_insertion(route, to_remove, distance_matrix)
108
107
  distance = distance_calc(distance_matrix, [route, distance])
109
108
  if (verbose == True):
110
- print('Iteration = ', iteration, 'Distance = ', round(best_d, 2))
109
+ print('Iteration = ', i, 'Distance = ', round(best_d, 2))
111
110
  if distance < best_d:
112
111
  best_r = copy.deepcopy(route)
113
112
  best_d = distance
114
- iteration = iteration + 1
115
113
  if (local_search == True):
116
114
  print('')
117
115
  print('Local Search:')
@@ -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.0
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**; **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
 
@@ -76,6 +76,7 @@ print('Total Distance: ', round(distance, 2))
76
76
  - 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))
77
77
  - 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))
78
78
  - 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))
79
+ - Or-opt ([ Colab Demo ](https://colab.research.google.com/drive/1p7JwrFLH83ZroCzIweXLCAXYgA3FKAI0?usp=sharing)) ( [ Paper ](https://doi.org/10.1057/palgrave.jors.2602160))
79
80
  - 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))
80
81
  - 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))
81
82
  - 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))
@@ -120,6 +121,7 @@ print('Total Distance: ', round(distance, 2))
120
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))
121
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))
122
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))
123
125
  - Stochastic Hill Climbing ([ Colab Demo ](https://colab.research.google.com/drive/1_wP6vg4JoRHGItGxEtXcf9Y9OuuoDlDl?usp=sharing)) ( [ Paper ](http://aima.cs.berkeley.edu/))
124
126
  - Sweep ([ Colab Demo ](https://colab.research.google.com/drive/1AkAn4yeomAp6POBslk3Asd6OrxfBrHT7?usp=sharing)) ( [ Paper ](http://dx.doi.org/10.1287/opre.22.2.340))
125
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))
@@ -39,6 +39,7 @@ pyCombinatorial/algorithm/opt_4.py
39
39
  pyCombinatorial/algorithm/opt_4s.py
40
40
  pyCombinatorial/algorithm/opt_5.py
41
41
  pyCombinatorial/algorithm/opt_5s.py
42
+ pyCombinatorial/algorithm/opt_or.py
42
43
  pyCombinatorial/algorithm/rl_double_ql.py
43
44
  pyCombinatorial/algorithm/rl_ql.py
44
45
  pyCombinatorial/algorithm/rl_sarsa.py
@@ -55,6 +56,7 @@ pyCombinatorial/algorithm/som.py
55
56
  pyCombinatorial/algorithm/spfc_h.py
56
57
  pyCombinatorial/algorithm/spfc_m.py
57
58
  pyCombinatorial/algorithm/spfc_s.py
59
+ pyCombinatorial/algorithm/ssi.py
58
60
  pyCombinatorial/algorithm/swp.py
59
61
  pyCombinatorial/algorithm/tat.py
60
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.0',
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