View Single Post
Old 03-17-2005, 08:00 PM   #1 (permalink)
brad_galloway
Registered User
 
brad_galloway's Avatar
 
Join Date: Feb 2005
Location: Western KY
Posts: 24
brad_galloway is on a distinguished road
Question Munske's Algorithm

This is my implemintation of Munske's Algorithm. The problem is that it locks up around step 4 or 5, but I can't figure out why.

Code:
// Brad Galloway
// CSC 445 - Programming Assignment 4
// Munkre's Algorithm

#include<iostream>
#include<iomanip>
#include<fstream>
#include<string>
#include<climits>

using namespace std;

int const MAX_SIZE = 20;            // size of matricies
int n;                              // the number of rows and columns the actual 
                                    // matrix has
int cost_matrix[MAX_SIZE][MAX_SIZE];// The cost matrix
int mask_matrix[MAX_SIZE][MAX_SIZE];// the mask matrix
int C_cover[MAX_SIZE];              // Array of column covers
int R_cover[MAX_SIZE];              // Array of row covers
int stepnum;                        // the step number
bool done;                          // Keeps track if the main program is done
int row = 0;
int col = 0;
int z0_r, z0_c;
int counter;
int path[MAX_SIZE][MAX_SIZE];
char outFilename[11] = "output.txt";

void read_file(char file[]){
  ifstream inFile( file );
	if(!inFile)
	{
		cerr << "File could not be opened.  \n";
		exit( 1 );
	}
	inFile >> n;
	for(int i = 0; i < n; i++)
		for(int j = 0; j < n; j++)
			inFile >> cost_matrix[i][j];
			
  for(int x = 0; x < n; x++){
    C_cover[x] = 0;
    R_cover[x] = 0;
  } 
}

void out_matrix(){
	ofstream outFile( outFilename );
	for(int x = 0; x < n; x++)
	{
		for(int y = 0; y < n; y++){
		  cout << setw(3);
      outFile << setw(3);
      if(mask_matrix[x][y] == 1){
        cout << "*";
        outFile << "*";
      }
      else if(mask_matrix[x][y] == 2){
        cout << "'";
        outFile << "'";
      }
      else if(C_cover[y] == 1 || R_cover[x] == 1){
        cout << "X";
        outFile << "X";
      }
      else{
       	cout << cost_matrix[x][y];
       	outFile << cost_matrix[x][y];
      }
    }
		cout << "\n";
	}
	cout << "\n";
}

void find_a_zero(int &r, int &c){
     int i = 1;
     int j;
     bool over = false;
     while(!over){
       j = 1;
       while( j <= n ){
         if(cost_matrix[i][j] == 0 && R_cover[i] == 0 && C_cover[j] == 0)
         {
           r = i;
           c = j;
           over = true;
         }
         j += 1;
       }
       if( i > n ){
         over = true;
       }       
     }
}

bool star_in_row(int r){
     bool tbool = false;
     for(int j = 0; j < n; j++){
       if(mask_matrix[r][j] == 1){
         tbool = true;
       }
     }
     return tbool;
}

void find_star_in_row(int &r, int &c){
     c = 0;
     for(int j = 0; j < n; j++){
       if(mask_matrix[r][j] == 1){
         c = j;
       }
     }
}

void find_star_in_col(int c, int &r){
     r = 0;
     for(int i = 0; i < n; i++){
       if(mask_matrix[i][c] == 1){
         r = i;
       }
     }
}

void find_prime_in_row(int r, int &c){
     for(int j = 0; j < n; j++){
       if(mask_matrix[r][j] == 2){
         c = j;
       }
     }
}

void convert_path(){
     for(int i = 0; i < counter; counter++){
       if(mask_matrix[path[i][1]][path[i][2]] == 1){
         mask_matrix[path[i][1]][path[i][2]]=0;
       }
       else{
         mask_matrix[path[i][1]][path[i][2]]=1;
       }
     }
}

void clear_covers(){
     for(int i = 0; i < n; i++){
       R_cover[i] = 0;
       C_cover[i] = 0;
     }
}

void erase_primes(){
     for(int i = 0; i < n; i++){
       for(int j = 0; j < n; j++){
         if(mask_matrix[i][j] == 2){
           mask_matrix[i][j] = 0;
         }
       }
     }
}

void find_smallest(int minval){
     minval = numeric_limits<int>::max();
     for(int i = 0; i < n; i++){
       for(int j = 0; j < n; j++){
         if(R_cover[i] == 0 && C_cover[j] == 0){
           if(minval > cost_matrix[i][j]){
             minval = cost_matrix[i][j];
           }
         }
       }
     }
}

