一、类CExactCoverSolution的声明
#include
#include
#include
#include
using namespace std;
//类型的定义
typedef int ELEMENT_TYPE;
typedef char SUBSET_NAME;
typedef vector ROW;
typedef vector MATRIX;
typedef vector FULL_SET;
typedef vector SUBSET_NAMES;
typedef SUBSET_NAMES SOLUTION;
class CExactCoverSolution
{
public:
CExactCoverSolution(const MATRIX& matrix
,const SUBSET_NAMES& names
);
~CExactCoverSolution(void);
const MATRIX& m_matrix; //0-1矩阵
SOLUTION m_solution; //当前可行解
const SUBSET_NAMES& m_subsetNames; //子集的名字
const int m_elementNum; //元素的个数
const int m_subsetNum; //子集的数目
//计算某一列的和
int GetColumnCount(int columnIndex)const;
int GetMinColumnIndex(int &sum)const; //找出含1个数最少的列号
//判断某一行是否全1
bool isFullOneRow(int rowIndex) const;
int getFullOneRow()const;
//获取和第c列相交或者不的所有行
void getRowNos(const int c,vector& rows,int value=1)const;
//获取和第r行相交或者不相交的所有列
void getColumnNos(const int r,vector& columns,int value=1)const;
//获取和第r行无公共元素的各行
void getOtherRows(const int r,vector& otherrows)const;
//在旧矩阵中去掉所有和row相交的行和列,获得新的矩阵,
void getNewMatrix(const vector& rows,const vector& columns,MATRIX& matrix)const;
void getNewNames(const vector& rows,SUBSET_NAMES& names)const;
public:
bool search(); //求解
public:
void print(ostream&os=cout)const;
};
二、实现
#include "ExactCoverSolution.h"
CExactCoverSolution
::CExactCoverSolution(const MATRIX& matrix
,const SUBSET_NAMES& names
)
:m_matrix(matrix)
,m_subsetNames(names)
,m_elementNum(matrix[0].size())
,m_subsetNum(matrix.size())
{
}
CExactCoverSolution::~CExactCoverSolution(void)
{
}
int CExactCoverSolution::GetMinColumnIndex( int &sum ) const
{
int ColumnIndex=0;
sum=GetColumnCount(ColumnIndex);
for(int i=1;i=0)
{
m_solution.push_back(m_subsetNames[rowIndex]);
flag =true;
}
else
{
int sum=0;
int c =GetMinColumnIndex(sum);
if (sum==0)
flag =false; //如果有全0的列,则说明此时一定无解
else
{
//得到和第c列相交的所有行列表
vector rows;
getRowNos(c,rows);
for(int i=0;i columns;
getColumnNos(r,columns,0);
vector other;
getOtherRows(r,other);
SUBSET_NAMES names;
getNewNames(other,names);
MATRIX matrix;
getNewMatrix(other,columns,matrix);
CExactCoverSolution s(matrix,names);
flag = s.search();
if (flag)
{
m_solution.push_back(m_subsetNames[r]);
m_solution.insert(m_solution.end(),s.m_solution.begin(),s.m_solution.end());
break;
}
}
}
}
return flag;
}
//判断某一行是否全1
bool CExactCoverSolution::isFullOneRow(int rowIndex) const
{
bool flag =true;
for (int i=0;i& rows,int value) const
{
for (int i=0;i& columns,int value) const
{
for (int i=0;i& otherrows )const
{
for(int i=0;i& rows,SUBSET_NAMES& names ) const
{
for(int i=0;i& rows,const vector& columns,MATRIX& matrix ) const
{
matrix=MATRIX(rows.size(),vector(columns.size()));
for(int i=0;i
三、测试代码
#include
#include
#include
#include
using namespace std;
#include "ExactCoverSolution.h"
const int ELEMENT_NUM=7 ; //元素的个数
const int SUBSET_NUM=6; //子集的个数
const int U[ELEMENT_NUM]={1,2,3,4,5,6,7}; //全集
const char NAMES[SUBSET_NUM]={'A','B','C','D','E','F'}; //各子集的名字
//0-1矩阵
const int Matrix[SUBSET_NUM][ELEMENT_NUM]={
{1,0,0,1,0,0,1}
,{1,0,0,1,0,0,0}
,{0,0,0,1,1,0,0}
,{0,0,1,0,1,1,0}
,{0,1,1,0,0,1,1}
,{0,1,0,0,0,0,1}
};
int main(int argc,char* argv[])
{
vector > M(SUBSET_NUM,vector(ELEMENT_NUM));
for (int i=0;i
四、运行结果
B,D,F