C++ implementation of Kruskal's algorithm - c++

I'm trying to implement Kruskal's algorithm. Here is a map of the structures I'm using:
g = array of edges, it keeps the left end and the right end and the edge's weight;
c = array which memorises the conex components; c[N] = the conex component in which we find the Nth vertex;
a = array which memorises the MST;
m = nr of vertexes;
n = nr of nodes.
There are two problems with the following code:
1) For the following input it outputs that the cost of the MST is 18 (which is wrong, the cost is actually 14):
7 ( =m )
6 ( =n )
1 2 9
1 3 5
1 4 2
2 3 7
3 5 3
4 6 1
5 6 1
2) Compiling the code step by step doesn't give any errors, although the actual execution of the program halts at some point, I figure it's when printing the cost of the MST.
Thanks for helping! Here's the code:
#include<stdio.h>
#include<stdlib.h>
#define grafMAX 101
FILE *fin = fopen("grafin.txt","r");
FILE *fout = fopen("grafout.txt","w");
struct Vertex{
int first,last,Cost;
};
void read_graf(Vertex **g, int *c, int &m, int &n){
int x,y,w;
fscanf(fin,"%d%d",&m,&n);
*g = (Vertex *)malloc(m*sizeof(Vertex));
for(int i=1;i<=m;++i){
fscanf(fin,"%d%d%d",&x,&y,&w);
(*g+i)->first = x;
(*g+i)->last = y;
(*g+i)->Cost = w;
}
for(int i=1;i<=n;++i)
c[i] = i;
}
int costMST(Vertex *g, int *a, int n){
int MST = 0;
for(int i=1;i<n;++i)
MST += g[a[i]].Cost;
return MST;
}
void Kruskal(Vertex *g, int *c, int *a, int n){
int nr = 0, mini, maxi;
for(int i=1;nr<n-1;++i)
if(c[g[i].first] != c[g[i].last]){
a[++nr] = i;
if(c[g[i].first] < c[g[i].last]){
mini = c[g[i].first];
maxi = c[g[i].last];
}
else{
maxi = c[g[i].first];
mini = c[g[i].last];
}
for(int j=1;j<=n;++j)
if(c[j] == maxi)
c[j] = mini;
}
}
inline int cmp(const void *a, const void *b){
return (((Vertex *)a)->Cost - ((Vertex *)b)->Cost);
}
int a[grafMAX], c[grafMAX];
int main(){
Vertex *g;
int m, n;
read_graf(&g,c,m,n);
qsort(g,m,sizeof(Vertex),cmp);
Kruskal(g,c,a,n);
fprintf(fout,"The cost of the MST is: %d.\n",costMST(g,a,n));
fclose(fin);
fclose(fout);
return 0;
}

