Coverage for moptipyapps / tsp / tour_length.py: 79%
33 statements
« prev ^ index » next coverage.py v7.13.0, created at 2025-12-11 04:40 +0000
« prev ^ index » next coverage.py v7.13.0, created at 2025-12-11 04:40 +0000
1"""
2The tour length objective function for tours in path representation.
4A Traveling Salesperson Problem (TSP) instance is defined as a
5fully-connected graph with
6:attr:`~moptipyapps.tsp.instance.Instance.n_cities` nodes. Each edge in the
7graph has a weight, which identifies the distance between the nodes. The goal
8is to find the *shortest* tour that visits every single node in the graph
9exactly once and then returns back to its starting node. Then nodes are
10usually called cities. In this file, we present methods for loading instances
11of the TSP as distance matrices `A`. In other words, the value at `A[i, j]`
12identifies the travel distance from `i` to `j`.
14A tour can be represented in path representation, which means that it is
15stored as a permutation of the numbers `0` to `n_cities-1`. The number at
16index `k` identifies that `k`-th city to visit. So the first number in the
17permutation identifies the first city, the second number the second city,
18and so on.
20The length of the tour can be computed by summing up the distances from the
21`k`-th city to the `k+1`-st city, for `k` in `0..n_cities-2` and then adding
22the distance from the last city to the first city. This is what the function
23:func:`tour_length` is doing. This function is then wrapped as objective
24function object in :class:`TourLength`.
26Important initial work on this code has been contributed by Mr. Tianyu LIANG
27(梁天宇), <liangty@stu.hfuu.edu.cn> a Master's student at the Institute of
28Applied Optimization (应用优化研究所) of the School
29of Artificial Intelligence and Big Data (人工智能与大数据学院) at Hefei
30University (合肥大学) in Hefei, Anhui, China (中国安徽省合肥市) under the
31supervision of Prof. Dr. Thomas Weise (汤卫思教授).
331. Gerhard Reinelt. TSPLIB - A Traveling Salesman Problem Library.
34 *ORSA Journal on Computing* 3(4):376-384. November 1991.
35 https://doi.org/10.1287/ijoc.3.4.376.
36 http://comopt.ifi.uni-heidelberg.de/software/TSPLIB95/
372. Gerhard Reinelt. *TSPLIB95.* Heidelberg, Germany: Universität
38 Heidelberg, Institut für Angewandte Mathematik. 1995.
39 http://comopt.ifi.uni-heidelberg.de/software/TSPLIB95/tsp95.pdf
403. David Lee Applegate, Robert E. Bixby, Vašek Chvátal, and William John Cook.
41 *The Traveling Salesman Problem: A Computational Study.* Second Edition,
42 2007. Princeton, NJ, USA: Princeton University Press. Volume 17 of
43 Princeton Series in Applied Mathematics. ISBN: 0-691-12993-2.
444. Gregory Z. Gutin and Abraham P. Punnen. *The Traveling Salesman Problem and
45 its Variations.* 2002. Kluwer Academic Publishers. Volume 12 of
46 Combinatorial Optimization. https://doi.org/10.1007/b101971.
475. Pedro Larrañaga, Cindy M. H. Kuijpers, Roberto H. Murga, Iñaki Inza, and
48 Sejla Dizdarevic. Genetic Algorithms for the Travelling Salesman Problem: A
49 Review of Representations and Operators. *Artificial Intelligence Review*
50 13(2):129-170. April 1999. https://doi.org/10.1023/A:1006529012972.
516. Eugene Leighton Lawler, Jan Karel Lenstra, Alexander Hendrik George Rinnooy
52 Kan, and David B. Shmoys. *The Traveling Salesman Problem: A Guided Tour of
53 Combinatorial Optimization.* September 1985. Chichester, West Sussex, UK:
54 Wiley Interscience. In Estimation, Simulation, and
55 Control - Wiley-Interscience Series in Discrete Mathematics and
56 Optimization. ISBN: 0-471-90413-9
577. Tianyu Liang, Zhize Wu, Jörg Lässig, Daan van den Berg, and Thomas Weise.
58 Solving the Traveling Salesperson Problem using Frequency Fitness
59 Assignment. In *Proceedings of the IEEE Symposium on Foundations of
60 Computational Intelligence (IEEE FOCI'22),* part of the *IEEE Symposium
61 Series on Computational Intelligence (SSCI'22),* December 4-7, 2022,
62 Singapore. Pages 360-367. IEEE.
63 https://doi.org/10.1109/SSCI51031.2022.10022296.
648. Thomas Weise, Raymond Chiong, Ke Tang, Jörg Lässig, Shigeyoshi Tsutsui,
65 Wenxiang Chen, Zbigniew Michalewicz, and Xin Yao. Benchmarking Optimization
66 Algorithms: An Open Source Framework for the Traveling Salesman Problem.
67 *IEEE Computational Intelligence Magazine.* 9(3):40-52. August 2014.
68 https://doi.org/10.1109/MCI.2014.2326101.
69"""
71from typing import Final
73import numba # type: ignore
74import numpy as np
75from moptipy.api.objective import Objective
76from moptipy.utils.logger import KeyValueLogSection
77from pycommons.types import type_error
79from moptipyapps.tsp.instance import Instance
80from moptipyapps.utils.shared import SCOPE_INSTANCE
83@numba.njit(cache=True, inline="always", fastmath=False, boundscheck=False)
84def tour_length(instance: np.ndarray, x: np.ndarray) -> int:
85 """
86 Compute the length of a tour.
88 :param instance: the distance matrix
89 :param x: the tour
90 :return: the length of the tour `x`
91 """
92 result: int = 0
93 last: int = x[-1]
94 for cur in x:
95 result += instance[last, cur]
96 last = cur
97 return result
100class TourLength(Objective):
101 """The tour length objective function."""
103 def __init__(self, instance: Instance) -> None:
104 """
105 Initialize the tour length objective function.
107 :param instance: the tsp instance
108 """
109 if not isinstance(instance, Instance):
110 raise type_error(instance, "instance", Instance)
111 #: the TSP instance we are trying to solve
112 self.instance: Final[Instance] = instance
114 def evaluate(self, x) -> int:
115 """
116 Compute the length of a tour in path representation.
118 :param x: the tour in path representation
119 :return: the tour length
120 """
121 return tour_length(self.instance, x)
123 def lower_bound(self) -> int:
124 """
125 Get the lower bound of the tour length.
127 :return: the lower bound of the tour length
128 """
129 return self.instance.tour_length_lower_bound
131 def upper_bound(self) -> int:
132 """
133 Get the upper bound of the tour length.
135 :return: the upper bound of the tour length
136 """
137 return self.instance.tour_length_upper_bound
139 def __str__(self):
140 """
141 Get the name of this objective function: always "tourLength".
143 :return: "tourLength"
144 :retval "tourLength": always
145 """
146 return "tourLength"
148 def log_parameters_to(self, logger: KeyValueLogSection) -> None:
149 """
150 Log the parameters of the space to the given logger.
152 :param logger: the logger for the parameters
153 """
154 super().log_parameters_to(logger)
155 with logger.scope(SCOPE_INSTANCE) as kv:
156 self.instance.log_parameters_to(kv)