Skip to content

Added greedy algos #239

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions Competitive Coding/Greedy/KruskalMst/Kruskal.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#include<bits/stdc++.h>
using namespace std;
bool vis[100];
int arr[100],size[100];
#define piii pair<int,pair<int,int> >
class mycmp{
public:
bool operator()(piii p1,piii p2)
{
return p1.first>p2.first;
}
};
int root(int x)
{
while(arr[x]!=x)
{
arr[x]=arr[arr[x]];
x=arr[x];
}
return x;
}
bool find(int x,int y)
{
int rootx=root(x),rooty=root(y);
return rootx==rooty;
}
void union1(int x,int y)
{
int rootx=root(x);
int rooty=root(y);
if(size[rootx]<size[rooty])
{
arr[rootx]=rooty;
size[rooty]+=size[rootx];
}
else
{
arr[rooty]=rootx;
size[rootx]+=size[rooty];
}
}
int main()
{
printf("Enter no of vertices and no of edges\n");
int n,m,i;cin>>n>>m;
for(i=1;i<=n;i++)
{
arr[i]=i;
size[i]=1;
}
printf("Enter\nsrc dest weight\n");
priority_queue<piii,vector<piii>,mycmp>pq;
for(i=1;i<=m;i++)
{
int u,v,w;cin>>u>>v>>w;
pq.push({w,{u,v}});
}
int sum=0;
while(!pq.empty())
{
piii p=pq.top();
pq.pop();
int w=p.first,fir=p.second.first,sec=p.second.second;
if(find(fir,sec)==false)
{
sum+=w;
union1(fir,sec);
}
}
printf("weight of MST\n");
cout<<sum<<endl;
}
23 changes: 23 additions & 0 deletions Competitive Coding/Greedy/KruskalMst/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
Given a connected and undirected graph, a spanning tree of that graph is a subgraph that is a tree and connects all the vertices together. A single graph can have many different spanning trees. A minimum spanning tree (MST) or minimum weight spanning tree for a weighted, connected and undirected graph is a spanning tree with weight less than or equal to the weight of every other spanning tree. The weight of a spanning tree is the sum of weights given to each edge of the spanning tree.


Below are the steps for finding MST using Kruskal’s algorithm

1. Sort all the edges in non-decreasing order of their weight.
2. Pick the smallest edge. Check if it forms a cycle with the spanning tree formed so far. If cycle is not formed, include this edge. Else, discard it.
3. Repeat step#2 until there are (V-1) edges in the spanning tree.

The step#2 uses Union-Find algorithm to detect cycle.

The algorithm is a Greedy Algorithm. The Greedy Choice is to pick the smallest weight edge that does not cause a cycle in the MST constructed so far.


Example:
4 5
0 1 10
0 2 6
0 3 5
1 3 15
2 3 4

Output: 19
121 changes: 121 additions & 0 deletions Competitive Coding/Greedy/PrimMst/Prim.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
#include<iostream>
#include <vector>
#include <algorithm>
using namespace std;
// declare a class for graph

struct Edge{
int src,dest,weight;
};

class Graph{
int V,E;
vector<Edge> edge; // an array of all the edges
public:
Graph(int v, int e);
void addEdge(int src, int dest, int weight);
void mst();
};

Graph::Graph(int v, int e){
V=v;
E=e;
}

void Graph::addEdge(int src, int dest, int weight){
Edge *e= new Edge;
e->src= src;
e->dest= dest;
e->weight= weight;
edge.push_back(*e);
}
bool comp(Edge e1, Edge e2){
return e1.weight<e2.weight ;
}

struct subset{
int parent;
int rank;
};
// A utility function to find set of an element i
// (uses path compression technique)
int find(struct subset subsets[], int i){
// find root and make root as parent of i (path compression)
if (subsets[i].parent != i)
subsets[i].parent = find(subsets, subsets[i].parent);
return subsets[i].parent;
}

// A function that does union of two sets of x and y
// (uses union by rank)
void Union(struct subset subsets[], int x, int y)
{
int xroot = find(subsets, x);
int yroot = find(subsets, y);

// Attach smaller rank tree under root of high rank tree
// (Union by Rank)
if (subsets[xroot].rank < subsets[yroot].rank)
subsets[xroot].parent = yroot;
else if (subsets[xroot].rank > subsets[yroot].rank)
subsets[yroot].parent = xroot;
else
{
subsets[yroot].parent = xroot;
subsets[xroot].rank++;
}
}

void Graph::mst(){
sort(edge.begin(), edge.end(), comp);
//create disjoint set for all vertices
struct subset *subsets = new subset[V];

// Create V subsets with single elements
for(int i=0;i<V;i++){
subsets[i].parent = i;
subsets[i].rank = 0;
}
vector<Edge> result;

// Number of edges to be taken is equal to V-1
for(auto i=edge.begin(); i!=edge.end();i++){
int src= i->src;
int dest=i->dest;
//if not same root
if(find(subsets, src)!= find(subsets, dest)){
result.push_back(*i);
Union(subsets, src, dest);
}
}
printf("The edges of the MST are\n");
for(auto i=result.begin(); i!=result.end(); i++)
cout<<i->src<<"--"<<i->dest<<"="<<i->weight<<endl;
return;
}