There are a lot of off by one errors in your code, I think because you are numbering your vertices from 1 rather than 0. One of these errors was causing it to crash, and I think another one was causing the wrong result to be produced.
I changed all of the internal numbering to be 0-based and and that has got it to work. I renamed your variables because they were quite preposterously named (what you call a Vertex is an Edge) and I couldn't make sense of the code with them like that.
I'm afraid I lost track of everything I changed, but I expect you can see what I did if you compare it with your original code.
Notice that I added some debug lines. When you can't work out what your code is doing, just print the relevant variables and you will soon see what the problem is.
#include<stdio.h>
#include<stdlib.h>
#define grafMAX 101
FILE *fin = fopen("grafin.txt","r");
FILE *fout = fopen("grafout.txt","w");
struct Edge {
int first,last,Cost;
};
void read_graf(Edge **g, int *components, int &num_edges, int &num_vertices){
int x,y,w;
fscanf(fin,"%d %d",&num_edges,&num_vertices);
*g = (Edge *)malloc(num_edges*sizeof(Edge));
for(int i=0;i<num_edges;++i){
fscanf(fin,"%d %d %d",&x,&y,&w);
(*g+i)->first = x - 1;
(*g+i)->last = y - 1;
(*g+i)->Cost = w;
}
for(int i=0;i< num_vertices;++i)
components[i] = i;
}
int costMST(Edge *edges, int *answer, int num_edges){
int MST = 0;
for(int i=0;i<num_edges;++i)
MST += edges[answer[i]].Cost;
return MST;
}
void print_components(const int* components, int num_components)
{
for (int i = 0; i < num_components; i++) {
printf("Vertex %d is in component %d\n", i, components[i]);
}
putchar('\n');
}
void print_edge(const Edge& edge, int index)
{
printf("Edge %d connecting %d to %d with weight %d", index, edge.first, edge.last, edge.Cost);
}
void Kruskal(Edge *edges, int *components, int *answer, int num_edges, int num_vertices){
int nr = 0, mini, maxi;
for(int i=0;i<num_edges && nr < num_vertices - 1;++i) {
printf("Considering ");
print_edge(edges[i], i);
putchar('\n');
if(components[edges[i].first] != components[edges[i].last]){
printf("Adding ");
print_edge(edges[i], i);
putchar('\n');
answer[nr++] = i;
if(components[edges[i].first] < components[edges[i].last]){
mini = components[edges[i].first];
maxi = components[edges[i].last];
}
else{
maxi = components[edges[i].first];
mini = components[edges[i].last];
}
for(int j=0;j<num_vertices;++j)
if(components[j] == maxi)
components[j] = mini;
print_components(components, num_vertices);
}
else {
printf("Rejecting ");
print_edge(edges[i], i);
putchar('\n');
}
}
}
inline int cmp(const void *a, const void *b){
return (((Edge *)a)->Cost - ((Edge *)b)->Cost);
}
int answer[grafMAX], components[grafMAX];
int main(){
Edge *edges;
int num_edges, num_vertices;
read_graf(&edges,components,num_edges,num_vertices);
qsort(edges,num_edges,sizeof(Edge),cmp);
Kruskal(edges,components,answer,num_edges,num_vertices);
fprintf(fout,"The cost of the MST is: %d.\n",costMST(edges,answer,num_vertices - 1));
fclose(fin);
fclose(fout);
return 0;
}

Related

N-Queen Problem: Cannot figure out why my solution is not working

