精确覆盖问题学习笔记(三)——算法的初步实现

一、类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

你可能感兴趣的:(算法,精确覆盖问题,代码,算法)