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.
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/PKG-INFO +3 -2
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/README.md +2 -1
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/__init__.py +1 -0
- pycombinatorial-2.1.2/pyCombinatorial/algorithm/ins_f.py +126 -0
- pycombinatorial-2.1.2/pyCombinatorial/algorithm/ssi.py +143 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pycombinatorial.egg-info/PKG-INFO +3 -2
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pycombinatorial.egg-info/SOURCES.txt +1 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/setup.py +1 -1
- pycombinatorial-2.1.1/pyCombinatorial/algorithm/ins_f.py +0 -112
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/LICENSE +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/__init__.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/aco.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/alns.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/bb.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/bf.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/bhk.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/brkga.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/bt.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/christofides.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/conc_hull.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/conv_hull.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/cw.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/eln.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/eo.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/frnn.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/ga.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/gksp.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/grasp.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/hpn.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/ins_c.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/ins_n.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/ins_r.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/ksp.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/lns.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/mf.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/nn.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/opt_2.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/opt_2_5.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/opt_2_5s.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/opt_2s.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/opt_3.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/opt_3s.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/opt_4.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/opt_4s.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/opt_5.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/opt_5s.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/opt_or.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/rl_double_ql.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/rl_ql.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/rl_sarsa.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/rr.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/rt.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/s_gui.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/s_itr.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/s_sct.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/s_shc.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/s_tabu.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/s_vns.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/sa.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/som.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/spfc_h.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/spfc_m.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/spfc_s.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/swp.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/tat.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/tbb.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/algorithm/zs.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/utils/__init__.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/utils/graphs.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pyCombinatorial/utils/util.py +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pycombinatorial.egg-info/dependency_links.txt +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pycombinatorial.egg-info/requires.txt +0 -0
- {pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pycombinatorial.egg-info/top_level.txt +0 -0
- {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.
|
|
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.
|
|
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
|
|
@@ -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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pycombinatorial-2.1.1 → pycombinatorial-2.1.2}/pycombinatorial.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|