int main(){
int V; // Number of vertices in graph
int E;
printf("Enter no of vertices and edges\n");
scanf("%d%d",&V,&E); // Number of edges in graph
Graph g(V,E);
int i,u,v,x;
printf("Enter\nsrc dest weight\n");
for(i=0;i<E;i++)
{
scanf("%d%d%d",&u,&v,&x);
g.addEdge(u,v,x);
}
// add edge 0-1
/*g.addEdge(0,3,1);
g.addEdge(4,5,2);
g.addEdge(2,4,5);
g.addEdge(3,4,6);
g.addEdge(0,1,3);
g.addEdge(1,2,1);
g.addEdge(2,3,1);
g.addEdge(1,3,3);
g.addEdge(2,5,4);*/
g.mst();
}
34 changes: 34 additions & 0 deletions Competitive Coding/Greedy/PrimMst/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
The idea behind Prim’s algorithm is simple, a spanning tree means all vertices must be connected. So the two disjoint subsets (discussed above) of vertices must be connected to make a Spanning Tree. And they must be connected with the minimum weight edge to make it a Minimum Spanning Tree.


Algorithm

1) Create a set mstSet that keeps track of vertices already included in MST.
2) Assign a key value to all vertices in the input graph. Initialize all key values as INFINITE. Assign key value as 0 for the first vertex so that it is picked first.
3) While mstSet doesn’t include all vertices
….a) Pick a vertex u which is not there in mstSet and has minimum key value.
….b) Include u to mstSet.
….c) Update key value of all adjacent vertices of u. To update the key values, iterate through all adjacent vertices. For every adjacent vertex v, if weight of edge u-v is less than the previous key value of v, update the key value as weight of u-v.


The idea of using key values is to pick the minimum weight edge from cut. The key values are used only for vertices which are not yet included in MST, the key value for these vertices indicate the minimum weight edges connecting them to the set of vertices included in MST.

Example:
6 9
0 3 1
4 5 2
2 4 5
3 4 6
0 1 3
1 2 1
2 3 1
1 3 3
2 5 4


Output :
0--3=1
1--2=1
2--3=1
4--5=2
2--5=4
16 changes: 16 additions & 0 deletions Competitive Coding/Greedy/activitySelection/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
You are given n activities with their start and finish times. Select the maximum number of activities that can be performed by a single person, assuming that a person can only work on a single activity at a time.

The greedy choice is to always pick the next activity whose finish time is least among the remaining activities and the start time is more than or equal to the finish time of previously selected activity. We can sort the activities according to their finishing time so that we always consider the next activity as minimum finishing time activity.

1) Sort the activities according to their finishing time
2) Select the first activity from the sorted array and print it.
3) Do following for remaining activities in the sorted array.
…….a) If the start time of this activity is greater than or equal to the finish time of previously selected activity then select this activity and print it.

Example:
6
1 3 0 5 8 5
2 4 6 7 9 9

Output:
selected activities are 0 1 3 4
38 changes: 38 additions & 0 deletions Competitive Coding/Greedy/activitySelection/activitySelection.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#include<stdio.h>

void selection(int s[], int f[], int n)
{
int i, j;
i = 0;
printf("%d ", i);

for (j = 1; j < n; j++)
{
if (s[j] >= f[i])
{
printf ("%d ", j);
i = j;
}
}
}

int main()
{
int n;
printf("Enter no of activities\n");
scanf("%d",&n);
int s[n],f[n],i;
printf("Enter the start times of the activities\n");
for(i=0;i<n;i++)
{
scanf("%d",&s[i]);
}
printf("Enter the finish times of the actvities\n");
for(i=0;i<n;i++)
{
scanf("%d",&f[i]);
}
printf("Following activities are selected\n");
selection(s, f, n);
return 0;
}
43 changes: 43 additions & 0 deletions Competitive Coding/Greedy/huffmanCoding/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
Huffman coding is a lossless data compression algorithm. The idea is to assign variable-length codes to input characters, lengths of the assigned codes are based on the frequencies of corresponding characters. The most frequent character gets the smallest code and the least frequent character gets the largest code.
The variable-length codes assigned to input characters are Prefix Codes, means the codes (bit sequences) are assigned in such a way that the code assigned to one character is not prefix of code assigned to any other character. This is how Huffman Coding makes sure that there is no ambiguity when decoding the generated bit stream.

There are mainly two major parts in Huffman Coding
1) Build a Huffman Tree from input characters.
2) Traverse the Huffman Tree and assign codes to characters.


Steps to build Huffman Tree:

a) Input is array of unique characters along with their frequency of occurrences and output is Huffman Tree.

1. Create a leaf node for each unique character and build a min heap of all leaf nodes (Min Heap is used as a priority queue. The value of frequency field is used to compare two nodes in min heap. Initially, the least frequent character is at root)

2. Extract two nodes with the minimum frequency from the min heap.

3. Create a new internal node with frequency equal to the sum of the two nodes frequencies. Make the first extracted node as its left child and the other extracted node as its right child. Add this node to the min heap.

4. Repeat steps #2 and #3 until the heap contains only one node. The remaining node is the root node and the tree is complete.

b) Steps to print codes from Huffman Tree:

Traverse the tree formed starting from the root. Maintain an auxiliary array. While moving to the left child, write 0 to the array. While moving to the right child, write 1 to the array. Print the array when a leaf node is encountered.



Example:
6
a 5
b 9
c 12
d 13
e 16
f 45

Output:
character code-word
f 0
c 100
d 101
a 1100
b 1101
e 111
Loading