Day20——图的m着色问题

再来讲讲函数之间的调用:
现在有三个函数——main()、func1()、func2()。
其中,main()函数中调用了func1(),并且func1()中调用了func2()。
三个函数的执行过程:main()先执行,执行到一半时调用func1(),会转向执行func1()中的代码,与main()一样,func1()执行一半时会转向执行func2()中的代码;当func2()中的代码执行结束的时候,会返回到func1()中继续执行之前还没执行的代码,直到func1()的代码执行结束后,又会继续执行main()中的代码。
如果在main()中用for循环把func1()包起来,则当上面的过程结束后,会开始下一次循环,重复上面的过程。
在这里插入图片描述
递归也就是函数调用自身,过程和上面的调用过程一样,可以照着慢慢理解。

简单化的背包问题:
有一个最多装8kg的背包,现有4个物品,每个物品至多装1次,问能否刚好装满8kg?
用一个数组来保存这4个物品,然后挨个尝试将物品装进背包使满足条件。
过程如图所示:
在这里插入图片描述
不难从图中发现有后进先出的特点,自然而然就会想到使用递归或栈,得出伪代码:

用数组weight来保存每个物体的重量,一共有n个物体,背包能背m kg
sum=0; //记录已经装入的重量 
bagTest(int currentIndex){
	if(sum==m){
		//表示能刚好装满
		return;
	}
	for(int i=currentIndex;i<n;i++){
		if(sum+weight[i]>m){
			//表示装入当前的物品会产生溢出,尝试装入下一个物品
			continue;
		}
		// 装入当前的物品,并继续尝试装入物品
		sum+=weight[i];
		bagTest(current+1)
	}
}

通过上面的代码可以尝试完所有的装入情形。

回到最初的问题——图的m着色问题
图中有n个顶点,要给这n个顶点着色,且要满足相邻的顶点的颜色不同,问有m种颜色能否满足条件?
其实,解题思路和上面的一样, 现在我们根据上面的思路尝试写出伪代码:

coloring(当前颜色curColor,当前着色顶点curNode){
	if(curNode>=n){
		//表示已经着色完所有顶点
		return;
	}
	for(int i=curColor;i<m;i++){
		if(能给当前顶点着色){
			coloring(curColor+1,curNode+1)
		}
	}
}

两个代码的形式都是一样的,只是一些判断需要根据不同问题进行调整而已,都是不断尝试的过程,如果发现不能实现目标时,则回退重新选择新的对象进行尝试。
代码部分:

/**
	 * 
	 *********************
	 * @Title: coloring
	 * @Description: TODO(Coloring.Output all possible schemes.)
	 *
	 * @param paraNumColors The number of colors.
	 *********************
	 *
	 */
	public void coloring(int paraNumColors) {
		// Step 1.Initialize.
		int tempNumNodes = connectivityMatrix.getRows();
		int[] tempColorScheme = new int[tempNumNodes];
		Arrays.fill(tempColorScheme, -1);

		coloring(paraNumColors, 0, tempColorScheme);
	}// Of coloring

	/**
	 * 
	 *********************
	 * @Title: coloring
	 * @Description: TODO(Coloring.Output all possible schemes.)
	 *
	 * @param paraNumColors       The number of colors.
	 * @param paraCurrentNumNodes The number of nodes that have been colored.
	 * @param paraCurrentColoring The array recording the coloring scheme.
	 *********************
	 *
	 */
	public void coloring(int paraNumColors, int paraCurrentNumNodes, int[] paraCurrentColoring) {
		// Step 1.Initialize.
		int tempNumNodes = connectivityMatrix.getRows();

		System.out.println("coloring: paraNumColors = " + paraNumColors + ", paraCurrentNumNodes = "
				+ paraCurrentNumNodes + ", paraCurrentColoring" + Arrays.toString(paraCurrentColoring));

		// A complete scheme.
		if (paraCurrentNumNodes >= tempNumNodes) {
			System.out.println("Find one:" + Arrays.toString(paraCurrentColoring));
			return;
		} // Of if

		for (int i = 0; i < paraNumColors; i++) {
			paraCurrentColoring[paraCurrentNumNodes] = i;
			if (!colorConflict(paraCurrentNumNodes + 1, paraCurrentColoring)) {
				coloring(paraNumColors, paraCurrentNumNodes + 1, paraCurrentColoring);
			}
		} // Of for i
	}// Of coloring

	/**
	 * 
	 *********************
	 * @Title: colorConflict
	 * @Description: TODO(Coloring conflict or not.Only compare the current last
	 *               node with previous ones.)
	 *
	 * @param paraCurrentNumNodes The current number of nodes.
	 * @param paraColoring        The current scheme.
	 * @return Conflict or not.
	 *********************
	 *
	 */
	public boolean colorConflict(int paraCurrentNumNodes, int[] paraColoring) {
		for (int i = 0; i < paraCurrentNumNodes - 1; i++) {
			if (connectivityMatrix.getValue(paraCurrentNumNodes - 1, i) == 0) {
				continue;
			} // Of if

			if (paraColoring[paraCurrentNumNodes - 1] == paraColoring[i]) {
				return true;
			} // Of if
		} // Of for i
		return false;
	}// Of colorConflict

	/**
	 * 
	 *********************
	 * @Title: coloringTest
	 * @Description: TODO(Coloring test)
	 *
	 *********************
	 *
	 */
	public static void coloringTest() {
		int[][] tempMatrix = { { 0, 1, 1, 0 }, { 1, 0, 0, 1 }, { 1, 0, 0, 0 }, { 0, 1, 0, 0 } };

		Graph tempGraph = new Graph(tempMatrix);

		// tempGraph.coloring(2);
		tempGraph.coloring(3);

	}// Of coloringTest
/**
	 * 
	 *********************
	 * @Title: main
	 * @Description: TODO(The entrance of the program)
	 *
	 * @param args Not used now.
	 *********************
	 *
	 */
	public static void main(String args[]) {
		System.out.println("Hello!");
		Graph tempGraph = new Graph(3);
		System.out.println(tempGraph);

		// Unit test.

		// getConnectivityTest();
		// breadthFirstTraverseTest();
		// depthFirstTraverseTest();

		coloringTest();

	}// Of main

运行结果:
在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值