Skip to content
Snippets Groups Projects
Commit e22f1442 authored by Jakub Janák's avatar Jakub Janák
Browse files

graphs added to README.md

parent 92d40115
No related branches found
No related tags found
No related merge requests found
......@@ -54,12 +54,114 @@ that doesn't have to be optimal but is great.
This method is called approximation and can be done very quickly.
In real life scenarios
is used much more that solving the instance exactly as there may be many nodes and edges(e.g., 1000, 10 000).
![Approximate vs Exact Solution](data_analysis/exact_vs_approx.png)
## Branch and Bound Algorithm
...
Branch and Bound (B&B) is a powerful algorithm for an exact solution of the travelling salesman problem.
It systematically explores the search space(all possible tours) while eliminating branches(subproblems)
that cannot lead to a better solution than the current best. The solution time is much better when compared to the brute force approach:
![Brute force vs B&B](data_analysis/brute_force_vs_branch_bound.png)
However, we still can't be sure that it will be calculated in reasonable time.
### Steps
1. Initialisation
- Start with a best tour approximation using some approximation algorhythm(Nearest Neighbour + 2Opt) in our case.
2. Bounding function
- We have to specify a bounding function that will calculate the lower bound for every partial tour taken.
3. Branching
- The branching step involves generating new subproblems by exploring the search space tree.
4. Bounding
- every time the loer bound calculated by the bounding function is higher than the best result yet the subproblem is pruned and not explored further.
5. Termination
- The algorithm terminates when all tours have been either explored or pruned, and the current best solution is the optimal solution for the TSP.
### Pseudo-code:
```plaintext
1. Initialize:
best_solution = infinity (or a heuristic approximation)
Create an initial node (partial tour with a single city)
2. For each neighbour of current node:
- If the neighbour is already in this subtour then continue
- Connect neighbour to the current sub-tour
- If bound is <= minimal tour then recursive search()
- If length of the tour is same as the number of nodes:
- If the cost is less then minimal tour then clear the set of best tours and add there this tour
- Else if cost is the same as the minimal cost then add current tour to the set of the best tours
3. Return best_solution as the optimal tour
```
### Parallelization
The Branch and bound can be parallelized, and the performance is indeed growing very well. When using the parallelized version,
we must make the initial heuristic approximation and cannot start with estimate of infinity. The pseudocode is very similar to the synchronized version, but the change of the best tours
set needs to be synchronized as well as getting the minimal cost. I am therefore synchronizing with two mutexes. However, the biggest problem is that you need to ensure DFS and not
accidentally search breath-first. Therefore, in each step in the recursion, the method call is added to thread pool and only for the first neighbor the thread continues in the search.
We can see that the parallelized version of B&B performs much better than synchronized:
![Brute force vs B&B](data_analysis/synchronized_vs_parallel_bb.png)
The scaling of the algorithm with different number of threads is very good too:
![Brute force vs B&B](data_analysis/algorithm_speedup_across_thread_counts.png)
## Implementation
...
## How to use TSS
...
\ No newline at end of file
After compiling the code on your machine you need to file the executable called tss.
We will be executing this file. If executed with no arguments or (-h, --help) the help window will show.
```bash
./tss --help
```
### Loading instances into program queue
As a first step, we need to load instances into a queue in the program and then solve them.
There are multiple ways to do this.
#### Load Instances
```bash
./tss -l "instance_name.dot"
```
This command will load instance from /files/instances folder.
#### Auto load Instances
```bash
./tss -a
```
This command will load all instances stored in the /files/instances folder.
#### Create Synthetic Instance
```bash
./tss -c 10
```
This command will create a synthetic instance, you need to specify how may nodes will the instance have.
The weight will be assigned randomly with ... The instance will then be loaded into queue.
### Solving loaded instances
#### Branch and Bound solve
```bash
./tss -s
```
This command will solve all instances in the queue with synchronous branch and bound algorithm.
#### Branch and Bound Parallel solve
```bash
./tss -p 8
```
This command will solve all instances in the queue with parallel branch and bound algo,
you need to specify the number of threads it can use.
#### Heuristic approximation
```bash
./tss -e
```
This command will let you approximate the solution using the Nearest neighbor & 2-Opt heuristic approach.
The same method the bb and bb-parallel uses to approximate the solution.
### Load and solve
```bash
./tss load solve
```
You need to load the instances at first and then pick a solving method.
An example will be:
```bash
./tss -a -p 10
```
\ No newline at end of file
data_analysis/algorithm_speedup_across_thread_counts.png

