#include #include #include #include #include #include #include #include #include using namespace std; char *filename; int maxxmin = 10; void printUsage(){ cout << "scalefree: analyzer of the scale-free structure of SAT instances. Version 2.3" << endl; cout << "Copyright (C) 2016 C. Ansótegui, M.L. Bonet, J. Giráldez-Cru, J. Levy" << endl; cout << "Cite: C. Ansótegui, M. L. Bonet, J. Levy: \"On the Structure of Industrial SAT Instances\"." <" << endl; cout << "OPTIONS:" << endl; cout << " -x : Max number of values discarded to estimate alpha or beta (default: 10)." << endl; exit(-1); } void parseArgs(int argc, char *argv[]){ int opt; while((opt=getopt(argc, argv, "h?x:")) != -1) switch(opt){ case 'x': maxxmin = atoi(optarg); break; case 'h': case '?': default: printUsage(); } if(optind < argc) filename = argv[optind]; else printUsage(); } //----------------------------------------------------------------------------- double abs(double x) { //----------------------------------------------------------------------------- if (x < 0) return -x; else return x; } int abs(int x){ if(x<0) return -x; else return x; } //----------------------------------------------------------------------------- double powlawc(int x, int xmin, double alpha) { //----------------------------------------------------------------------------- // Computes sum_{i=x}^{\infty} x^{alpha} / sum_{i=xmin}^{\infty} x^{alpha} // or approximates it as (x/xmin)^(alpha+1) //----------------------------------------------------------------------------- assert(alpha < -1); assert(xmin <= x); #define MAXITER 10000 double num = 0, den = 0; int i; if (xmin < 25) { for (i=xmin; i 0.00000001 && n < MAXITER) { den += pow((double)i, alpha); num += pow((double)i, alpha); i++; n++; pold = p; p = num/den; } if (n < MAXITER) return p; } return pow((double)x/xmin, alpha + 1); } //----------------------------------------------------------------------------- double exponc(int x, int xmin, double beta) { //----------------------------------------------------------------------------- return exp(beta*(xmin - x)) ; } //----------------------------------------------------------------------------- void arity(vector > &arityVar, vector > &arityCla){ //----------------------------------------------------------------------------- FILE *source; source = fopen(filename, "r"); if(!source){ cerr << "ERROR: Unable to read CNF file " << filename << endl; exit(-1); } // Skip comments int aux=-1; while((aux=getc(source))=='c') while (getc(source)!='\n'); ungetc(aux,source); // File Head int totVars=0, totClauses=0; if( !fscanf(source, "p cnf %i %i", &totVars, &totClauses)) { cerr << "Invalid CNF file\n"; exit(-1); } vector nOccurs(totVars,0); //nOccurs[i] = number of occurences of variable i+1 vector nSizes; //nSizes[i] = number of clauses of size i int var; int size = 0; while(fscanf(source, "%d", &var)==1) { if(var == 0){ if(size >= nSizes.size()) nSizes.resize(size+1); nSizes[size]++; size=0; } else { size++; nOccurs[abs(var)-1]++; } } sort(nOccurs.begin(), nOccurs.end()); int prev = nOccurs[0]; int addition = 1; for (int i=1; i0) arityCla.push_back(make_pair(i,nSizes[i])); } //----------------------------------------------------------------------------- void mostlikely(vector > &v, string filename) { //----------------------------------------------------------------------------- if (v.size() < 4) { cerr << "ERROR: Unable to compute exponent for "< x(n), y(n+1), syx(n+1), sylogx(n+1); double Sy = 0; for (int i=0; i=0; i--) { x[i] = v[i].first; y[i] = y[i+1] + v[i].second / Sy; sylogx[i] = sylogx[i+1] + v[i].second / Sy * log(x[i]); syx[i] = syx[i+1] + v[i].second / Sy * x[i]; } //------ Compute, for powerlaw (a) and exponential (b), // the best alpha, xmin, dif and where is located-------------------- double bestalpha, bestbeta; int bestxmina=0, bestxminb=0; double bestdifa = 1, bestdifb = 1; int bestinda, bestindb; int wherea, whereb; int ind = 0; int xmin; for (int ind=1; ind<=maxxmin && ind= bestdifa) { worstdif = aux; worstx = (int)x[j]; j = n; //Finish search of worst diff } else if (aux >= worstdif) { worstdif = aux; worstx = (int)x[j]; } } for (int j=ind; j= bestdifa) { worstdif = aux; worstx = (int)x[j]+1; j = n; //Finish search of worst diff } else if (aux >= worstdif) { worstdif = aux; worstx = (int)x[j]+1; } } } if(worstdif < bestdifa) { bestalpha = alpha; bestxmina = xmin; bestdifa = worstdif; bestinda = ind; wherea = worstx; } //------------- Model exponential ----------------------------------------- worstdif = -1; worstx = -1; for (int j=ind+1; j= bestdifb) { worstdif = aux; worstx = x[j]; j = n; //Finish search of worst diff } else if (aux >= worstdif) { worstdif = aux; worstx = x[j]; } } for (int j=ind; j= bestdifb) { worstdif = aux; worstx = x[j]+1; j = n; //Finish search of worst diff } else if (aux >= worstdif) { worstdif = aux; worstx = x[j]+1; } } } if(worstdif < bestdifb) { bestbeta = beta; bestxminb = xmin; bestdifb = worstdif; bestindb = ind; whereb = worstx; } } //--------- Write results -------------------------------------------- cout << " Powerlaw:\n"; cout << " alpha = " << -bestalpha << endl; cout << " min. value = " << bestxmina << endl; cout << " max. error = " << bestdifa << " in value:"<< wherea << endl; cout << " Exponential:\n"; cout << " beta = " << bestbeta << endl; cout << " min. value = " << bestxminb << endl; cout << " max. error = " << bestdifb << " in value:"<< whereb << endl; //--------- Generate file INT----------------------------------------- string fileint(filename); fileint.append(".int"); FILE *fint = fopen(fileint.c_str(), "w"); if(fint == NULL) { cerr << "ERROR: Unable to open file " << fileint << endl; exit(-1); } for (int i=0; i > arityVar; vector > arityCla; double bestAlphaVar, bestBetaVar, bestAlphaCla, bestBetaCla; parseArgs(argc,argv); arity(arityVar, arityCla); string nameroot(filename); nameroot=nameroot.substr(0,nameroot.length()-4); string namevar(nameroot); namevar.append(".var"); cout << "VARIABLES" << endl; mostlikely(arityVar, namevar); if (arityCla.size() > 3) { string namecla(nameroot); namecla.append(".cla"); cout << "CLAUSES" << endl; mostlikely(arityCla, namecla); } }