void step_one(){
     cout << "\nStep One\n";
     int minval;
     for(int i = 0; i < n; i++){
       minval = cost_matrix[i][1];
       for(int j = 0; j < n; j++){
         if(minval > cost_matrix[i][j])
           minval = cost_matrix[i][j];
       }
       for(int k = 0; k < n; k++)
         cost_matrix[i][k] = cost_matrix[i][k] - minval;
     }

     out_matrix();     
     stepnum = 2;
}
void step_two(){
     cout << "\nStep Two\n";
     for(int i = 0; i < n; i++){
       for(int j = 0; j < n; j++){
         if(cost_matrix[i][j] == 0 && C_cover[j] == 0 && R_cover[i] == 0){
           mask_matrix[i][j] = 1;
           C_cover[j] = 1;
           R_cover[i] = 1;
         }
       }
     }
     cout << "\nMask Matrix\n";
     for(int x = 0; x < n; x++){
  		 for(int y = 0; y < n; y++)
		     cout << setw(3) << mask_matrix[x][y];
       cout << "\n";
     }
     cout << "\n";

     out_matrix();
     for(int x = 0; x < n; x++){
       C_cover[x] = 0;
       R_cover[x] = 0;
     }
     cout << "\nAfter Step Two\n";
     out_matrix();
     stepnum = 3;
     
}
void step_three(){
     cout << "\nStep Three\n";
     int counter = 0;
     for(int i = 0; i < n; i++){
       for(int j = 0; j < n; j++){
         if(mask_matrix[i][j] == 1)
           C_cover[j] = 1;
       }
     }

     out_matrix();
     for(int x = 0; x < n; x++)
       counter += C_cover[x];
     if(counter >= n)
       stepnum = 7;
     else
       stepnum = 4;
}

void step_four(){
     bool thru = false;
     cout <<"\nStep Four\n";
     while(!thru){
       find_a_zero(row, col);
       if(row == 0){
         thru = true;
         stepnum = 6;
       }
       else{
         mask_matrix[row][col] = 2;
         if(star_in_row(row)){
           find_star_in_row(row, col);
           R_cover[row] = 1;
           C_cover[col] = 0;
         }
         else{
           thru = true;
           stepnum = 5;
           z0_r = row;
           z0_c = col;
         }
       }
     }
     out_matrix();
}
void step_five(){
     cout << "\nStep Five\n";
     counter = 1;
     path[counter][1] = z0_r;
     path[counter][2] = z0_c;
     int r;
     int c;
     bool quit = false;
     while(!quit){
       find_star_in_col(path[counter][2], r);
       if(r > 0){
         counter += 1;
         path[counter][1] = r;
         path[counter][2] = path[counter-1][2];
       }
       else{
         quit = true;
       }
       if(!quit){
         find_prime_in_row(path[counter][1], c);
         counter += 1;
         path[counter][1] = path[counter-1][1];
         path[counter][2] = c;
       }
     }
     convert_path();
     clear_covers();
     erase_primes();
     stepnum = 3;

     out_matrix();
}

void step_six(){
     cout << "\nStep six\n";
     int minval;
     find_smallest(minval);
     for(int i = 0; i < n; i++){
       for(int j = 0; j < n; j++){
         if(R_cover[i] == 1){
           cost_matrix[i][j] = cost_matrix[i][j]-minval;
         }
         if(C_cover[j] == 0){
           cost_matrix[i][j] = cost_matrix[i][j]-minval;
         }
       }
     }

     out_matrix();
     stepnum = 4;
}
void finished(){
     done = true;
}

int main(){
    char filename[25];
    char answer;
    bool do_another = true;

    while(do_another){
      done = false;
      stepnum = 1;
      cout << "Enter filename containing cost matrix:  ";
      cin >> filename;
      cout << endl;
      read_file(filename);
      out_matrix();
      while(!done){
        switch( stepnum ) {
          case 1: step_one();
          case 2: step_two();
          case 3: step_three();
          case 4: step_four();
          case 5: step_five();
          case 6: step_six();
          default: finished();
          break;
        }
      }
      cout << "Would you like to do another file?(y or n):  ";
      cin >> answer;
      if(answer == 'n' || 'N'){
        do_another = false;
      }
    }
    return 0;
}
brad_galloway is offline   Reply With Quote