Skip to content

Commit 5b23872

Browse files
AshishYUOashishdaulatabadgithub-actions[bot]Panquesito7
authored
feat: add Strassen's Matrix Multiplication (#2413)
* Feat: Add Strassen's matrix multiplication * updating DIRECTORY.md * Fix cpp lint error * updating DIRECTORY.md * clang-format and clang-tidy fixes for 02439b5 * Fix windows error * Add namespaces * updating DIRECTORY.md * Proper documentation * Reduce the matrix size. * updating DIRECTORY.md * clang-format and clang-tidy fixes for 0545555 Co-authored-by: toastedbreadandomelette <[email protected]> Co-authored-by: github-actions[bot] <[email protected]> Co-authored-by: David Leal <[email protected]>
1 parent a6a9d8e commit 5b23872

File tree

6 files changed

+764
-260
lines changed

6 files changed

+764
-260
lines changed

DIRECTORY.md

+4
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282

8383
## Divide And Conquer
8484
* [Karatsuba Algorithm For Fast Multiplication](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/divide_and_conquer/karatsuba_algorithm_for_fast_multiplication.cpp)
85+
* [Strassen Matrix Multiplication](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/divide_and_conquer/strassen_matrix_multiplication.cpp)
8586

8687
## Dynamic Programming
8788
* [0 1 Knapsack](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/dynamic_programming/0_1_knapsack.cpp)
@@ -110,6 +111,7 @@
110111
* [Partition Problem](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/dynamic_programming/partition_problem.cpp)
111112
* [Searching Of Element In Dynamic Array](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/dynamic_programming/searching_of_element_in_dynamic_array.cpp)
112113
* [Shortest Common Supersequence](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/dynamic_programming/shortest_common_supersequence.cpp)
114+
* [Subset Sum](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/dynamic_programming/subset_sum.cpp)
113115
* [Tree Height](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/dynamic_programming/tree_height.cpp)
114116
* [Word Break](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/dynamic_programming/word_break.cpp)
115117

@@ -146,6 +148,7 @@
146148
* [Spirograph](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/graphics/spirograph.cpp)
147149

148150
## Greedy Algorithms
151+
* [Boruvkas Minimum Spanning Tree](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/greedy_algorithms/boruvkas_minimum_spanning_tree.cpp)
149152
* [Dijkstra](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/greedy_algorithms/dijkstra.cpp)
150153
* [Huffman](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/greedy_algorithms/huffman.cpp)
151154
* [Jumpgame](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/greedy_algorithms/jumpgame.cpp)
@@ -171,6 +174,7 @@
171174
* [Vector Ops](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/machine_learning/vector_ops.hpp)
172175

173176
## Math
177+
* [Aliquot Sum](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/math/aliquot_sum.cpp)
174178
* [Approximate Pi](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/math/approximate_pi.cpp)
175179
* [Area](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/math/area.cpp)
176180
* [Armstrong Number](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/math/armstrong_number.cpp)

bit_manipulation/travelling_salesman_using_bit_manipulation.cpp

