算法基础之穷举算法

Posted by Naah on Saturday, Sep 09,2017 11:28:38

穷举算法

穷举法的基本思想是根据题目的部分条件确定答案的大致范围,并在此范围内对所有可能的情况逐一验证,直到全部情况验证完毕。若某个情况验证符合题目的全部条件,则为本问题的一个解;若全部情况验证后都不符合题目的全部条件,则本题无解。穷举法也称为枚举法。

算法应用

泊松分酒问题

有一个12品脱(pint)的酒瓶,里面装满葡萄酒,另有8品脱和5品脱的瓶子各一个。问如何从中分出6品脱的酒出来?

使用穷举算法,并且使用递归思想

/**
 * 泊松分酒
 *
 * @author Naah
 *
 */
public class BoSongShareWine {

	// 第一个瓶子默认12L瓶子
	private int bottle1 = 12;

	// 第二个瓶子默认8L瓶子
	private int bottle2 = 8;

	// 第三个瓶子默认5L瓶子
	private int bottle3 = 5;

	/**
	 * 默认构造函数
	 */
	public BoSongShareWine() {
		super();
	}

	/**
	 * 自定义瓶子容量函数
	 * @param bottle1 第一个瓶子容量
	 * @param bottle2 第二个瓶子容量
	 * @param bottle3 第三个瓶子容量
	 */
	public BoSongShareWine(int bottle1, int bottle2, int bottle3) {
		super();
		this.bottle1 = bottle1;
		this.bottle2 = bottle2;
		this.bottle3 = bottle3;
	}

	/**
	 * 分酒方法
	 * @param getWine 目标容量
	 * @param capacity1 第一个瓶子初始容量
	 * @param capacity2 第二个瓶子初始容量
	 * @param capacity3 第三个瓶子初始容量
	 * @param num 分酒的次数
	 * @return 分酒的次数
	 */
	public int shareWine(int getWine, int capacity1, int capacity2, int capacity3, int num) {
		//输出当前瓶子的酒量
		System.out.println("1瓶:" + capacity1 + " 2瓶:" + capacity2 + " 3瓶:" + capacity3);

		//如果右瓶子分出了目标容量,则结束
		if (capacity1 == getWine || capacity2 == getWine || capacity3 == getWine) {
			return 0;
		}

		//如果2瓶子不为空,3瓶子不满
		if (capacity2 != 0 && capacity3 != bottle3) {

			//如果2瓶子+3瓶子的酒不溢出3瓶子
			if (capacity2 + capacity3 <= bottle3) {

				//将2瓶子的酒倒入3瓶子
				num += shareWine(getWine, capacity1, 0, capacity2 + capacity3, num);

			//否则
			} else {

				//将3瓶子装满,2瓶子含有剩余部分
				num += shareWine(getWine, capacity1, capacity2 - (bottle3 - capacity3), bottle3, num);
			}

		//如果3瓶子满了
		} else if (capacity3 == bottle3) {

			//如果3瓶子+1瓶子的酒不溢出1瓶子
			if (capacity3 + capacity1 <= bottle1) {

				//将3瓶子的酒装入1瓶子
				num += shareWine(getWine, capacity3 + capacity1, capacity2, 0, num);

			//否则
			} else {

				//将1瓶子装满,3瓶子含有剩余部分
				num += shareWine(getWine, bottle1, capacity2, capacity3 - (bottle1 - capacity1), num);
			}

		//如果2瓶子为空
		} else if (capacity2 == 0) {

			//如果1瓶子的酒大于2瓶子的容量
			if (capacity1 >= capacity2) {

				//将2瓶子装满,1瓶子含有剩余部分
				num += shareWine(getWine, capacity1 - bottle2, bottle2, capacity3, num);

			//否则
			} else {

				//将1瓶子的酒都导入2瓶子
				num += shareWine(getWine, 0, capacity1, capacity3, num);
			}
		}
		return num;
	}

	public static void main(String[] args) {
		BoSongShareWine share = new BoSongShareWine();

		//目标酒量为6
		//1瓶子默认12升酒
		//2瓶子默认0升酒
		//3瓶子默认0升酒
		//初始次数为1
		System.out.println(share.shareWine(6, 12, 0, 0, 1));
	}
}