Esempio n. 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)
Esempio n. 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
Esempio n. 3
0
    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
Esempio n. 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
Esempio n. 5
0
    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]
Esempio n. 6
0
    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
Esempio n. 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)
Esempio n. 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"
Esempio n. 9
0
 def get_route(self, route: Route) -> Route:
     return route.shuffle()
Esempio n. 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
Esempio n. 11
0
 def test_distance_no_points(self):
     r = Route()
     with pytest.raises(ValueError):
         r.total_distance
Esempio n. 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
Esempio n. 13
0
 def test_add_valid_point(self):
     p = Point("a", 1, 2)
     r = Route()
     r.add(p)
     assert len(r) == 1
Esempio n. 14
0
 def test_add_invalid(self):
     p = "Bart Simpson"
     r = Route()
     with pytest.raises(TypeError):
         r.add(p)