121 KiB | W: | H:

data_analysis/algorithm_speedup_across_thread_counts.png

118 KiB | W: | H:

data_analysis/algorithm_speedup_across_thread_counts.png
data_analysis/algorithm_speedup_across_thread_counts.png
data_analysis/algorithm_speedup_across_thread_counts.png
data_analysis/algorithm_speedup_across_thread_counts.png
  • 2-up
  • Swipe
  • Onion skin
data_analysis/brute_force_vs_branch_bound.png

105 KiB | W: | H:

data_analysis/brute_force_vs_branch_bound.png

104 KiB | W: | H:

data_analysis/brute_force_vs_branch_bound.png
data_analysis/brute_force_vs_branch_bound.png
data_analysis/brute_force_vs_branch_bound.png
data_analysis/brute_force_vs_branch_bound.png
  • 2-up
  • Swipe
  • Onion skin
source diff could not be displayed: it is too large. Options to address this: view the blob.
data_analysis/synchronized_vs_parallel_bb.png

132 KiB | W: | H:

data_analysis/synchronized_vs_parallel_bb.png

121 KiB | W: | H:

data_analysis/synchronized_vs_parallel_bb.png
data_analysis/synchronized_vs_parallel_bb.png
data_analysis/synchronized_vs_parallel_bb.png
data_analysis/synchronized_vs_parallel_bb.png
  • 2-up
  • Swipe
  • Onion skin
......@@ -63,8 +63,8 @@ void compare_brute_force_solve() {
}
void compare_bb_and_bb_parallel() {
int max_instance_size = 13;
int data_per_instance_size = 20;
int max_instance_size = 12;
int data_per_instance_size = 30;
for (int i = 3; i <= max_instance_size; i++) {
for (int j = 1; j <= data_per_instance_size; j++) {
......@@ -95,9 +95,9 @@ void compare_bb_and_bb_parallel() {
}
void compare_parallel_with_different_num_of_threads() {
int instance_size = 8;
int instance_size = 10;
size_t max_number_of_threads = std::thread::hardware_concurrency();
int data_per_algo = 20;
int data_per_algo = 100;
for (size_t j = 1; j <= data_per_algo; j++) {
std::cout << "K(" + std::to_string(instance_size) + ") num:" + std::to_string(j) << std::endl;
......@@ -114,9 +114,28 @@ void compare_parallel_with_different_num_of_threads() {
write_to_csv(data_to_csv, "comparing_different_num_of_threads.csv");
}
void compare_approximation_vs_exact_solution() {
int max_instance_size = 10;
int data_per_instance_size = 100;
for (size_t i = 4; i <= max_instance_size; i++) {
for (int j = 0; j < data_per_instance_size; j++) {
std::cout << "K(" + std::to_string(i) + ") num:" << j << std::endl;
std::unique_ptr<ts_instance> instance = helper::create_synthetic_instance(i);
auto approximation = instance->heuristic_combo();
instance->solve();
auto exact_solution = instance->get_min_cost();
data_to_csv.push_back(
std::to_string(i) + ", " + std::to_string(approximation) + ", " + std::to_string(exact_solution));
}
}
write_to_csv(data_to_csv, "approximation_vs_exact_solution.csv");
}
int main() {
set_stats_up();
compare_brute_force_solve();
compare_bb_and_bb_parallel();
compare_parallel_with_different_num_of_threads();
compare_approximation_vs_exact_solution();
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment