Data Structures and Algorithms B
  • Introduction
  • Stable Marrage
  • Huffman Codes
    • ABL
    • Implementation
  • Graph Algorithms
    • Connect Component
    • Bipartiteness
    • Strongly Connected Components
      • Implementation
    • Topological Sort
      • Implementation 1
      • Implementation 2
    • Dijkstra’s Shortest Path
    • Minimum Spanning Tree
      • Prims
        • Implementation 1
      • Kruskels
        • Implementation 1
      • Traveling Salesman Problem
    • k-Clustering
    • Dynamic Programming with Trees
      • Implementation 1
      • Implementation 2
    • Disjoint Sets
      • Implementation
    • Eularian Cycle
      • Implementation
    • Hamiltonian Path
      • Implementation
  • Divide and Conquer
    • Merge Sort
    • Integer Multiplication
    • Closest Pair
    • Master Method
  • Dynamic Programming
    • Interval Scheduling
    • Knapsack Problem
  • Network Flow
    • Maximum Network Flow
    • Improvements
    • Image Segmentation
  • String Algorithms
    • Z Algorithm
    • Boyer-Moore
    • Knuth-Morris-Pratt
    • Suffix Trees
      • Naive Implementation
      • Ukkonens Algorithm
        • Implementation
      • Applications
        • Longest Common Substring
        • Longest Palindromic Substring
        • Longest Repeated Substring
  • Randomized Algorithms
    • Bloom Filters
      • Implementation
Powered by GitBook
On this page
  • The First Reveal: Brute Force
  • Implementation

Was this helpful?

  1. Graph Algorithms
  2. Minimum Spanning Tree

Traveling Salesman Problem

PreviousImplementation 1Nextk-Clustering

Last updated 5 years ago

Was this helpful?

AKA, Robots Shortest Tour.

Context:

Input: Some set of 2D Cartesian coordinates.

Output: The minimum distance such that all points are visited.

The First Reveal: Brute Force

The general idea is to generate a complete graph from the set of points. We define a complete graph a simple undirected graph in which every pair of distinct vertices is connected by a unique edge.

What this effectively produces is a graph with complete freedom. The robot is not constrained to the path it could take, but we'll leave it to the greedy algorithm to take care of the rest. Running a MST algorithm on this graph will then generate the minimum weight of all distances, such that all nodes are linked.

Of course, we'd have to cover distance between each edge in the process.

Consider the complete graph above, with a radius of 10. We then obtain:

      -5 9(0) : 10 0-17, 0 10-5, -5 -9-18, 5 9-10, 5 -9-20, -10 0-10, 0 -10-19,
      10 0(0) : -5 9-17, 0 10-14, -5 -9-17, 5 9-10, 5 -9-10, -10 0-20, 0 -10-14,
      0 10(0) : -5 -9-19, 5 9-5, -5 9-5, 10 0-14, 5 -9-19, -10 0-14, 0 -10-20,
     -5 -9(0) : -5 9-18, 10 0-17, 0 10-19, 5 9-20, 5 -9-10, -10 0-10, 0 -10-5,
       5 9(0) : -5 9-10, 10 0-10, 0 10-5, 5 -9-18, -10 0-17, 0 -10-19, -5 -9-20,
      5 -9(0) : -5 9-20, 10 0-10, 0 10-19, -5 -9-10, 5 9-18, -10 0-17, 0 -10-5,
     -10 0(0) : -5 9-10, 10 0-20, 0 10-14, -5 -9-10, 5 9-17, 5 -9-17, 0 -10-14,
     0 -10(0) : -5 9-19, 10 0-14, 0 10-20, -5 -9-5, 5 9-19, 5 -9-5, -10 0-14,

And our MST algorithm should generate:

        ID    WEIGHT PARENT_ID
      10 0        10       5 9
      -5 9         5      0 10
      0 10         0      null
     -5 -9         5     0 -10
       5 9         5      0 10
     0 -10         5      5 -9
     -10 0        10      -5 9
      5 -9        10      10 0

                  min_weight: 50

Which is correct, and makes sense: the more points we add along x2+y2=r2x^2+y^2=r^2x2+y2=r2 should converge towards 2πr2 \pi r2πr.

Implementation

  • I've assumed use of my MST algorithm in my Data Structures and Algorithms Book. Here are the features I've added in:

class Graph {
    Graph(const vector<pair<int, int>> &coords) {
        generate_complete_graph(coords);
    }

    ...

    void db_print_points(const pair<string, vector<pair<string, int>>> &points) {
        cout << "---(" << points.first << ")---: ";
        for (auto i : points.second)
            cout << "(" << i.first << " " << i.second << ")";
        cout << "\n\n";
    }

    int distance(const pair<int, int> &p1, const pair<int, int> &p2)
    {
        return sqrt(pow(p1.first - p2.first, 2) + pow(p1.second - p2.second, 2));
    }

    void generate_complete_graph(const vector<pair<int, int>> &points)
    {
        for (int i = 0; i < points.size(); i++) {

            string main_id = to_string(points[i].first) + " " + to_string(points[i].second);
            vector<pair<string, int>> coords;
            pair<string, vector<pair<string, int>>> cmpt_cord_set;

            // j != i; doesnt connected to itself redundently
            for (int j = 0; j < points.size(); j++) {
                if (j == i) continue;
                string match_id = to_string(points[j].first) + " " + to_string(points[j].second);
                int dist = distance(points[i], points[j]);
                coords.push_back({ match_id, dist });

            }

            cmpt_cord_set.first = main_id;
            cmpt_cord_set.second = coords;

            //db_print_points(cmpt_cord_set);
            //pause();

            add_hash_list(cmpt_cord_set);
        }
    }
}


void test()
{
    cout << "\n\n";

    vector<pair<int, int>> coordinates = { {0, 10},{5, 9},{10, 0},{5, -9},
                                           {0, -10},{-5, -9},{-10, 0},{-5, 9}};

    Graph g(coordinates);
    g.traverse_all();

    unordered_map<string, MST_info> test = g.MST_prims(Node("0 10"));
    print_MST(test);

}

int main()
{
    test();
}