コード例 #1
0
    def test_shuffle(self):
        r = Route()
        p = Point("a", 0, 0)
        p2 = Point("b", 0, 2)
        p3 = Point("c", 2, 2)
        r.add(p, p2, p3)
        r2 = r.shuffle()

        assert r is not r2
        assert len(r) == len(r2)
コード例 #2
0
    def test_repr(self):
        """Asserts that the id's of the points all appear"""
        p = Point("aaa", 1, 2)
        p2 = Point("bbb", 3, 4)
        p3 = Point("ccc", 5, 6)
        r = Route()
        r.add(p, p2, p3)

        rep = r.__repr__()
        assert p.id in rep
        assert p2.id in rep
        assert p3.id in rep
コード例 #3
0
ファイル: nearest.py プロジェクト: benhowes/tsp-ga-solver
    def get_route(self, route: Route) -> Route:
        """
        This works by coping Points over from the input route to the output
        route ordered by hopping to the next nearest Point over each iteration
        until all nodes have been visited.

        Args:
            route (Route) - The starting route

        Returns:
            Route - The result of repeatedly hopping to the nearest neighbor
        """
        nn_route = Route()

        # initialize by picking a starting point
        current_point = route.pop(0)

        while len(route):
            nn_route.add(current_point)

            # 1. create a list of tuples with the point and the distance
            # 2. pick the closest
            # 3. remove that from the source route and add to the new route
            distances = [(other, current_point.distance(other)) for other in route]
            next_point, distance = min(distances, key=lambda x: x[1])
            route.remove(next_point)
            current_point = next_point

        return nn_route
コード例 #4
0
    def test_valid_map(self):
        """
        Asserts that the test file `input_file` decodes to what we expect
        """
        input_file = "index,x_coord,y_coord\n1,0,0\n2,0,1\n"

        p = Point("1", 0, 0)
        p2 = Point("2", 0, 1)
        expected_route = Route()
        expected_route.add(p, p2)

        with patch("solver.map_utils.open",
                   self.get_f_open(input_file),
                   create=True) as file:
            route = load_map("mock_file")

        # Note - this does rely on hashing/eq working on points
        assert route == expected_route
コード例 #5
0
ファイル: genetic.py プロジェクト: benhowes/tsp-ga-solver
    def combine(self, parent_a: Route, parent_b: Route) -> list:
        """Uses Cyclic Crossover to combine 2 parents"""
        cycles = self.combine_get_cycles(parent_a, parent_b)

        child_a = [False] * len(parent_a)
        child_b = [False] * len(parent_a)

        # Use alternate loops
        for i, cycle in enumerate(cycles):
            for index in cycle:
                if i % 2:
                    child_a[index] = parent_a[index]
                    child_b[index] = parent_b[index]
                else:
                    child_a[index] = parent_b[index]
                    child_b[index] = parent_a[index]

        child_a = Route(child_a)
        child_b = Route(child_b)
        return [child_a, child_b]
コード例 #6
0
ファイル: genetic.py プロジェクト: benhowes/tsp-ga-solver
    def combine_get_cycles(self, parent_a: Route, parent_b: Route) -> list:
        """Gets the loops from 2 parents. This is done using the method described here:
        http://www.rubicite.com/Tutorials/GeneticAlgorithms/CrossoverOperators/CycleCrossoverOperator.aspx
        """
        seen = [False] * len(parent_a)  # Tracks which parts have been seen
        cycles = []

        for cycle_start in range(len(parent_a)):
            if not seen[cycle_start]:

                cycle = [cycle_start]
                seen[cycle_start] = True
                index = parent_a.index(parent_b[cycle_start])

                while index != cycle_start:
                    cycle.append(index)
                    seen[index] = True
                    index = parent_a.index(parent_b[index])

                cycles.append(cycle)
        return cycles
コード例 #7
0
    def test_total_distance(self):
        r = Route()
        p = Point("a", 0, 0)
        p2 = Point("b", 0, 2)
        r.add(p, p2)
        assert r.total_distance == pytest.approx(2)

        p3 = Point("c", 2, 2)
        r.add(p3)
        assert r.total_distance == pytest.approx(4)
コード例 #8
0
    def test_pop_index(self):
        p = Point("a", 1, 2)
        p2 = Point("b", 1, 2)
        r = Route()
        r.add(p, p2)

        assert len(r) == 2
        r.pop(0)
        assert len(r) == 1
        assert r[0].id == "b"
コード例 #9
0
ファイル: shuffle.py プロジェクト: benhowes/tsp-ga-solver
 def get_route(self, route: Route) -> Route:
     return route.shuffle()
コード例 #10
0
 def test_distance_one_point(self):
     r = Route()
     p = Point("a", 1, 2)
     r.add(p)
     with pytest.raises(ValueError):
         r.total_distance
コード例 #11
0
 def test_distance_no_points(self):
     r = Route()
     with pytest.raises(ValueError):
         r.total_distance
コード例 #12
0
 def test_add_duplicate_point(self):
     p = Point("a", 1, 2)
     r = Route()
     r.add(p)
     r.add(p)
     assert len(r) == 1
コード例 #13
0
 def test_add_valid_point(self):
     p = Point("a", 1, 2)
     r = Route()
     r.add(p)
     assert len(r) == 1
コード例 #14
0
 def test_add_invalid(self):
     p = "Bart Simpson"
     r = Route()
     with pytest.raises(TypeError):
         r.add(p)