I was having a go at the standard N-Queens problem for an upcoming interview.
I have tried to dry run my code and it seems to work fine. I can't spot the error in my code.
I am traversing it column by column, and using backtracking to recur back from an incorrect path.
Can anyone help me with why this doesn't give me the desired output (details below)?
Here's the problem statement
#include<bits/stdc++.h>
using namespace std;
void solve(vector<vector<int>> &ans, vector<int> &curr, int col, int n){
if(col==n){
ans.push_back(curr);
return;
}
bool flag=false;
for(int row=0; row<n; row++){
if(col==0){
curr.push_back(row);
solve(ans, curr, col+1, n);
curr.pop_back();
}
else{
for(int i=0; i<curr.size(); i++){
if((curr[i] == row) || (abs(row-curr[i]) == (col-i))){
flag=true;
break;
}
}
if(flag)
continue;
curr.push_back(row);
solve(ans, curr, col+1, n);
curr.pop_back();
}
}
}
int main()
{
int t;
cin>>t;
while(t--){
int n;
cin>>n;
vector<vector<int>> ans;
vector<int> curr;
solve(ans, curr, 0, n);
for (int i = 0; i < ans.size(); i++) {
cout << "[";
for (int j = 0; j < ans[i].size(); j++)
cout << ans[i][j]+1 << " ";
cout << "]";
}
cout << endl;
}
return 0;
}
A sample input would look like:
2
1
4
and the corresponding output would be:
[1 ]
[2 4 1 3 ] [3 1 4 2 ]
The compiler gives me an output (for my code):
[1 ]
The bool flag variable (used to check if placing a queen at (row, col) would intersect with any existing queens in curr) is currently being re-used across rows.
So, if you place the line bool flag=false; just above for(int i=0; i<curr.size(); i++){, it should produce the correct output for your test case.
Other notes:
It might be easier to create a separate function bool does_intersect(const vector<int>& cur, int row, int col) to check the queen intersection condition so that the bool flag variable isn't needed.
The if(col==0){ condition can be removed since it doesn't do anything that the else part cannot already handle.
This solution passes LeetCode's online judge for N Queens problem, and uses three flags to solve the problem:
#include <string>
#include <vector>
class Solution {
public:
std::vector<std::vector<std::string>> solveNQueens(int n) {
std::vector<std::vector<std::string>> possibilities;
std::vector<std::string> n_queens(n, std::string(n, '.'));
std::vector<int> flag_col(n, 1);
std::vector<int> flag_diag_a(2 * n - 1, 1);
std::vector<int> flag_diag_b(2 * n - 1, 1);
solveNQueens(possibilities, n_queens, flag_col, flag_diag_a, flag_diag_b, 0, n);
return possibilities;
}
private:
void solveNQueens(std::vector<std::vector<std::string>>& possibilities,
std::vector<std::string>& n_queens,
std::vector<int>& flag_col, std::vector<int>& flag_diag_a, std::vector<int>& flag_diag_b,
int row, int& n) {
if (row == n) {
possibilities.push_back(n_queens);
return;
}
for (int col = 0; col != n; col++) {
if (flag_col[col] && flag_diag_a[row + col] && flag_diag_b[n - 1 + col - row]) {
flag_col[col] = flag_diag_a[row + col] = flag_diag_b[n - 1 + col - row] = 0;
n_queens[row][col] = 'Q';
solveNQueens(possibilities, n_queens, flag_col, flag_diag_a, flag_diag_b, row + 1, n);
n_queens[row][col] = '.';
flag_col[col] = flag_diag_a[row + col] = flag_diag_b[n - 1 + col - row] = 1;
}
}
}
};
For interview, you should not probably use:
#include<bits/stdc++.h>
using namespace std;
and make sure to write clean codes.
N Queens is a low frequency interview question. There are much better questions to be asked in the interviews (such as Number of Islands), probably you would not get N Queens. But, it's good to practice.
This is a pretty simple way to solve the problem of the N-Queens using backtracking:
#include <bits/stdc++.h>
using namespace std;
int m[20][20];
bool ended = false;
void print(int n){
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
cout<<(m[i][j] == -1? "O" : "-")<<" ";
}
cout<<endl;
}
}
void fill(int val, int row, int col, int n){
int d = 1;
for(int i = col + 1; i < n; i++, d++){
m[row][i] += val;
if(row - d >= 0) m[row - d][i] += val;
if(row + d < n) m[row + d][i] += val;
}
}
void solve(int n, int col = 0){
if(ended) return;
if(col == n){ print(n); ended = true; return; }
for(int i = 0; i < n; i++){
if(m[i][col] == 0){
m[i][col] = -1;
fill(1, i, col, n);
solve(n, col + 1);
m[i][col] = 0;
fill(-1, i, col, n);
}
}
}
int main(){
memset(m, 0, sizeof(m));
solve(8); //dimension of board
return 0;
}
The idea is to always look forward. Place a queen in a slot that is 0 in the matrix. After that, add 1 in all slots where she can move to. When you return from the backtracking, subtract 1 from the same slots you just added and continue trying.

