编程题目:基于实现韦尔奇·鲍威尔法(贪婪算法)对图进行着色。
编程内容及要求:
编写程序,实现输入图G,基于韦尔奇·鲍威尔法对图G的结点进行着色,输出对应的一个正常着色。
编程语言可选择C、C++、Java或Python。
正常着色输出格式示例(设图G的结点为v1, v2, v3,颜色用1, 2, 3等数字代表):
------------------
v1:1,v2:2,v3:3
------------------
编程目的:学会用程序语言实现图的表示,基本操作,以及着色。
编程语言:
C++
程序设计简要描述:
储存结构:采用二维数组(矩阵)来储存用户输入的图的信息(接邻矩阵),建立Vertex结构体来储存顶点信息,文本文件graph.txt储存输出。
主要算法:用for循环遍历数组接受用户输入,接着代码实现实现韦尔奇·鲍威尔法(贪婪算法):
(1) 将图 G 中的节点按度数的递减顺序进行排列(这种排列可能不是唯一的,因为有些节点的度数可能相同)
(2) 用第一种颜色对第一个节点着色,并按排列顺序对与前面着色节点不邻接的每一节点着上同样的颜色
(3) 用第二种颜色对尚未着色的节点重复步骤 (2),用第三种颜色继续这种做法,直到所有的节点全部着上色为止
Vertex结构体设计:color储存被赋予的颜色,degree储存该顶点的度,方便后续进行顶点间度的比较,flag储存顶点的位置(序号)。
输出的字符文件graph.txt内容(粘贴):
---------------------------------
v2:1,v3:2,v4:2,v5:3,v1:3
---------------------------------
源程序代码:
#include <iostream>
#include <algorithm>
#include <fstream>
#define MAX 100
using namespace std;
int c[MAX][MAX];
int n;
int count = 0;
struct Vertex
{
int color;
int degree;
int flag; // 标记原始点的位置
} vertex[MAX];
// 排序前的副本
Vertex copys[MAX];
// 初始化顶点颜色,并计算每个点的度数
void getDegree()
{
for (int i = 1; i <= n; i++)
{
vertex[i].color = vertex[i].degree = 0;
vertex[i].flag = i;
for (int j = 1; j <= n; j++)
vertex[i].degree += c[i][j];
}
}
// 按顶点度数从大到小排序
bool cmp(Vertex a, Vertex b)
{
return a.degree > b.degree;
}
int main()
{
printf("输入顶点数:");
cin >> n;
printf("输入无向图的邻接矩阵:\n");
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
cin >> c[i][j];
getDegree();
// 排序前保留一份副本
for (int i = 1; i <= n; i++) {
copys[i].color = 0;
copys[i].degree = vertex[i].degree;
copys[i].flag = vertex[i].flag;
}
sort(vertex + 1, vertex + n + 1, cmp);
int coloredNum = 0;
int k = 0;
fstream write("./graph.txt", ios::out | ios::trunc);
write << "---------------------------------" << endl;
while (coloredNum < n)
{
k++;
for (int i = 1; i <= n; i++)
{
// 如果没有着色
if (vertex[i].color == 0)
{
bool ok = true;
for (int j = 1; j <= n; j++)
{
// 如果相邻顶点有相同颜色
if (c[vertex[i].flag][j] == 1 && copys[j].color == k)
{
ok = false;
break;
}
}
// 相邻顶点有相同颜色,直接跳过
if (!ok)
continue;
// 相邻顶点没有相同颜色,则对当前节点着色
vertex[i].color = copys[vertex[i].flag].color = k;
coloredNum++;
//控制格式化输出的逗号
if (::count < n - 1)
write << 'v' << vertex[i].flag << ':' << vertex[i].color << ',';
else
write << 'v' << vertex[i].flag << ':' << vertex[i].color;
::count ++;
}
}
}
write << endl << "---------------------------------";
}