图的着色问题-回溯解决
2016-11-22 13:37
183 查看
问题描述:
图着色问题(Graph Coloring Problem, GCP) 又称着色问题,是最著名的NP-完全问题之一。数学定义:给定一个无向图G=(V, E),其中V为顶点集合,E为边集合,图着色问题即为将V分为K个颜色组,每个组形成一个独立集,即其中没有相邻的顶点。其优化版本是希望获得最小的K值。
图的m-着色判定问题——给定无向连通图G和m种不同的颜色。用这些颜色为图G的各顶点着色,每个顶点着一种颜色,是否有一种着色法使G中任意相邻的2个顶点着不同颜色?
问题简单分析:
这个问题和八皇后还有求子集和等问题都具有类似之处,其核心在通过遍历找到所有的问题子集 ,但是在递归遍历的时候,都在加一个判断,将那些明显不满足条件的情况给直接排出,减少问题的规模,其实这类问题,在递归遍历的时候都是类似与对一颗树的便利每个节点相当走到此时的状态,然后再判断此时的状态是否能继续走下去,如果不能就将其回溯到上一个节点,避免浪费时间。下面以一个简单例子作分析:
如图分析如下:
具体代码如下:
import java.util.Scanner; public class Main { static int[][] e = new int[5][5]; //存储各个边的情况连同为1 不连为0 static int[] state = new int[e.length]; //表示当前染色情况 static int Colornum = 3;//共有几种颜色 static void sear(int index) {//递归函数 if (isOk(index)) {//判断当前状态能否满足条件 if (index == e.length - 1) {//若已经染到最后一个节点则输出情况 Show(index); } else { for (int i = 1; i <= Colornum; i++) {//将所有 的颜色情况给遍历 state[index + 1] = i;//假如下一个染色, sear(index + 1);//进入下次递归并且在递归的入口判断是否满足条件 } } } } //打印当前状态 private static void Show(int index) { for (int i = 1; i <= index; i++) { System.out.println(i + "is " + "Color " + state[i]); } System.out.println(); } //判断是否能染色 private static boolean isOk(int index) { for (int i = 1; i < index; i++) { if (e[index][i] == 1 && state[i] == state[index])//当两个节点是连同并且颜色一样则不满足返回false return false; } return true; } public static void main(String[] args) { Scanner in = new Scanner(System.in); int n = in.nextInt(); //输入边的情况 for (int i = 1; i <= n; i++) { int a = in.nextInt(); int b = in.nextInt(); e[a][b] = 1; e[b][a] = 1; } //从0开始递归,但0不是一个节点 sear(0); } }
代码测试部分结果对于三色:
i is Color j 代表 i 节点为j颜色相关文章推荐
- c++实现回溯算法解决图的M着色问题
- Ubuntu中设置vi编辑器语法着色和高亮显示,解决vi方向键问题
- pku 1129 Channel Allocation(回溯(经典的图着色问题))
- 图的着色问题-回溯法
- 解决fedora64下vim不能语法着色问题
- Java实现回溯法解决0-1背包问题
- 解决Visual Assist .NET 在中文版 VS 2003 中syntax coloring着色混乱的问题
- 图的m着色问题(回溯)
- 用回溯的思想解决排列问题
- 回溯算法——解决n皇后问题
- 回溯法解决喝酒问题
- 回溯法-------图的m--着色问题
- lv 算法与回溯法相结合解决n皇后问题
- 回溯算法 图m着色问题
- Ubuntu 9.10中设置vi编辑器语法着色和高亮显示,解决vi方向键问题
- C#WPF实现回溯算法解决八皇后问题
- 回溯经典-m图着色问题(和地图4色问题的区别)
- 回溯经典-m图着色问题
- 火车调度问题的回溯法解决
- 回溯法解决0-1背包问题