+67-45
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,26 @@
55
* (https://www.geeksforgeeks.org/travelling-salesman-problem-set-1/)
66
*
77
* @details
8-
* Given the distance/cost(as and adjacency matrix) between each city/node to the other city/node ,
9-
* the problem is to find the shortest possible route that visits every city exactly once
10-
* and returns to the starting point or we can say the minimum cost of whole tour.
8+
* Given the distance/cost(as and adjacency matrix) between each city/node to
9+
* the other city/node , the problem is to find the shortest possible route that
10+
* visits every city exactly once and returns to the starting point or we can
11+
* say the minimum cost of whole tour.
1112
*
1213
* Explanation:
13-
* INPUT -> You are given with a adjacency matrix A = {} which contains the distance between two cities/node.
14+
* INPUT -> You are given with a adjacency matrix A = {} which contains the
15+
* distance between two cities/node.
1416
*
1517
* OUTPUT -> Minimum cost of whole tour from starting point
1618
*
1719
* Worst Case Time Complexity: O(n^2 * 2^n)
1820
* Space complexity: O(n)
1921
* @author [Utkarsh Yadav](https://github.com/Rytnix)
2022
*/
21-
#include <algorithm> /// for std::min
23+
#include <algorithm> /// for std::min
2224
#include <cassert> /// for assert
23-
#include <iostream> /// for IO operations
24-
#include <vector> /// for std::vector
25-
#include <limits> /// for limits of integral types
25+
#include <iostream> /// for IO operations
26+
#include <limits> /// for limits of integral types
27+
#include <vector> /// for std::vector
2628

2729
/**
2830
* @namespace bit_manipulation
@@ -42,40 +44,53 @@ namespace travelling_salesman_using_bit_manipulation {
4244
* @param setOfCitites represents the city in bit form.\
4345
* @param city is taken to track the current city movement.
4446
* @param n is the no of citys .
45-
* @param dp vector is used to keep a record of state to avoid the recomputation.
46-
* @returns minimum cost of traversing whole nodes/cities from starting point back to starting point
47+
* @param dp vector is used to keep a record of state to avoid the
48+
* recomputation.
49+
* @returns minimum cost of traversing whole nodes/cities from starting point
50+
* back to starting point
4751
*/
48-
std::uint64_t travelling_salesman_using_bit_manipulation(std::vector<std::vector<uint32_t>> dist, // dist is the adjacency matrix containing the distance.
49-
// setOfCities as a bit represent the cities/nodes. Ex: if setOfCities = 2 => 0010(in binary)
50-
// means representing the city/node B if city/nodes are represented as D->C->B->A.
51-
std::uint64_t setOfCities,
52-
std::uint64_t city, // city is taken to track our current city/node movement,where we are currently.
53-
std::uint64_t n, // n is the no of cities we have.
54-
std::vector<std::vector<uint32_t>> &dp) //dp is taken to memorize the state to avoid recomputition
52+
std::uint64_t travelling_salesman_using_bit_manipulation(
53+
std::vector<std::vector<uint32_t>>
54+
dist, // dist is the adjacency matrix containing the distance.
55+
// setOfCities as a bit represent the cities/nodes. Ex: if
56+
// setOfCities = 2 => 0010(in binary) means representing the
57+
// city/node B if city/nodes are represented as D->C->B->A.
58+
std::uint64_t setOfCities,
59+
std::uint64_t city, // city is taken to track our current city/node
60+
// movement,where we are currently.
61+
std::uint64_t n, // n is the no of cities we have.
62+
std::vector<std::vector<uint32_t>>
63+
&dp) // dp is taken to memorize the state to avoid recomputition
5564
{
56-
//base case;
57-
if (setOfCities == (1 << n) - 1) // we have covered all the cities
58-
return dist[city][0]; //return the cost from the current city to the original city.
65+
// base case;
66+
if (setOfCities == (1 << n) - 1) { // we have covered all the cities
67+
return dist[city][0]; // return the cost from the current city to the
68+
// original city.
69+
}
5970

60-
if (dp[setOfCities][city] != -1)
71+
if (dp[setOfCities][city] != -1) {
6172
return dp[setOfCities][city];
62-
//otherwise try all possible options
63-
uint64_t ans = 2147483647 ;
73+
}
74+
// otherwise try all possible options
75+
uint64_t ans = 2147483647;
6476
for (int choice = 0; choice < n; choice++) {
65-
//check if the city is visited or not.
66-
if ((setOfCities & (1 << choice)) == 0 ) { // this means that this perticular city is not visited.
67-
std::uint64_t subProb = dist[city][choice] + travelling_salesman_using_bit_manipulation(dist, setOfCities | (1 << choice), choice, n, dp);
68-
// Here we are doing a recursive call to tsp with the updated set of city/node
69-
// and choice which tells that where we are currently.
77+
// check if the city is visited or not.
78+
if ((setOfCities & (1 << choice)) ==
79+
0) { // this means that this perticular city is not visited.
80+
std::uint64_t subProb =
81+
dist[city][choice] +
82+
travelling_salesman_using_bit_manipulation(
83+
dist, setOfCities | (1 << choice), choice, n, dp);
84+
// Here we are doing a recursive call to tsp with the updated set of
85+
// city/node and choice which tells that where we are currently.
7086
ans = std::min(ans, subProb);
7187
}
72-
7388
}
7489
dp[setOfCities][city] = ans;
7590
return ans;
7691
}
77-
} // namespace travelling_salesman_using_bit_manipulation
78-
} // namespace bit_manipulation
92+
} // namespace travelling_salesman_using_bit_manipulation
93+
} // namespace bit_manipulation
7994