I can't figure out what is wrong my implementation of MST with Kruskal algorithm [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I am trying to solve an algorithm problem (MST with Kruskal algorithm). It works sometimes and doesn't work sometimes (with runtime error). I solved this problem with another approach, but I want to figure out what is wrong with this code for future problems. I guess it is the memory problem, but I can't find out for two days.
typedef struct edges
{
struct edges *nextNode;
int weight;
int src;
int dest;
}EDGES;
typedef struct vertex
{
EDGES *edgePtr;
int verNum;
int weight;
COLOR color;
}VERTEX;
typedef struct setTree
{
struct setTree *parent;
int verNum;
int rank;
}SETNODE;
SETNODE *findSet(SETNODE *tree)
{
if (tree != tree->parent)
tree->parent = findSet(tree->parent);
return tree->parent;
}
void makeSet(SETNODE *tree, int vernum)
{
tree->parent = tree;
tree->verNum = vernum;
tree->rank = 0;
}
int linkSet(SETNODE *x, SETNODE *y)
{
SETNODE *x_root = findSet(x);
SETNODE *y_root = findSet(y);
if (x_root->rank > y_root->rank)
y_root->parent = x_root;
else if (x_root->rank < y_root->rank)
{
x_root->parent = y_root;
}
else
{
y_root->parent = x_root;
++x_root->rank;
}
return 1;
}
int unionSet(SETNODE *x, SETNODE *y)
{
return linkSet(x, y);
}
void MST_Kruskal(VERTEX **graph, int N, EDGES **edgeList, int edgeNum)
{
SETNODE *set[MAXN];
EDGES *result[MAXN*(MAXN - 1)];
EDGES *tmp[MAXN];
int edgeCnt = 0;
int tmpVerNum1, tmpVerNum2;
for (int i = 0; i < N; ++i)
{
set[i] = new SETNODE;
}
for (int i = 0; i < N; ++i)
{
makeSet(set[i], (i + 1));
}
mergeSort(edgeList, tmp, 0, edgeNum - 1);
/*for (int i = 0; i < edgeNum; ++i)
printf("%d->%d : %d\n", edgeList[i]->src, edgeList[i]->dest, edgeList[i]->weight);
*/
for (int i = 0; i < edgeNum; ++i)
{
tmpVerNum1 = edgeList[i]->src; tmpVerNum2 = edgeList[i]->dest;
if (findSet(set[tmpVerNum1 - 1]) != findSet(set[tmpVerNum2 - 1]))
{
int success = unionSet(set[tmpVerNum1 - 1], set[tmpVerNum2 - 1]);
if (success)
result[edgeCnt++] = edgeList[i];
}
}
printf("%d\n", edgeCnt);
for (int i = 0; i < edgeCnt; ++i)
{
printf("%d %d %d\n", result[i]->src, result[i]->dest, result[i]->weight);
}
for (int i = 0; i < N; ++i)
{
delete set[i];
}
}
For mergeSort, there's some kind of restriction with this problem that if weight is same between edges, there should be less vertex number first.
void merge(EDGES **arr, EDGES **tmp, int left, int middle, int right)
{
int i = left, j = middle + 1, k = left, l;
while (i <= middle && j <= right)
{
if (arr[i]->weight < arr[j]->weight)
{
tmp[k++] = arr[i++];
}
else if (arr[i]->weight == arr[j]->weight)
{
if (arr[i]->src < arr[j]->src)
tmp[k++] = arr[i++];
else if (arr[i]->src == arr[j]->src)
{
if (arr[i]->dest <= arr[j]->dest)
tmp[k++] = arr[i++];
else
tmp[k++] = arr[j++];
}
else
tmp[k++] = arr[j++];
}
else
{
tmp[k++] = arr[j++];
}
}
if (i > middle)
{
for (l = j; l <= right; l++)
{
tmp[k++] = arr[l];
}
}
else
{
for (l = i; l <= middle; l++)
{
tmp[k++] = arr[l];
}
}
for (l = left; l <= right; l++)
{
arr[l] = tmp[l];
}
}
void mergeSort(EDGES **arr, EDGES **tmp, int left, int right)
{
int middle = (left + right) / 2;
if (left < right)
{
mergeSort(arr, tmp, left, middle);
mergeSort(arr, tmp, middle + 1, right);
merge(arr, tmp, left, middle, right);
}
}
I think the problem lies in the declaration of tmp array. You have used it as a temporary array for the merge function in mergeSort.
I am assuming maxN is the maximum number of vertices in the graph. Hence the maximum number of edges in the graph can be maxN*(maxN-1). You have declared the size of result to be that and not tmp when infact the size of result should be maxN (maxN-1 to be precise since it will consist of edges representing a MST at the end) and the size of tmp should be maxN*(maxN-1) since the size of edgeList (which is being sorted using tmp array), i.e., edgeNum can be anywhere between 0 and maxN*(maxN-1).
In general, the fewer pointers you use means you are less likely to run into memory problems. Make sure that you aren't accidentally accessing members of a nullptr, or forgetting to pass an address to a function. It would be helpful if you could give us more information on the error :)
Here is an implementation of Kruskal that I wrote a while back. It makes heavy use of the STL and no pointers while simulating a linked list for the EdgeList using a pre-allocated array:
#include <cstdio>
#include <vector>
#include <queue>
#include <functional>
#include <algorithm>
const int MAXSZ = 1010;
struct Edge
{
static int cnt;
int from, to, weight, next;
} edges[MAXSZ * 2], full[MAXSZ * 2];
int Edge::cnt = 1;
int head[MAXSZ]; // for EdgeList impl
int bigb[MAXSZ]; // for DisjointSet impl
int find(const int c) // DisjointSet `find`
{
if (bigb[c] == c)
return c;
bigb[c] = find(bigb[c]);
return bigb[c];
}
void addEdge(const int a, const int b, const int w) // add edges to EdgeList from pure data
{
edges[Edge::cnt].from = a;
edges[Edge::cnt].to = b;
edges[Edge::cnt].weight = w;
edges[Edge::cnt].next = head[a];
head[a] = Edge::cnt;
++Edge::cnt;
bigb[find(a)] = bigb[find(b)] = std::min(find(a), find(b)); // needed to init DisjointSet
}
void addEdge(const Edge &base) // copy insert to EdgeList
{
edges[Edge::cnt] = base;
edges[Edge::cnt].next = head[base.from];
head[base.from] = Edge::cnt;
++Edge::cnt;
bigb[find(base.from)] = bigb[find(base.to)] = std::min(find(base.from), find(base.to));
}
int main()
{
int m, n;
scanf("%d%d", &m, &n);
auto cmp = [](const int &l, const int &r) { return full[l].weight > full[r].weight; };
std::priority_queue<int, std::vector<int>, std::function<bool(int, int)> > pq(cmp); // Used for kruskal
/* input */
for (int i = 1; i <= n; ++i)
{
int a, b, w;
scanf("%d%d%d", &a, &b, &w);
full[i].from = a;
full[i].to = b;
full[i].weight = w;
pq.push(i);
bigb[full[i].from] = full[i].from;
bigb[full[i].to] = full[i].to;
}
int sum = 0;
for (int vis = 0; !pq.empty(); pq.pop())
{
auto cur = full[pq.top()];
if (find(cur.to) == vis && find(cur.from) == vis)
continue; // if it leads back to something we already have
addEdge(cur);
addEdge(cur.to, cur.from, cur.weight); // other direction
vis = std::min(find(cur.to), find(cur.from));
printf("%d -> %d, %d\n", cur.from, cur.to, cur.weight);
sum += cur.weight;
//debug*/ for (int i=1; i<=m; ++i) printf("%3d", i); printf("\n"); for (int i=1; i<=m; ++i) printf("%3d", bigb[i]); printf("\n\n");
}
printf("total: %d\n", sum);
return 0;
}
/* test data
first line: verticies, edges
next #edges lines: from, to, weight
3 3
1 2 3
3 2 1
3 1 2
5 6
1 2 2
1 4 1
2 3 2
3 4 -2
3 5 1
4 5 9
*/

