精确覆盖问题学习笔记(三)——算法的初步实现
来源:互联网 发布:腾讯云备案域名买卖 编辑:程序博客网 时间:2024/04/29 10:27
一、类CExactCoverSolution的声明
#include<vector>#include<string>#include <algorithm>#include <iostream>using namespace std;//类型的定义typedef int ELEMENT_TYPE;typedef char SUBSET_NAME; typedef vector<int> ROW;typedef vector<ROW> MATRIX;typedef vector<ELEMENT_TYPE> FULL_SET;typedef vector<SUBSET_NAME> 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个数最少的列号//判断某一行是否全1bool isFullOneRow(int rowIndex) const;int getFullOneRow()const;//获取和第c列相交或者不的所有行void getRowNos(const int c,vector<int>& rows,int value=1)const;//获取和第r行相交或者不相交的所有列void getColumnNos(const int r,vector<int>& columns,int value=1)const;//获取和第r行无公共元素的各行void getOtherRows(const int r,vector<int>& otherrows)const; //在旧矩阵中去掉所有和row相交的行和列,获得新的矩阵,void getNewMatrix(const vector<int>& rows,const vector<int>& columns,MATRIX& matrix)const;void getNewNames(const vector<int>& 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<m_elementNum;++i){int newSum=0;if ((newSum=GetColumnCount(i))<sum){sum=newSum;ColumnIndex = i;}}return ColumnIndex;}bool CExactCoverSolution::search() {bool flag = false;int rowIndex=-1;//如果矩阵为空,则说明所有元素已经被得到已经得到可行解。if (m_matrix.size()==0) flag=true;//如果有全1的行,则将该行加入到可行解中,并返回真else if ((rowIndex=getFullOneRow())>=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<int> rows;getRowNos(c,rows);for(int i=0;i<rows.size();++i){int r=rows[i];//得到和本行不相交的所有列vector<int > columns;getColumnNos(r,columns,0);vector<int > 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;}//判断某一行是否全1bool CExactCoverSolution::isFullOneRow(int rowIndex) const{bool flag =true;for (int i=0;i<m_elementNum;++i)if (m_matrix[rowIndex][i]==0){flag=false;break;}return flag;}int CExactCoverSolution::getFullOneRow() const{bool flag =false;int rowIndex = -1;for (int i=0;i<m_subsetNum && !flag;++i){if (isFullOneRow(i)){rowIndex = i;break;}}return rowIndex;}int CExactCoverSolution::GetColumnCount( int columnIndex ) const{int sum=0;for(int i=0;i<m_subsetNum;++i)sum += m_matrix[i][columnIndex];return sum;}void CExactCoverSolution::getRowNos( const int c,vector<int>& rows,int value) const{for (int i=0;i<m_subsetNum;++i)if (m_matrix[i][c]==value)rows.push_back(i);}void CExactCoverSolution::getColumnNos( const int r,vector<int>& columns,int value) const{for (int i=0;i<m_elementNum;++i)if (m_matrix[r][i]==value)columns.push_back(i);}void CExactCoverSolution::getOtherRows( const int r,vector<int>& otherrows )const{for(int i=0;i<m_subsetNum;++i){bool flag=true;for(int j=0;j<m_elementNum;++j)if (m_matrix[i][j]==m_matrix[r][j] && m_matrix[r][j]==1){flag=false;break;}if (flag)otherrows.push_back(i);}}void CExactCoverSolution::getNewNames( const vector<int>& rows,SUBSET_NAMES& names ) const{for(int i=0;i<rows.size();++i)names.push_back(m_subsetNames[rows[i]]);}void CExactCoverSolution::getNewMatrix( const vector<int>& rows,const vector<int>& columns,MATRIX& matrix ) const{matrix=MATRIX(rows.size(),vector<int>(columns.size()));for(int i=0;i<rows.size();++i)for(int j=0;j<columns.size();++j)matrix[i][j]=m_matrix[rows[i]][columns[j]];}void CExactCoverSolution::print(ostream&os ) const{os << m_solution[0];for (int i=1;i<m_solution.size();++i){os << ","<<m_solution[i];}}
三、测试代码
#include <cstdlib>#include <iostream>#include <fstream>#include <vector>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<vector<int> > M(SUBSET_NUM,vector<int>(ELEMENT_NUM));for (int i=0;i<SUBSET_NUM;++i)for (int j=0;j<ELEMENT_NUM;++j)M[i][j]=Matrix[i][j];FULL_SET values(U,U+ELEMENT_NUM);SUBSET_NAMES names(NAMES,NAMES+SUBSET_NUM);CExactCoverSolution s(M,names);if (s.search())s.print();cout<<endl;system("pause");return 0;}
四、运行结果
B,D,F
- 精确覆盖问题学习笔记(三)——算法的初步实现
- 精确覆盖问题学习笔记(五)——优化算法的实现代码
- 精确覆盖问题学习笔记(二)——基本算法
- 精确覆盖问题学习笔记(四)——算法优化
- 精确覆盖问题的回溯算法(一)——问题描述
- 跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题
- 跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题
- 跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题
- 跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题
- 跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题
- 跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题
- 跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题
- 跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题
- 跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题
- 【算法学习笔记】19.算法设计初步 最大子列和问题的三种方法
- 【精确覆盖问题】DLX算法
- [转载链接]跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题
- DLX (Dancing Links/舞蹈链)算法——求解精确覆盖问题
- sysfs文件系统
- invoke伪指令
- Keil总是出现“File has been changed outside the editor, reload?”提示
- mpeg4的解码演示程序
- (转载)带着项目学PHP第四讲 - 添加自动收缩浮动的客服(QQ客服,在线MSN,旺旺),兼容IE,Firefox
- 精确覆盖问题学习笔记(三)——算法的初步实现
- sql语句中select的查询顺序
- shell脚本 调用 另一个 shell脚本的三种方法
- javascript实现抢购倒计时Demo程序
- Centos配置固定ip
- android流程图
- jQuery多种循环展示插件roundabout
- 数据环境设计器
- 在Myeclipse buildpath 加server lib