diff --git a/Graph algorithm/BellmanFord.cpp b/Graph algorithm/BellmanFord.cpp new file mode 100644 index 0000000..7c221fa --- /dev/null +++ b/Graph algorithm/BellmanFord.cpp @@ -0,0 +1,89 @@ +//Snehal Kumar +#include + +// a structure to represent a weighted edge in graph +struct Edge { + int src, dest, weight; +}; + +// a structure to represent a connected, directed and +// weighted graph +struct Graph { + int V, E; + struct Edge* edge; +}; + +// Creates a graph with V vertices and E edges +struct Graph* createGraph(int V, int E) +{ + struct Graph* graph = new Graph; + graph->V = V; + graph->E = E; + graph->edge = new Edge[E]; + return graph; +} + +void printArr(int dist[], int n) +{ + printf("Vertex Distance from Source\n"); + for (int i = 0; i < n; ++i) + printf("%d \t\t %d\n", i, dist[i]); +} + + +void BellmanFord(struct Graph* graph, int src) +{ + int V = graph->V; + int E = graph->E; + int dist[V]; + + // Initialize distances as INFINITE + for (int i = 0; i < V; i++) + dist[i] = INT_MAX; + dist[src] = 0; + + // Relax the edges + for (int i = 1; i <= V - 1; i++) { + for (int j = 0; j < E; j++) { + int u = graph->edge[j].src; + int v = graph->edge[j].dest; + int weight = graph->edge[j].weight; + if (dist[u] != INT_MAX && dist[u] + weight < dist[v]) + dist[v] = dist[u] + weight; + } + } + + // check for negative-weight cycles + for (int i = 0; i < E; i++) { + int u = graph->edge[i].src; + int v = graph->edge[i].dest; + int weight = graph->edge[i].weight; + if (dist[u] != INT_MAX && dist[u] + weight < dist[v]) { + printf("Graph contains negative weight cycle"); + return; + } + } + + printArr(dist, V); + + return; +} + +// Driver program to test above functions +int main() +{ + int V = 5; // Number of vertices in graph + int E = 8; // Number of edges in graph + struct Graph* graph = createGraph(V, E); + for(int i=0;iedge[i].src = a; + graph->edge[i].dest = b; + graph->edge[i].weight = w; + } + BellmanFord(graph, 0); + + return 0; +} \ No newline at end of file diff --git a/Graph algorithm/BellmanFord.py b/Graph algorithm/BellmanFord.py new file mode 100644 index 0000000..7796468 --- /dev/null +++ b/Graph algorithm/BellmanFord.py @@ -0,0 +1,53 @@ +#Snehal Kumar +#Python program for Bellman Ford +class Graph: + + def __init__(self, vertices): + self.V = vertices # No. of vertices + self.graph = [] + + # function to add an edge to graph + def addEdge(self, u, v, w): + self.graph.append([u, v, w]) + + # utility function used to print the solution + def printArr(self, dist): + print("Vertex Distance from Source") + for i in range(self.V): + print("{0}\t\t{1}".format(i, dist[i])) + + # The main function that finds shortest distances + def BellmanFord(self, src): + + # Initialize distances as INFINITE + dist = [float("Inf")] * self.V + dist[src] = 0 + + + # Relax all edges + for _ in range(self.V - 1): + # Update dist value and parent index of the adjacent vertices + for u, v, w in self.graph: + if dist[u] != float("Inf") and dist[u] + w < dist[v]: + dist[v] = dist[u] + w + + # Check for negative-weight cycles. + for u, v, w in self.graph: + if dist[u] != float("Inf") and dist[u] + w < dist[v]: + print("Graph contains negative weight cycle") + return + + self.printArr(dist) + +g = Graph(5) +g.addEdge(0, 1, -1) +g.addEdge(0, 2, 4) +g.addEdge(1, 2, 3) +g.addEdge(1, 3, 2) +g.addEdge(1, 4, 2) +g.addEdge(3, 2, 5) +g.addEdge(3, 1, 1) +g.addEdge(4, 3, -3) + +# Print the solution +g.BellmanFord(0) \ No newline at end of file diff --git a/Greedy Algorithms/dijkstra_adjlist.cpp b/Greedy Algorithms/dijkstra_adjlist.cpp new file mode 100644 index 0000000..93c65a1 --- /dev/null +++ b/Greedy Algorithms/dijkstra_adjlist.cpp @@ -0,0 +1,304 @@ +#include +#include +#include + +// A structure to represent a node in adjacency list +struct AdjListNode +{ + int dest; + int weight; + struct AdjListNode* next; +}; + +// A structure to represent an adjacency list +struct AdjList +{ + struct AdjListNode *head; // pointer to head node of list +}; + +// A structure to represent a graph. A graph is an array of adjacency lists. +// Size of array will be V (number of vertices in graph) +struct Graph +{ + int V; + struct AdjList* array; +}; + +// A utility function to create a new adjacency list node +struct AdjListNode* newAdjListNode(int dest, int weight) +{ + struct AdjListNode* newNode = + (struct AdjListNode*) malloc(sizeof(struct AdjListNode)); + newNode->dest = dest; + newNode->weight = weight; + newNode->next = NULL; + return newNode; +} + +// A utility function that creates a graph of V vertices +struct Graph* createGraph(int V) +{ + struct Graph* graph = (struct Graph*) malloc(sizeof(struct Graph)); + graph->V = V; + + // Create an array of adjacency lists. Size of array will be V + graph->array = (struct AdjList*) malloc(V * sizeof(struct AdjList)); + + // Initialize each adjacency list as empty by making head as NULL + for (int i = 0; i < V; ++i) + graph->array[i].head = NULL; + + return graph; +} + +// Adds an edge to an undirected graph +void addEdge(struct Graph* graph, int src, int dest, int weight) +{ + // Add an edge from src to dest. A new node is added to the adjacency + // list of src. The node is added at the beginning + struct AdjListNode* newNode = newAdjListNode(dest, weight); + newNode->next = graph->array[src].head; + graph->array[src].head = newNode; + + // Since graph is undirected, add an edge from dest to src also + newNode = newAdjListNode(src, weight); + newNode->next = graph->array[dest].head; + graph->array[dest].head = newNode; +} + +// Structure to represent a min heap node +struct MinHeapNode +{ + int v; + int dist; +}; + +// Structure to represent a min heap +struct MinHeap +{ + int size; // Number of heap nodes present currently + int capacity; // Capacity of min heap + int *pos; // This is needed for decreaseKey() + struct MinHeapNode **array; +}; + +// A utility function to create a new Min Heap Node +struct MinHeapNode* newMinHeapNode(int v, int dist) +{ + struct MinHeapNode* minHeapNode = + (struct MinHeapNode*) malloc(sizeof(struct MinHeapNode)); + minHeapNode->v = v; + minHeapNode->dist = dist; + return minHeapNode; +} + +// A utility function to create a Min Heap +struct MinHeap* createMinHeap(int capacity) +{ + struct MinHeap* minHeap = + (struct MinHeap*) malloc(sizeof(struct MinHeap)); + minHeap->pos = (int *)malloc(capacity * sizeof(int)); + minHeap->size = 0; + minHeap->capacity = capacity; + minHeap->array = + (struct MinHeapNode**) malloc(capacity * sizeof(struct MinHeapNode*)); + return minHeap; +} + +// A utility function to swap two nodes of min heap. Needed for min heapify +void swapMinHeapNode(struct MinHeapNode** a, struct MinHeapNode** b) +{ + struct MinHeapNode* t = *a; + *a = *b; + *b = t; +} + +// A standard function to heapify at given idx +// This function also updates position of nodes when they are swapped. +// Position is needed for decreaseKey() +void minHeapify(struct MinHeap* minHeap, int idx) +{ + int smallest, left, right; + smallest = idx; + left = 2 * idx + 1; + right = 2 * idx + 2; + + if (left < minHeap->size && + minHeap->array[left]->dist < minHeap->array[smallest]->dist ) + smallest = left; + + if (right < minHeap->size && + minHeap->array[right]->dist < minHeap->array[smallest]->dist ) + smallest = right; + + if (smallest != idx) + { + // The nodes to be swapped in min heap + MinHeapNode *smallestNode = minHeap->array[smallest]; + MinHeapNode *idxNode = minHeap->array[idx]; + + // Swap positions + minHeap->pos[smallestNode->v] = idx; + minHeap->pos[idxNode->v] = smallest; + + // Swap nodes + swapMinHeapNode(&minHeap->array[smallest], &minHeap->array[idx]); + + minHeapify(minHeap, smallest); + } +} + +// A utility function to check if the given minHeap is ampty or not +int isEmpty(struct MinHeap* minHeap) +{ + return minHeap->size == 0; +} + +// Standard function to extract minimum node from heap +struct MinHeapNode* extractMin(struct MinHeap* minHeap) +{ + if (isEmpty(minHeap)) + return NULL; + + // Store the root node + struct MinHeapNode* root = minHeap->array[0]; + + // Replace root node with last node + struct MinHeapNode* lastNode = minHeap->array[minHeap->size - 1]; + minHeap->array[0] = lastNode; + + // Update position of last node + minHeap->pos[root->v] = minHeap->size-1; + minHeap->pos[lastNode->v] = 0; + + // Reduce heap size and heapify root + --minHeap->size; + minHeapify(minHeap, 0); + + return root; +} + +// Function to decreasy dist value of a given vertex v. This function +// uses pos[] of min heap to get the current index of node in min heap +void decreaseKey(struct MinHeap* minHeap, int v, int dist) +{ + // Get the index of v in heap array + int i = minHeap->pos[v]; + + // Get the node and update its dist value + minHeap->array[i]->dist = dist; + + // Travel up while the complete tree is not hepified. + // This is a O(Logn) loop + while (i && minHeap->array[i]->dist < minHeap->array[(i - 1) / 2]->dist) + { + // Swap this node with its parent + minHeap->pos[minHeap->array[i]->v] = (i-1)/2; + minHeap->pos[minHeap->array[(i-1)/2]->v] = i; + swapMinHeapNode(&minHeap->array[i], &minHeap->array[(i - 1) / 2]); + + // move to parent index + i = (i - 1) / 2; + } +} + +// A utility function to check if a given vertex +// 'v' is in min heap or not +bool isInMinHeap(struct MinHeap *minHeap, int v) +{ + if (minHeap->pos[v] < minHeap->size) + return true; + return false; +} + +// A utility function used to print the solution +void printArr(int dist[], int n) +{ + printf("Vertex Distance from Source\n"); + for (int i = 0; i < n; ++i) + printf("%d \t\t %d\n", i, dist[i]); +} + +// The main function that calulates distances of shortest paths from src to all +// vertices. It is a O(ELogV) function +void dijkstra(struct Graph* graph, int src) +{ + int V = graph->V;// Get the number of vertices in graph + int dist[V]; // dist values used to pick minimum weight edge in cut + + // minHeap represents set E + struct MinHeap* minHeap = createMinHeap(V); + + // Initialize min heap with all vertices. dist value of all vertices + for (int v = 0; v < V; ++v) + { + dist[v] = INT_MAX; + minHeap->array[v] = newMinHeapNode(v, dist[v]); + minHeap->pos[v] = v; + } + + // Make dist value of src vertex as 0 so that it is extracted first + minHeap->array[src] = newMinHeapNode(src, dist[src]); + minHeap->pos[src] = src; + dist[src] = 0; + decreaseKey(minHeap, src, dist[src]); + + // Initially size of min heap is equal to V + minHeap->size = V; + + // In the followin loop, min heap contains all nodes + // whose shortest distance is not yet finalized. + while (!isEmpty(minHeap)) + { + // Extract the vertex with minimum distance value + struct MinHeapNode* minHeapNode = extractMin(minHeap); + int u = minHeapNode->v; // Store the extracted vertex number + + // Traverse through all adjacent vertices of u (the extracted + // vertex) and update their distance values + struct AdjListNode* pCrawl = graph->array[u].head; + while (pCrawl != NULL) + { + int v = pCrawl->dest; + + // If shortest distance to v is not finalized yet, and distance to v + // through u is less than its previously calculated distance + if (isInMinHeap(minHeap, v) && dist[u] != INT_MAX && + pCrawl->weight + dist[u] < dist[v]) + { + dist[v] = dist[u] + pCrawl->weight; + + // update distance value in min heap also + decreaseKey(minHeap, v, dist[v]); + } + pCrawl = pCrawl->next; + } + } + + // print the calculated shortest distances + printArr(dist, V); +} +int main() +{ + // create the graph given in above fugure + int V = 9; + struct Graph* graph = createGraph(V); + addEdge(graph, 0, 1, 4); + addEdge(graph, 0, 7, 8); + addEdge(graph, 1, 2, 8); + addEdge(graph, 1, 7, 11); + addEdge(graph, 2, 3, 7); + addEdge(graph, 2, 8, 2); + addEdge(graph, 2, 5, 4); + addEdge(graph, 3, 4, 9); + addEdge(graph, 3, 5, 14); + addEdge(graph, 4, 5, 10); + addEdge(graph, 5, 6, 2); + addEdge(graph, 6, 7, 1); + addEdge(graph, 6, 8, 6); + addEdge(graph, 7, 8, 7); + + dijkstra(graph, 0); + + return 0; +} \ No newline at end of file diff --git a/Greedy Algorithms/dijkstra_stl.cpp b/Greedy Algorithms/dijkstra_stl.cpp new file mode 100644 index 0000000..23cdad2 --- /dev/null +++ b/Greedy Algorithms/dijkstra_stl.cpp @@ -0,0 +1,123 @@ +#include +using namespace std; +# define INF 0x3f3f3f3f + +// iPair ==> Integer Pair +typedef pair iPair; + +// This class represents a directed graph using +// adjacency list representation +class Graph +{ + int V; // No. of vertices + + // In a weighted graph, we need to store vertex + // and weight pair for every edge + list< pair > *adj; + +public: + Graph(int V); // Constructor + + // function to add an edge to graph + void addEdge(int u, int v, int w); + + // prints shortest path from s + void shortestPath(int s); +}; + +// Allocates memory for adjacency list +Graph::Graph(int V) +{ + this->V = V; + adj = new list [V]; +} + +void Graph::addEdge(int u, int v, int w) +{ + adj[u].push_back(make_pair(v, w)); + adj[v].push_back(make_pair(u, w)); +} + +// Prints shortest paths from src to all other vertices +void Graph::shortestPath(int src) +{ + // Create a priority queue to store vertices that + // are being preprocessed. This is weird syntax in C++. + // Refer below link for details of this syntax + // https://www.geeksforgeeks.org/implement-min-heap-using-stl/ + priority_queue< iPair, vector , greater > pq; + + // Create a vector for distances and initialize all + // distances as infinite (INF) + vector dist(V, INF); + + // Insert source itself in priority queue and initialize + // its distance as 0. + pq.push(make_pair(0, src)); + dist[src] = 0; + + /* Looping till priority queue becomes empty (or all + distances are not finalized) */ + while (!pq.empty()) + { + // The first vertex in pair is the minimum distance + // vertex, extract it from priority queue. + // vertex label is stored in second of pair (it + // has to be done this way to keep the vertices + // sorted distance (distance must be first item + // in pair) + int u = pq.top().second; + pq.pop(); + + // 'i' is used to get all adjacent vertices of a vertex + list< pair >::iterator i; + for (i = adj[u].begin(); i != adj[u].end(); ++i) + { + // Get vertex label and weight of current adjacent + // of u. + int v = (*i).first; + int weight = (*i).second; + + // If there is shorted path to v through u. + if (dist[v] > dist[u] + weight) + { + // Updating distance of v + dist[v] = dist[u] + weight; + pq.push(make_pair(dist[v], v)); + } + } + } + + // Print shortest distances stored in dist[] + printf("Vertex Distance from Source\n"); + for (int i = 0; i < V; ++i) + printf("%d \t\t %d\n", i, dist[i]); +} + +// Driver program to test methods of graph class +int main() +{ + // create the graph given in above fugure + int V = 9; + Graph g(V); + + // making above shown graph + g.addEdge(0, 1, 4); + g.addEdge(0, 7, 8); + g.addEdge(1, 2, 8); + g.addEdge(1, 7, 11); + g.addEdge(2, 3, 7); + g.addEdge(2, 8, 2); + g.addEdge(2, 5, 4); + g.addEdge(3, 4, 9); + g.addEdge(3, 5, 14); + g.addEdge(4, 5, 10); + g.addEdge(5, 6, 2); + g.addEdge(6, 7, 1); + g.addEdge(6, 8, 6); + g.addEdge(7, 8, 7); + + g.shortestPath(0); + + return 0; +} \ No newline at end of file diff --git a/Greedy Algorithms/kruskal.py b/Greedy Algorithms/kruskal.py new file mode 100644 index 0000000..771a274 --- /dev/null +++ b/Greedy Algorithms/kruskal.py @@ -0,0 +1,102 @@ +# Snehal Kumar +# Python program for Kruskal's algorithm to find +# Minimum Spanning Tree of a given connected, +# undirected and weighted graph + +from collections import defaultdict + +#Class to represent a graph +class Graph: + + def __init__(self,vertices): + self.V= vertices #No. of vertices + self.graph = [] # default dictionary + # to store graph + + + # function to add an edge to graph + def addEdge(self,u,v,w): + self.graph.append([u,v,w]) + + # A utility function to find set of an element i + # (uses path compression technique) + def find(self, parent, i): + if parent[i] == i: + return i + return self.find(parent, parent[i]) + + # A function that does union of two sets of x and y + # (uses union by rank) + def union(self, parent, rank, x, y): + xroot = self.find(parent, x) + yroot = self.find(parent, y) + + # Attach smaller rank tree under root of + # high rank tree (Union by Rank) + if rank[xroot] < rank[yroot]: + parent[xroot] = yroot + elif rank[xroot] > rank[yroot]: + parent[yroot] = xroot + + # If ranks are same, then make one as root + # and increment its rank by one + else : + parent[yroot] = xroot + rank[xroot] += 1 + + # The main function to construct MST using Kruskal's + # algorithm + def KruskalMST(self): + + result =[] #This will store the resultant MST + + i = 0 # An index variable, used for sorted edges + e = 0 # An index variable, used for result[] + + # Step 1: Sort all the edges in non-decreasing + # order of their + # weight. If we are not allowed to change the + # given graph, we can create a copy of graph + self.graph = sorted(self.graph,key=lambda item: item[2]) + + parent = [] ; rank = [] + + # Create V subsets with single elements + for node in range(self.V): + parent.append(node) + rank.append(0) + + # Number of edges to be taken is equal to V-1 + while e < self.V -1 : + + # Step 2: Pick the smallest edge and increment + # the index for next iteration + u,v,w = self.graph[i] + i = i + 1 + x = self.find(parent, u) + y = self.find(parent ,v) + + # If including this edge does't cause cycle, + # include it in result and increment the index + # of result for next edge + if x != y: + e = e + 1 + result.append([u,v,w]) + self.union(parent, rank, x, y) + # Else discard the edge + + # print the contents of result[] to display the built MST + print ("Following are the edges in the constructed MST") + for u,v,weight in result: + #print str(u) + " -- " + str(v) + " == " + str(weight) + print ("%d -- %d == %d" % (u,v,weight)) + +# Driver code +g = Graph(4) +g.addEdge(0, 1, 10) +g.addEdge(0, 2, 6) +g.addEdge(0, 3, 5) +g.addEdge(1, 3, 15) +g.addEdge(2, 3, 4) + +g.KruskalMST() \ No newline at end of file