Weird crashing program while debug runs smoothly (Eclipse C++)

I'm writing a program for my algorithmic math class at university and I'm using Win 7 (x64), Eclipse Oxygen.1a Release (4.7.1a) with MinGW 6.3.0.
Whenever I build and run the program it crashes with windows claiming 'Abgabe3.exe stopped working' but when trying to find the problem using the debugger and breakpoints I step trough the whole program and it finishes without errors...
I stripped everything not used by the problematic function and copied everything into a seperate file and the exact problem occurs.
Maybe somebody has a clue what happened at my side. ^^
#include <math.h> /* pow, sqrt */
#include <iostream> /* cin, cout */
#include <new> /* new */
#include <string> /* string */
#include <stdlib.h> /* srand, rand */
#include <time.h> /* time */
using namespace std;
void NORM(double* res, double* x, int n){
res[0] = 0.0;
for(int i = 0; i < n; i++){
res[0] += pow(x[i], 2);
}
res[0] = sqrt(res[0]);
}
void initRand(double* x, int n){
srand (time(NULL) * rand());
for(int i = 0; i < n; i++){
x[i] = (((double) rand()) / ((double) RAND_MAX));
}
}
void createArray(double* &x, int n){
if (n > 0){
x = new double[n];
initRand(x, n);
}
}
void printArray(double* x, int n){
if (x != NULL){
cout<<"(\n";
for(int i = 0; i < n; i++){
if(i+1 == n) cout<<x[i];
else if ((i % 5) == 0) cout<<x[i];
else if ( ((i+1) % 5) == 0 ){
cout<<", "<<x[i]<<"\n";
}
else {
cout<<", "<<x[i];
}
}
cout<<"\n)\n";
}
else cout<<"\nError: pointer = NULL\n";
}
unsigned long long int bin(unsigned int n, unsigned int k){
unsigned long long res = 1;
if(k == 0) return 1;
else if( n >= k){
for(unsigned long long int i = 1; i <= k; i++){
res *= (n + 1 - i) / i;
}
}
else return 0;
return res;
}
void newArray(double** x, unsigned int v, unsigned int n){
for(unsigned int i = 0; i < v; i++){
double* ptr = x[i];
createArray(ptr,n);
x[i] = ptr;
}
}
void experiment(double** vektorArray){
unsigned int n = 10, v = 20;
cout<<"Dimension n = "<<n<<"\nAnzahl Versuche v = "<<v<<endl;
//Erstellen der Vektoren
cout<<"Erstellen - starte\n";
vektorArray = new double*[n];
newArray(vektorArray, v, n);
cout<<"Erstellen - fertig\n";
for(unsigned int i = 0; i < v; i++){
if(i%10 == 0) printArray(vektorArray[i], n);
}
}
int main(int argc, char** argv){
double** vektorArray = NULL;
experiment(vektorArray);
return 0;
}
vektorArray = new double*[n];
created an array of size n, but
void newArray(double** x, unsigned int v, unsigned int n)
{
for (unsigned int i = 0; i < v; i++)
{
double* ptr = x[i];
createArray(ptr, n);
x[i] = ptr;
}
}
and
for (unsigned int i = 0; i < v; i++)
{
if (i % 10 == 0)
printArray(vektorArray[i], n);
}
index that array with v. Looks like you got your variables crossed. Strongly recommend giving variables better, more descriptive names to help make this more obvious.

