//***************************************************************************** // // main.C // author: Eric Michael Ryckman // e-mail: eryckman@umich.edu // // Code for Permanent Approximations, according to // // "The Distance Approach to Approximate Combinatorial Counting" // // by // // A. Barvinok and A. Samorodnitsky // // // function LAP code by R. Jonker and A. Volgenant // e-mail: roy_jonker@majiclogic.com // //***************************************************************************** #include #include #include #include #include #include #include #include using namespace std; const int MAXDIM = 1000; //Dimension of matrix, or |V|/2 const int MAX = 10000; //const int MAX = DIM*ceil(log(DIM))+1, //largest plausible value of m const int SETS = 2; //number of sets of vertices int sumRows(int[MAXDIM][MAXDIM], int, int); int sumCols(int[MAXDIM][MAXDIM], int, int); int makem(int[MAXDIM], int[MAXDIM], int, int[MAXDIM][MAXDIM], int[MAXDIM]); int assignWeights(int[MAXDIM][MAXDIM], int[MAX], int[MAXDIM][MAXDIM], int[MAXDIM], int); int LAP(int, int[MAXDIM][MAXDIM], int [MAXDIM], int[MAXDIM], int[MAXDIM], int[MAXDIM]); float H(float); void generateStrings(int[MAX], int); //****************************************************************************** //****************************************************************************** //****************************************************************************** int main() { ifstream inFile; string fileName; //name of input file int DIM; //dimension of matrix int i, j; //for iterations int m, M; //min(m+,m-) int lapcost; //weight of optimal matching long K, K1; //number of strings to create long b; //for large iterations float epsilon; //for precision float alphaaverage; //sum of alphas float alphaaverage1; //average of alphas float beta; float lowerbound; float upperbound; float center; int rowSum[MAXDIM]; int colSum[MAXDIM]; int mi[MAXDIM]; //mi[i]=lengths of strings int randomStrings[MAX]; int rowsol[MAXDIM]; //col matched to row int colsol[MAXDIM]; //row matched to col int u[MAXDIM]; //dual variable int v[MAXDIM]; //dual varuable int alpha[LONG_MAX]; //bth optimal matching weight int matrix[MAXDIM][MAXDIM]; int weights[MAXDIM][MAXDIM]; //weight matrix cout << "\n\n**************************************************************" << "\nThis program embeds the set of all perfect matchings of a" << "\ngraph into the Boolean Cube. It then estimates the average" << "\nHamming distance from a random point in the cube to the set." << "\nBased on this distance, it provides a lower bound (achieved" << "\nwhen the set of perfect matchings is sparse) and an upper" << "\nbound (achieved when the set of perfect matchings is dense)" << "\nfor the number of perfect matchings of the graph." << "\n**************************************************************\n"; cout << "\nEnter the dimension of the matrix: "; cin >> DIM; while(DIM<=0) { cout << "\nThis must be greater than zero."; cout << "\n\nEnter the dimension of the matrix: "; cin >> DIM; } cout << "\nEnter the name of the file to open: "; cin >> fileName; inFile.open(fileName.c_str(), ios::in); //if can't open while(!inFile) { cout << "\n\nCould not open the file '" << fileName << "' "; cout << "please try again."; inFile.close(); cout << "\n\nEnter the name of the file to open: "; cin >> fileName; inFile.open(fileName.c_str(), ios::in); } //get a valid K cout << "\nEnter the number of random points to sample from the cube: "; cin >> K; cout << endl; while(K<=0) { cout << "\nThis must be greater than zero."; cout << "\n\nEnter the number of strings to create: "; cin >> K; } //read in matrix from inFile for(i=0; i> matrix[i][j]; //sum rows and columns for(i=0; i=M+1) cout << "\n\n\tper A = 0"; else if(alphaaverage1=0) { m = mplus; for(i=0; i=0) { m = mminus; for(i=0; i=0; j--)//reverse order gives better results { min = assigncost[0][j]; imin = 0; for(i=1; i=umin) { usubmin = h; j2 = j; } else { usubmin = umin; umin = h; j2 = j1; j1 = j; } } i0 = colsol[j1]; if(umin < usubmin) //change the reduction of the min col to increase the min //reduced cost in the row to the subminimum v[j1] = v[j1] - (usubmin - umin); else if(i0>=0) { j1 = j2; i0 = colsol[j2]; } //(re)assign i to j1, possibly un-assigning an i0 rowsol[i] = j1; colsol[j1] = i; if(i0 >= 0) if(umin < usubmin) //put in current k, and go back to that k //continue augmenting path i - j1 with i0 free[--k] = i0; else //no further augmenting reduction possible //store i0 in list of free rows for next phase free[numfree++] = i0; } } while(loopcnt < 2); //AUGMENT SOLUTION for each free row for(f=0; f