C++ 图论应用:项目日程安排算法详解

本文将通过 C++ 代码实现项目日程安排算法,并用图论的思想,利用邻接矩阵,对用户输入的项目信息进行建图,并通过贪心算法对其进行染色,最终实现项目日程表的可视化输出。

代码解析

#include <iostream>
#include <vector>
#include <algorithm>
#include <fstream>
#include <string.h>
#include <stdio.h>
#include <windows.h>

using namespace std;

int map[49] = { 0 };

void Create(int a[]) { //根据用户输入进行建图
	for (int i = 0; i < 3; i++)
		for (int j = 0; j < 3; j++)
			if ((a[i] != a[j]) && (a[i] != 0) && (a[j] != 0)) {
				map[(a[i] - 1) * 7 + (a[j] - 1)] = 1;
			}
}

struct Node { //图结点
	int index;//结点在矩阵中的行数即位置
	int degree;//结点度数,用于根据从大到小的度数关系进行涂色
	int mark;//结点染色标记
};

string name[] = { '标枪', '铅球', '铁饼', '100m', '200m', '跳远', '跳高' };

bool cmp(Node a, Node b) { //自定义'小于'
	return a.degree > b.degree;
}

void Print(vector <int>mark, int n, vector <Node>node, int Mark) { //创建可视化图表
	int a[10] = { 0 };//存储标记对应的项目数
	int b = 0, c = 1;
	for (int j = 0; j < mark.size(); j++) { //同一标记对应项目数的赋值
		for (int i = 0; i < n; i++)
			if (node[i].mark == mark[j])
				a[j]++;
	}
	int max = a[0];
	for (int j = 0; j < mark.size() - 1; j++) { //确定项目日程表中列数的最大值
		if (a[j + 1] > max)
			max = a[j + 1];
	}
	cout << '  _________________________________' << endl;//实现项目日程的可视化
	for (int p = 0; p < Mark; p++) {
		cout << ' |        |        |       |       |' << endl;
		if (c == 1)
			cout <<  '|' <<  '|';
		else if (c == 2)
			cout <<  '|' <<  '|';
		else if (c == 3)
			cout <<  '|' <<  '|';
		else if (c == 4)
			cout <<  '|' <<  '|';
		else if (c == 5)
			cout <<  '|' <<  '|';
		for (int i = 0; i < n; i++) {
			if (node[i].mark == c) {
				cout << name[node[i].index] << '    |';
				b++;
			}
		}
		if (b < max)
			for (int i = 0; i < max - b; i++)
				cout << '        |';
		b = 0;
		c++;
		cout << endl;
		cout << '  ------------------' << endl;
	}
}

int fillcolor(int map[], int n) { //涂色
	cout << '邻接矩阵' <<  endl;
	int Mark = 0;
	vector<int>mark;//动态标记集
	vector<Node>node;//动态结点集
	node.resize(n);//为结点集分配空间
	for (int i = 0; i < n; i++) { //统计图中结点的度
		node[i].degree = node[i].mark = 0;//度数、标记均初始化为0
		node[i].index = i;
		for (int j = 0; j < n; j++) {
			if (map[i * n + j] == 1)
				node[i].degree++;
		}
	}
	sort(node.begin(), node.end(), cmp);//将图结点降序排列

	for (int i = 0; i < n; i++) {
		for (int j = 0; j < mark.size(); j++) { //取染色集元素进行染色
			if (node[i].mark == 0)
				node[i].mark = mark[j];
			for (int k = 0; k < n; k++) {
				if ((map[node[i].index * n + k] == 1) && (node[k].mark == node[i].mark)) { //两结点相邻且颜色相同,取消标记
					node[i].mark = 0;
					break;
				}
			}
		}
		if (node[i].mark == 0) {
			mark.push_back(++Mark);
			node[i].mark = mark.back();
		}
	}
	Print(mark, n, node, Mark); //创建可视化图表
	return Mark;//返回所需场次
};

int main() {
	cout << '各项目对应编号为:标枪(1),铅球(2),铁饼(3),100m(4),200m(5),跳远(6),跳高(7) ' << endl;
	cout << '请依次将选手所报项目编号输入' << endl;
	int a[3] = { 0 };
	string b[5] = { '张三', '李四', '王五', '赵六', '李七' };
	for (int i = 0; i < 5; i++) {
		cout << '请输入 ' << b[i] << ' 所报项目编号:';
		for (int j = 0; j < 3; j++) {
			a[j] = cin.get() - 48;
			if (j == 2 && a[j] != -38)
				cin.get();
			else if (a[j] == -38) {
				a[j] = 0;
				break;
			}
		}
		Create(a);
	}
	for (int i = 0; i < 7; i++) {
		for (int j = 0; j < 7; j++)
			cout << map[i * 7 + j] << ' ';
		cout << endl;
	}
	int n = fillcolor(map, 7);
	cout << '将需要比赛' << n << '场' <<  endl;
	system('pause');
}

难点处理

在完成题目的过程中,最难处理的问题是如何根据用户输入建立图结构。这个问题的解决方法是使用一个大小为 49 的一维数组来表示图的邻接矩阵,通过遍历用户输入的项目编号,将对应的图结点之间的关系标记为 1,表示相邻。这样就成功地建立了图结构。

代码解释

  1. 建立图结构:
    • 使用一个大小为 49 的数组 map 来表示图的邻接矩阵,其中 map[i * 7 + j] = 1 表示第 i 个项目和第 j 个项目需要在不同场次进行。
    • 函数 Create(int a[]) 根据用户输入的项目编号建立邻接矩阵。
  2. 贪心染色算法:
    • 使用 fillcolor(int map[], int n) 函数进行图染色,该函数使用贪心算法对图结点进行染色,以确保相邻结点颜色不同。
    • 函数首先统计每个结点的度数,并根据度数从大到小排序。
    • 然后,对于每个结点,依次遍历已有的染色集,如果当前结点与已染色结点不相邻,则使用该颜色对当前结点进行染色,否则继续尝试其他颜色。
    • 如果当前结点没有找到合适的颜色,则使用新的颜色对当前结点进行染色,并将该颜色加入染色集中。
  3. 可视化输出:
    • 函数 Print(vector <int>mark, int n, vector <Node>node, int Mark) 使用一个二维数组来存储染色结果,并通过循环遍历数组,将染色结果输出到屏幕。
    • 输出格式为:将每个项目名称列出,并在其下方用 '|' 连接,同一场次的项目用相同的 '|' 连接,不同的场次用不同的 '|' 连接,并通过空格调整格式,以实现可视化效果。

总结

本文详细解析了如何利用 C++ 图论算法解决项目日程安排问题,并通过实例代码演示了算法的实现过程。希望本文能帮助读者理解图论算法在实际应用中的作用。

C++ 图论应用:项目日程安排算法详解

原文地址: https://www.cveoy.top/t/topic/fwVa 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录