Segmentation Fault: 11 on small input for array/vector

There are several questions related to this error on stackoverflow, and I understand that its related to excess memory usage by the array, or when using pointers (I tried this with vectors aswell) but using a small array, it still shows this error. The same code earlier was running fine (for merge sorting an array).
My input was as follows:
5
9 8 1 2 4
Output:
Segmentation fault: 11
#include<iostream>
#include<vector>
using namespace std;
void merge(vector <int> ar, int l, int m, int r){
int n1 = m-l+1;
int n2 = r-m;
int L[n1];
int R[n2];
for (int i = 0; i < n1; ++i)
{
L[i]=ar[l+i];
}
for (int j = 0; j < n2; ++j)
{
R[j]=ar[m+j+1];
}
int i,j;
i = j = 0;
int k = i;
while(i<n1 && j<n2){
if (L[i]<R[j])
{
ar[k]=L[i];
i++;
}
else if (R[j]<L[i])
{
ar[k]=R[j];
j++;
}
k++;
}
while(i<n1){
ar[k]=L[i];
i++;
k++;
}
while(j<n2){
ar[k]=R[j];
j++;
k++;
}
}
void mergesort(vector <int> ar, int l, int r){
int m;
m=r+(l-r)/2;
if (l<r)
{
mergesort(ar, l, m);
mergesort(ar, m+1, r);
merge(ar, l, m, r);
}
}
void print(vector <int> ar, int size){
for (int i = 0; i < size; ++i)
{
cout<<ar[i]<< " ";
}
}
int main()
{
int n;
cin>>n;
vector <int> ar;
for (int i = 0; i < n; ++i)
{
cin>>ar[i];
}
print(ar,n);
mergesort(ar, 0, n-1);
print(ar, n);
return 0;
}
The problem is in part with m=r+(l-r)/2. When l is 0 and r is 1, (l-r)/2 is 0. This makes m equal to 1, l equal to 0, and r equal to 1 and the mergesort(ar, l, m); call identical to the one it just worked through. The stack grows unbounded until you have a segmentation fault. One way to fix this which will also make your code more efficient is to merge the lists when the difference between l and r is below some threshold. Or, you can just swap the two elements when you get to the point where l and r differ by one, like so:
if (l - r <= 1) {
int temp = ar[l];
ar[l] = ar[r];
ar[r] = temp;
return;
}