8095
/**
8196
* @brief Self-test implementations
@@ -84,29 +99,36 @@ std::uint64_t travelling_salesman_using_bit_manipulation(std::vector<std::vector
8499
static void test() {
85100
// 1st test-case
86101
std::vector<std::vector<uint32_t>> dist = {
87-
{0, 20, 42, 35}, {20, 0, 30, 34}, {42, 30, 0, 12}, {35, 34, 12, 0}
88-
};
102+
{0, 20, 42, 35}, {20, 0, 30, 34}, {42, 30, 0, 12}, {35, 34, 12, 0}};
89103
uint32_t V = dist.size();
90104
std::vector<std::vector<uint32_t>> dp(1 << V, std::vector<uint32_t>(V, -1));
91-
assert(bit_manipulation::travelling_salesman_using_bit_manipulation::travelling_salesman_using_bit_manipulation(dist, 1, 0, V, dp) == 97);
92-
std::cout << "1st test-case: passed!" << "\n";
105+
assert(bit_manipulation::travelling_salesman_using_bit_manipulation::
106+
travelling_salesman_using_bit_manipulation(dist, 1, 0, V, dp) ==
107+
97);
108+
std::cout << "1st test-case: passed!"
109+
<< "\n";
93110

94111
// 2nd test-case
95112
dist = {{0, 5, 10, 15}, {5, 0, 20, 30}, {10, 20, 0, 35}, {15, 30, 35, 0}};
96113
V = dist.size();
97-
std::vector<std::vector<uint32_t>> dp1(1 << V, std::vector<uint32_t>(V, -1));
98-
assert(bit_manipulation::travelling_salesman_using_bit_manipulation::travelling_salesman_using_bit_manipulation(dist, 1, 0, V, dp1) == 75);
99-
std::cout << "2nd test-case: passed!" << "\n";
114+
std::vector<std::vector<uint32_t>> dp1(1 << V,
115+
std::vector<uint32_t>(V, -1));
116+
assert(bit_manipulation::travelling_salesman_using_bit_manipulation::
117+
travelling_salesman_using_bit_manipulation(dist, 1, 0, V, dp1) ==
118+
75);
119+
std::cout << "2nd test-case: passed!"
120+
<< "\n";
100121
// 3rd test-case
101-
dist = {
102-
{0, 10, 15, 20}, {10, 0, 35, 25}, {15, 35, 0, 30}, {20, 25, 30, 0}
103-
};
122+
dist = {{0, 10, 15, 20}, {10, 0, 35, 25}, {15, 35, 0, 30}, {20, 25, 30, 0}};
104123
V = dist.size();
105-
std::vector<std::vector<uint32_t>> dp2(1 << V, std::vector<uint32_t>(V, -1));
106-
assert(bit_manipulation::travelling_salesman_using_bit_manipulation::travelling_salesman_using_bit_manipulation(dist, 1, 0, V, dp2) == 80);
107-
108-
std::cout << "3rd test-case: passed!" << "\n";
124+
std::vector<std::vector<uint32_t>> dp2(1 << V,
125+
std::vector<uint32_t>(V, -1));
126+
assert(bit_manipulation::travelling_salesman_using_bit_manipulation::
127+
travelling_salesman_using_bit_manipulation(dist, 1, 0, V, dp2) ==
128+
80);
109129

130+
std::cout << "3rd test-case: passed!"
131+
<< "\n";
110132
}
111133

112134
/**

0 commit comments

Comments
 (0)