回溯法实验(图的m着色问题)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
算法分析与设计实验报告第六次附加实验
cout<<endl;
}
else
for(int i=1;i<=m;i++)
{
x[t]=i;
if(ok(t)) Backtrack(t+1);//回溯,继续寻找下一层
x[t]=0;//回到最初状态,使x[1]继续尝试其他填色的可能解
}
}
测试结果
当输入图如下时:
结果如下:
1
2
4
3
5
只要输入边即可
当输入的图如下时:
结果如下:
附录:
完整代码(回溯法)
//图的m着色问题回溯法求解
#include<iostream>
using namespace std;
class Color
{
friend void mColoring(int,int,int **);
private:
bool ok(int k);
void Backtrack(int t);
int n, //图的顶点个数
m, //可用颜色数
**a, //图的邻接矩阵
*x; //当前解
long sum; //当前已找到的可m着色的方案数};
bool Color::ok(int k) //检查颜色可用性
{
for(int j=1;j<=n;j++)
if((a[k][j]==1)&&(x[j]==x[k])) //两个点之间有约束且颜色相同return false;
return true;
}
void Color::Backtrack(int t)
{
if(t>n) //到达叶子节点
{
sum++; //可行解+1
cout<<"着色: ";
for(int i=1;i<=n;i++) //输出可行解方案
cout<<x[i]<<" ";
cout<<endl;
}
else
for(int i=1;i<=m;i++)
{
x[t]=i;
if(ok(t)) Backtrack(t+1);//回溯,继续寻找下一层
x[t]=0;//回到最初状态,使x[1]继续尝试其他填色的可能解 }
}
void mColoring(int n,int m,int **a)
{
Color X;
//初始化X
X.n=n;
X.m=m;
X.a=a;
X.sum=0;
int *p=new int[n+1];
for(int i=0;i<=n;i++)
p[i]=0;
X.x=p;
cout<<"顶点: ";
for(int i=1;i<=n;i++) //用于输出结果
cout<<i<<" " ;
cout<<endl;
X.Backtrack(1); //从顶点1开始回溯
delete []p;
cout<<"解法个数:"<<X.sum<<endl;
}
int main()
{
int n;
int m;
cout<<"please input number of node:";
cin>>n;
cout<<"please input number of color:";
cin>>m;
int **a=new int*[n+1];
for(int i=0;i<=n;i++)
a[i]=new int[n+1];
for(int i=0;i<=n;i++) //利用抽象图实现图的邻接矩阵
for(int j=0;j<=n;j++)
a[i][j]=0;
int edge;
cout<<"please input adjacent edge number:";
cin>>edge;
int v,w;
cout<<"please inout adjacent edge:"<<endl; //只要输入边即可
for(int i=0;i<edge;i++)
{
cin>>v>>w; //由于是无向图,所以对应的邻接矩阵对应的边都有,即v->m,m->v都有边
a[v][w]=1;
a[w][v]=1;
}
mColoring(n,m,a);
system("pause");
return 0;
}。