Matrix Chain Multiplication using Dynamic Programming in C++ Program Crashes?

I have written following C++ program to implement to implement MCM using Dynamic Programming. But the following program crashes. What is wrong in my code ?
#include<iostream>
#include<cstdlib>
#define SZ 10
using namespace std;
int table[SZ][SZ];
int P[] = {2,3,3,5};
int MCM(int i, int j)
{
if(i==j) return 0;
else
{
int min = INT_MAX;
for(int k=i;k<=j;k++)
{
if(table[i][k]==0)
table[i][k] = MCM(i,k);
if(table[k+1][j]==0)
table[k+1][j] = MCM(k+1,j);
int sum = table[i][k] + table[k+1][j] + P[i-1]*P[j]*P[k];
if(sum<min)
min = sum;
}
return min;
}
}
int main()
{
int size = sizeof(P)/sizeof(P[0]);
printf("Minimum number of mutiplications is %d",MCM(0,size-1));
return 0;
}
Your code is going to infinite loop. Besides you have made some mistakes:
You have never assigned the optimum value in the table (when you find minimum sum, you are not storing it). Hence every time you are checking for table[i][j] == 0, it's true
k in your loop can be equal to j and you are using k+1, this is a mistake
Anyway I think the right version of your code should be something like this:
#include<iostream>
#include<cstdlib>
#define SZ 10
using namespace std;
int table[SZ][SZ];
int P[] = {1,2,3,4};
int MCM(int i, int j)
{
if(i==j) return 0;
else
{
int min = INT_MAX;
for(int k=i;k<j;k++)
{
if(table[i][k]==0)
table[i][k] = MCM(i,k);
if(table[k+1][j]==0)
table[k+1][j] = MCM(k+1,j);
int sum = table[i][k] + table[k+1][j] + P[i]*P[j]*P[k];
if(sum<min)
min = sum;
}
table[i][j] = min;
return min;
}
}
int main()
{
int size = sizeof(P)/sizeof(P[0]);
printf("Minimum number of mutiplications is %d",MCM(0,size-1));
return 0;
}
The first time MCM(0, size-1) is called, the parameter i = 0, but then you subtract 1 and use the resulting -1 to access P[-1] (on line 23). That probably causes the crash.
Oh I got what is wrong with this its just a minor mistake
The loop on should on line 17 should end at the condition
k<j
and not at
k<=j
The program compiles and runs successfully
#include<iostream>
#include<cstdlib>
#define SZ 10
using namespace std;
int table[SZ][SZ];
int P[] = {1, 2, 3, 4, 3};
int MCM(int i, int j)
{
if(i==j) return 0;
else
{
int min = INT_MAX;
for(int k=i;k<j;k++) // bug was here: for(int k=i;k<=j;k++)
{
if(table[i][k]==0)
table[i][k] = MCM(i,k);
if(table[k+1][j]==0)
table[k+1][j] = MCM(k+1,j);
int sum = table[i][k] + table[k+1][j] + P[i-1]*P[j]*P[k];
if(sum<min)
min = sum;
}
return min;
}
}
int main()
{
int size = sizeof(P)/sizeof(P[0]);
printf("Minimum number of mutiplications is %d",MCM(1,size-1));
return 0;
}