图着色算法描述:
https://www.jianshu.com/p/6a52b390f5fa
给定无向连通图和m种不同的颜色。用这些颜色为图G的各顶点着色,每个顶点着一种颜色。是否有一种着色法使G中每条边的两个顶点有不同的颜色。
这个问题是图的m可着色判定问题。若一个图最少需要m种颜色才能使图中每条边相连接的两个顶点着不同颜色,称这个数m为这个图的色数。
求一个图的色数m称为图的m可着色优化问题。 给定一个图以及m种颜色,请计算出涂色方案数。
图的着色算法分析:
- Color存储着色方案。
- 从第一个顶点开始着色,判断是否安全。
- 安全则继续着色直到顶点全部被着色,输出可行的着色方案
- 若不安全则停止着色方案,回溯,测试下一方案
本人使用的是C#,以下是完整代码,输入为顶点数,颜色数和图的连接矩阵。IsSafe函数判断安全与否,ColorGraph函数具体着色。递归实现回溯。
using System; namespace graphColoring { class Program { static void Main(string[] args) { Console.WriteLine("请输入顶点数:"); string numberN = Console.ReadLine(); int N = Int32.Parse(numberN); Console.WriteLine("请输入颜色数:"); string numberColor = Console.ReadLine(); int M= Int32.Parse(numberColor); int[, ] matN = new int[N, N]; //无向图的邻接矩阵 Console.WriteLine("请输入无向图的邻接矩阵:"); for(int i = 0; i < N; i++) { string str = Console.ReadLine(); string[] temp = str.Split(" ".ToCharArray()); for(int j = 0; j < N; j++) { matN[i, j] = Int32.Parse(temp[j]); } } int[,] MatN = matN; graph myGraph = new graph(N,M,MatN); Console.WriteLine("所有的方案:"); myGraph.graphDeal(); } } class graph { private int n; //顶点数 private int m; //颜色数 private int[,] matN; //邻接矩阵 private int[] color; //着色方案 public graph(int N,int M,int[,] MatN) { n = N; m = M; matN = MatN; color = new int[n]; for (int i = 0; i < n; i++) color[i] = 0; } public void graphDeal() { ColorGraph(matN, m, color, 0); } private bool IsSafe(int[, ] matN,int[] color, int n1, int i) { for(int j = 0; j < n; j++) if (matN[n1, j] == 1 && i == color[j]) return false; return true; } private void ColorGraph(int[, ] matN,int m,int[] color,int n1) { if (n == n1) { printSolution(color); return; } for(int i = 1; i <= m; i++) { if (IsSafe(matN, color, n1, i)) { color[n1] = i; ColorGraph(matN, m, color, n1 + 1); color[n1] = 0; //如果缺少则color无法在每个正确或者错误的方案完成后重置 } } } void printSolution(int[] color) { foreach(int i in color) { Console.Write(i+" "); } Console.WriteLine(); } } }