Skip to content

Added greedy algorithms #248

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

Closed
wants to merge 4 commits into from
Closed
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;
}
23 changes: 23 additions & 0 deletions Competitive Coding/Greedy/jobSequencing/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
Given an array of jobs where every job has a deadline and associated profit if the job is finished before the deadline. It is also given that every job takes single unit of time, so the minimum possible deadline for any job is 1. How to maximize total profit if only one job can be scheduled at a time.


A Simple Solution is to generate all subsets of given set of jobs and check individual subset for feasibility of jobs in that subset. Keep track of maximum profit among all feasible subsets. The time complexity of this solution is exponential.

This is a standard Greedy Algorithm problem. Following is algorithm.

1) Sort all jobs in decreasing order of profit.
2) Initialize the result sequence as first job in sorted jobs.
3) Do following for remaining n-1 jobs
.......a) If the current job can fit in the current result sequence
without missing the deadline, add current job to the result.
Else ignore the current job.

Example:
4
a 4 20
b 1 10
c 1 40
d 1 30

Output:
c a
51 changes: 51 additions & 0 deletions Competitive Coding/Greedy/jobSequencing/jobSequencing.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#include <iostream>
#include <algorithm>
using namespace std;

struct job
{
char title;
int dead;
int profit;
};

bool compare(job a,job b)
{
return (a.profit > b.profit);
}

int main()
{
int n;
printf("Example Input:\n");
printf("4\n");
printf("a 4 20\n");
printf("b 1 10\n");
printf("c 1 40\n");
printf("d 1 30\n");
printf("Enter no of activities\n");
cin>>n;
job j[n];
printf("Enter\n");
printf("JobID Deadline Profit\n");
for(int i=0;i<n;i++) //user input
{
cin>>j[i].title;
cin>>j[i].dead;
cin>>j[i].profit;
}
sort(j,j+n,compare);
printf("Max sequence of jobs is\n");

cout<<j[0].title<<" "; //selecting the first job with highest profit
int count=1; //count of number of jobs completed
for(int i=1;i<n;i++) //look for other jobs within the timeline
{
if(j[i].dead > count) //If current job can be accocmodated take it
{
cout<<j[i].title<<" ";
count++;
}
}
return 0;
}