我试图使用强力技术找出图形的最佳顶点覆盖,但它适用于较小的图形,如顶点数20但顶点数> 50它会提示bad_alloc()错误。我无法找到它导致内存无法分配的位置。我正在尝试这两个版本以递归方式和顺序方式查找所有子集。
#include<fstream>
#include<stdlib.h>
#include<time.h>
#include<queue>
#include<math.h>
#include<iostream>
using namespace std;
void subsetR(bool **,bool *,int); //optimum vertex cover
void subsetS(bool **g,int len);
void printArray(bool *, int);
bool checkVertexCover(bool **,bool *);
bool checkVertexCover(bool **g,const vector<bool>&ss);
void printGraph(bool **,int);
int sizeOfArray(bool *,int vertexCount);
int sizeOfArray(vector<bool>&ar,int vertexCount);
int approxVertexCover(bool **,int);
int approxVertexCover2(bool **, int);
int findMaxDegree(bool **,int);
bool isGraphEmpty(bool **,int);
void initializeAr(bool *subset,int len);
bool eq(bool*a,bool*b);
int mini = 1111;
int vertexCount = 0;
int main()
{
cout<<"Vertex Cover Problem"<<endl;
ifstream myfile;
//cout<<"Enter the graph file name"<<endl;
//char fileName[20];
//cin>>fileName;
myfile.open("chordal_graphs.txt");
//myfile.open("g.txt");
int graphNo = 0;
bool **graph = NULL;
bool *vertices = NULL;
srand(time(NULL));
if(myfile.is_open())
{
myfile >> graphNo;
cout<<"No of graphs: "<<graphNo<<endl;
for(int s=0;s<graphNo;s++)
{
cout<<"\nGraph: "<<s+1<<endl;
myfile >> vertexCount;
graph = new bool*[vertexCount];
vertices = new bool[vertexCount];
for(int i=0;i<vertexCount;i++)
{
vertices[i] = false;
graph[i] = new bool[vertexCount];
}
for(int i=0;i<vertexCount;i++)
for(int j=0;j<vertexCount;j++)
myfile >> graph[i][j];
//cout<<"before calling"<<endl;
//printGraph(graph,vertexCount);
//subsetR(graph,vertices,0);
cout<<"Min vertex-cover size = "<<mini<<endl;
int vc = approxVertexCover(graph,vertexCount);
cout<<"General Approx vertex cover: "<<vc<<endl;
//cout<<"Approximation Ratio: "<<static_cast<float>(vc)/static_cast<float>(mini)<<endl;
vc = approxVertexCover2(graph,vertexCount);
cout<<"Greedy Approx vertex cover: "<<vc<<endl;
//cout<<"Approximation Ratio: "<<static_cast<float>(vc)/static_cast<float>(mini)<<endl;
mini = 1111;
subsetS(graph,vertexCount);
cout<<"Min vertex-cover size = "<<mini<<endl;
mini = 1111;
}
}
else
cout<<"Unable to open the file"<<endl;
return 0;
}
void subsetR(bool **g,bool *ar,int index)
{
if(index < vertexCount)
{
if(index+1 == vertexCount)
{
//printArray(ar,vertexCount);
if(checkVertexCover(g,ar) == true)
{
int sz = sizeOfArray(ar,vertexCount);
if(sz < mini)
mini = sz;
}
}
subsetR(g,ar,index+1);
ar[index] = true;
for(int i=index+1;i<vertexCount;i++)
ar[i] = false;
if(index+1 == vertexCount)
{
//printArray(ar,vertexCount);
if(checkVertexCover(g,ar) == true)
{
int sz = sizeOfArray(ar,vertexCount);
if(sz < mini)
mini = sz;
}
}
subsetR(g,ar,index+1);
}
}
void subsetS(bool **g,int len)
{
unsigned long long n = pow(2,len);
//generatePrintBinary(n);
//cout<<sizeof(int)<<endl;
vector<bool> b;
b.clear();
b.resize(len,false);
for(int j=0;j<n;j++)
{
//for(int k=0;k<len;k++)
//cout<<b[k];
//cout<<"\n";
if(checkVertexCover(g,b) == true)
{
int sz = sizeOfArray(b,len);
if(sz < mini)
{
mini = sz;
//cout<<"mini 00 "<<mini<<endl;
}
}
for(int i=len-1;i>=0;i--)
{
if(b[i] == 0)
{
b[i] = 1;
break;
}
else
b[i] = 0;
}
}
}
void printArray(bool *ar,int vertexCount)
{
cout<<"Array is :"<<endl;
for(int i=0;i<vertexCount;i++)
cout<<ar[i]<<" ";
cout<<"\n";
}
bool checkVertexCover(bool **g,bool *ss)
{
//printArray(ss,vertexCount);
//cout<<"check"<<endl;
bool **graph = NULL;
graph = new bool*[vertexCount];
for(int i=0;i<vertexCount;i++)
graph[i] = new bool[vertexCount];
for(int i=0;i<vertexCount;i++)
for(int j=0;j<vertexCount;j++)
graph[i][j] = g[i][j];
//printGraph(g,vertexCount);
for(int i=0;i<vertexCount;i++)
{
if(ss[i] == true)
{
//cout<<"i "<<i<<endl;
for(int j=0;j<vertexCount;j++)
{
graph[i][j] = false;
graph[j][i] = false;
}
}
}
//cout<<"after"<<endl;
//printGraph(graph,vertexCount);
return isGraphEmpty(graph,vertexCount);
}
bool checkVertexCover(bool **g,const vector<bool>& ss)
{
//printArray(ss,vertexCount);
//cout<<"check"<<endl;
bool **graph = NULL;
graph = new bool*[vertexCount];
for(int i=0;i<vertexCount;i++)
graph[i] = new bool[vertexCount];
for(int i=0;i<vertexCount;i++)
for(int j=0;j<vertexCount;j++)
graph[i][j] = g[i][j];
//printGraph(g,vertexCount);
for(int i=0;i<vertexCount;i++)
{
if(ss.at(i) == true)
{
//cout<<"i "<<i<<endl;
for(int j=0;j<vertexCount;j++)
{
graph[i][j] = false;
graph[j][i] = false;
}
}
}
//cout<<"after"<<endl;
//printGraph(graph,vertexCount);
return isGraphEmpty(graph,vertexCount);
}
void printGraph(bool **g,int vertexCount)
{
cout<<"Graph is: "<<endl;
for(int i=0;i<vertexCount;i++)
{
for(int j=0;j<vertexCount;j++)
{
cout<<g[i][j]<<"\t";
}
cout<<"\n";
}
}
int sizeOfArray(bool *ar,int vertexCount)
{
int result = 0;
for(int i=0;i<vertexCount;i++)
{
if(ar[i] == true)
result++;
}
return result;
}
int sizeOfArray(vector<bool>&ar,int vertexCount)
{
int result = 0;
for(int i=0;i<vertexCount;i++)
{
if(ar.at(i) == true)
result++;
}
return result;
}
int approxVertexCover(bool **g,int vertexCount)
{
bool **graph = NULL;
graph = new bool*[vertexCount];
for(int i=0;i<vertexCount;i++)
graph[i] = new bool[vertexCount];
for(int i=0;i<vertexCount;i++)
for(int j=0;j<vertexCount;j++)
graph[i][j] = g[i][j];
int result = 0;
int sz = vertexCount*vertexCount;
bool graphEmpty = false;
//cout<<"before while"<<endl;
while(graphEmpty == false)
{
//cout<<"hello"<<endl;
graphEmpty = true;
int randomEdge = rand() % sz;
//cout<<"after randome"<<endl;
if(graph[randomEdge/vertexCount][randomEdge%vertexCount] == false)
while(graph[randomEdge/vertexCount][randomEdge%vertexCount] == false)
randomEdge = rand() % sz;
int v1 = randomEdge/vertexCount;
int v2 = randomEdge%vertexCount;
//cout<<randomEdge<<endl;
//cout<<"v1: "<<v1<<" v2: "<<v2<<endl;
for(int i=0;i<vertexCount;i++)
{
graph[v1][i] = false;
graph[i][v1] = false;
graph[v2][i] = false;
graph[i][v2] = false;
}
//printGraph(g,vertexCount);
result = result + 2;
graphEmpty = isGraphEmpty(graph,vertexCount);
}
return result;
}
bool isGraphEmpty(bool **g,int vertexCount)
{
for(int i=0;i<vertexCount;i++)
{
for(int j=0;j<vertexCount;j++)
{
if(g[i][j] == true)
return false;
}
}
return true;
}
int approxVertexCover2(bool **g, int vertexCount)
{
int result = 0;
bool graphEmpty = isGraphEmpty(g,vertexCount);
bool **graph = NULL;
graph = new bool*[vertexCount];
for(int i=0;i<vertexCount;i++)
graph[i] = new bool[vertexCount];
for(int i=0;i<vertexCount;i++)
for(int j=0;j<vertexCount;j++)
graph[i][j] = g[i][j];
while(graphEmpty == false)
{
int v = findMaxDegree(graph,vertexCount);
result++;
for(int i=0;i<vertexCount;i++)
{
graph[v][i] = false;
graph[i][v] = false;
}
graphEmpty = isGraphEmpty(graph,vertexCount);
}
return result;
}
int findMaxDegree(bool **g,int vertexCount)
{
int degree = 0;
int maxi = -1111;
int resultVertex = -1;
for(int i=0;i<vertexCount;i++)
{
degree = 0;
for(int j=0;j<vertexCount;j++)
{
if(g[i][j] == true)
degree++;
}
if(maxi < degree)
{
maxi = degree;
resultVertex = i;
}
}
return resultVertex;
}
void initializeAr(bool *subset,int len)
{
for(int i=0;i<len;i++)
subset[i] = false;
}
bool eq(bool *a,bool *b)
{
for(int i=0;i<vertexCount;i++)
if(a[i] != b[i])
return false;
return true;
}