基于实现韦尔奇·鲍威尔法(贪婪算法)对图进行着色

编程题目:基于实现韦尔奇·鲍威尔法(贪婪算法)对图进行着色。

编程内容及要求:

编写程序,实现输入图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 
#include 
#include 
#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 << "---------------------------------";
}

你可能感兴趣的:(算法,c++)