JAVA算法:无向图的着色(Graph Coloring)问题

图着色(Graph Coloring)问题


图着色问题(Graph Coloring Problem, GCP) 又称着色问题,是最著名的NP—完全问题之一。道路着色问题(Road Coloring Problem)是图论中最著名的猜想之一。

数学定义给定一个无向图 G=(V, E),其中V为顶点集合,E为边集合,图着色问题即为将V分为K个颜色组,每个组形成一个独立集,即其中没有相邻的顶点。其优化版本是希望获得最小的K值。

图的m—着色判定问题

给定无向连通图G和m种不同的颜色。用这些颜色为图G的各顶点着色,每个顶点着一种颜色,是否有一种着色法使G中任意相邻的2个顶点着不同颜色?


图的m—着色优化问题

若一个图最少需要m种颜色才能使图中任意相邻的2个顶点着不同颜色,则称这个数m为该图的色数。求一个图的最小色数m的问题称为m—着色优化问题。
 

基本贪心着色算法

  1. 第一步:用第一种颜色给第一个顶点着色。
  2. 第二步:对剩余的 V-1 顶点执行以下操作:
  • 考虑当前选取的顶点,并用以前从未使用过的最低编号的颜色为相邻的顶点着色。
  • 如果所有以前使用的颜色都出现在于 v 相邻的顶点上,则为其指定新颜色。

算法实现

package com.bean.algorithm.graph;

import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedList;

public class GraphColoring {
	private int V; // 顶点的数量(vertices)
	private LinkedList adj[]; // 邻接表(Adjacency List)

	// 构造方法
	GraphColoring(int v) {
		V = v;
		adj = new LinkedList[v];
		for (int i = 0; i < v; ++i)
			adj[i] = new LinkedList();
	}

	// 向图中加入边(Edge)
	void addEdge(int v, int w) {
		adj[v].add(w);
		adj[w].add(v); // 无向图( undirected)
	}

	// 分配颜色 (从0号开始为所有的节点) 并且打印所有的颜色
	void greedyColoring() {
		int result[] = new int[V];

		// 初始化所有未分配的顶点
		Arrays.fill(result, -1);

		// 为第一个顶点(vertex)分配第一种颜色 
		result[0] = 0;

		//使用available数组存放所有可以分配的颜色. False
		//available[cr]的值为false时,表示颜色cr可能已经分配给与它相邻的顶点了
		boolean available[] = new boolean[V];

		// 初始时,所有的颜色都可以使用
		Arrays.fill(available, true);

		// 为剩下的  V-1 顶点(vertices)分配颜色
		for (int u = 1; u < V; u++) {
			// 迭代处理所有的邻接点( adjacent vertices)并且标记他们的颜色为不可用( unavailable)
			Iterator it = adj[u].iterator();
			while (it.hasNext()) {
				int i = it.next();
				if (result[i] != -1)
					available[result[i]] = false;
			}

			// 找到第一个可用的颜色( available color)
			int cr;
			for (cr = 0; cr < V; cr++) {
				if (available[cr])
					break;
			}

			result[u] = cr; // 赋值

			// 将所有的颜色值为 true并且开始下一次迭代(next iteration)
			Arrays.fill(available, true);
		}

		// 输出结果
		for (int u = 0; u < V; u++)
			System.out.println("Vertex " + u + " --->  Color " + result[u]);
	}

	public static void main(String args[]) {
		GraphColoring g1 = new GraphColoring(5);
		g1.addEdge(0, 1);
		g1.addEdge(0, 2);
		g1.addEdge(1, 2);
		g1.addEdge(1, 3);
		g1.addEdge(2, 3);
		g1.addEdge(3, 4);
		System.out.println("Coloring of graph 1");
		g1.greedyColoring();

		System.out.println();
		GraphColoring g2 = new GraphColoring(5);
		g2.addEdge(0, 1);
		g2.addEdge(0, 2);
		g2.addEdge(1, 2);
		g2.addEdge(1, 4);
		g2.addEdge(2, 4);
		g2.addEdge(4, 3);
		System.out.println("Coloring of graph 2 ");
		g2.greedyColoring();
	}
}

程序运行结果:

Coloring of graph 1
Vertex 0 --->  Color 0
Vertex 1 --->  Color 1
Vertex 2 --->  Color 2
Vertex 3 --->  Color 0
Vertex 4 --->  Color 1

Coloring of graph 2 
Vertex 0 --->  Color 0
Vertex 1 --->  Color 1
Vertex 2 --->  Color 2
Vertex 3 --->  Color 0
Vertex 4 --->  Color 3
 

你可能感兴趣的:(算法分析与设计,算法分析与设计,JAVA算法设计,无向图着色算法,无向图着色)