summaryrefslogtreecommitdiffstats
path: root/src/CS340.TSP/Solve.cs
blob: dd3d3063abceb54b62d5c0ed96bdbf7e81357d43 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
using System.Diagnostics;
using System.Linq;
using System.Text.RegularExpressions;
using Graph;
using Graph.IO;

namespace TSP
{

    using Map = Graph<Vertex<Edge<double>, double>, Edge<double>, double>;

    public static class Solve
    {
        static Map Map { get; set; }
        static Tour BestTour = null;

        public static Tour BruteForce(string file, int init)
        {
            Map = GraphFile.Read(new FileReader(file));
            Tour intialTour = new Tour(Map.Vertices);
            GenerateTour(intialTour[init], new Tour(Map.Vertices), new Tour());

            return BestTour;
        }

        static void GenerateTour(City city, Tour tour, Tour visited)
        {
            // create local copy of Tour variables
            Tour currTour = new Tour(tour.Cities);
            Tour currVisited = new Tour(visited.Cities);
            City currCity = new City(city);

            // remove current City from tour
            currTour.Cities.RemoveAt(currTour.Cities.FindIndex(city => city.Id == currCity.Id));

            //? verify that city was removed
            Debug.Assert(currVisited.Cities.Find(city => city.Id == currCity.Id) == null,
                         $"Failed to remove a city from the tour. \nTour: {tour}\nCity: {currCity.Id}");

            // add current City to visited
            if (currVisited.Cities.Count > 0)
            {
                currCity.Parent = currVisited.Cities.Last().Id;
            }

            currVisited.Cities.Add(currCity);

            //? verify that city was added
            Debug.Assert(currVisited.Cities.Find(city => city.Id == currCity.Id) != null,
                         $"Failed to add a city to the tour. \nTour: {tour}\nCity: {currCity.Id}");

            // loop through each city. Each level of recursion has a one less city in currTour.Cities
            // leaving the base case
            foreach (City neighbor in currTour.Cities)
                GenerateTour(neighbor, currTour, currVisited);


            if (currTour.Cities.Count == 0)
            {
                currVisited.Cities.First().Parent = currVisited.Cities.Last().Id;

                if (BestTour == null || currVisited.Weight < BestTour.Weight)
                    BestTour = new Tour(currVisited.Cities);
                // Debug.Print($"{currTour}");
            }


            return;
        }
    }
}