【算法设计与分析基础】8、穷举 旅行商问题

package cn.xf.algorithm.ch03;

import java.util.LinkedList;

import org.apache.commons.lang.StringUtils;
import org.junit.Test;

/**
 * 
 * 功能:穷举 旅行商问题
 * @author xiaofeng
 * @date 2017年4月26日
 * @fileName TravelingSalesmanProblem.java
 *
 */
public class TravelingSalesmanProblem {
	
	/**
	 * 递归穷举所有路径,路径可以但是和不对!!!,求高手指点????
	 * @param data
	 * @param points
	 * @param paths
	 * @param count
	 * @param pre
	 * @param current
	 */
	public static void getPathAndCount(int data[][], LinkedList<Character> points, String paths, String pathCount,
			int count, char pre, char current) {
		if (points.size() == 0) {
			System.out.println(
					paths.toString() + " count:" + pathCount.substring(0, pathCount.length() - 2) + "=" + count);
		} else {
			int len = points.size();
			String seq = "abcd";
			// 保存当前路径节点
			// char oldpre = new Character(current);
			pre = new Character(current);
			pathCount = new String(pathCount);
			for (int i = 0; i < len; ++i) {
				// 这个是浅拷贝
				LinkedList<Character> newPoints = (LinkedList<Character>) points.clone();
				// pre = current;
				current = new Character(newPoints.get(i));
				newPoints.remove(i);

				int index1 = seq.indexOf(pre);
				int index2 = seq.indexOf(current);

				String newPaths = new String(paths);
				if (pre != current) {
					newPaths += "->" + current;
					if (index1 != -1 && index2 != -1) {
						count += data[index1][index2];
						pathCount += data[index1][index2] + " + ";
					}
				}
				getPathAndCount(data, newPoints, newPaths, pathCount, count, pre, current);
			}
		}
	}
	
	/**
	 * 换个说法,就是吧这个几个城市的全排列枚举出来
	 * @param data
	 * @param points
	 * @param paths
	 * @param pathCount
	 * @param count
	 * @param pre
	 * @param current
	 */
	public static void getPathAndCount2(int data[][], LinkedList<Character> points, String paths) {
		if(points.size() == 0){
			String seq = "abcd";
			String resultPath[] = paths.split("->");
			//在这个时候进行统计数据和
			String countPath = "";
			int count = 0;
			String pre = resultPath[0];
			String cur;
			for(int j = 1; j < resultPath.length; ++j){
				if(!StringUtils.isEmpty(countPath)){
					//如果是空,那么说明没有加入数据
					countPath += " + " ;
				} 
				//统计和路径
				cur = resultPath[j];
				countPath += data[seq.indexOf(pre)][seq.indexOf(cur)];
				//求和
				count += data[seq.indexOf(pre)][seq.indexOf(cur)];
				pre = resultPath[j];
			}
			
			System.out.println(paths + " count:" + countPath + " = " + count);
			return;
		}
		
		int len = points.size();
		for(int i = 0; i < len; ++i){
			//递归到节点全部加入,这里不能直接把原本的节点加入,应该是对一个新的链表操作,深拷贝
			LinkedList<Character> newPoints = (LinkedList<Character>) points.clone();
			String newPaths = new String(paths);
			Character cur = points.get(i);
			if(StringUtils.isNotEmpty(paths)){
				//如果路径非空,说明已经有节点
				newPaths += "->" + cur;
			} else {
				newPaths += cur;
			}
			newPoints.remove(i);	//移除当前加入路径的节点
			getPathAndCount2(data, newPoints, newPaths);
		}
	}
	
	@Test
	public void testGetPathAndCount(){
		int data[][] = {{0,2,5,7},{2,0,8,3},{5,8,0,1},{7,3,1,0}};
		LinkedList<Character> points = new LinkedList<Character>();
		points.add('a');points.add('b');points.add('c');points.add('d');
		String paths = "";
		String pathCount = "   ";
		int count = 0; char pre = '0'; char current = '0';
		TravelingSalesmanProblem.getPathAndCount2(data, points, paths);
//		TravelingSalesmanProblem.getPathAndCount(data, points, paths, pathCount, count, pre, current);
		
	}
	
	public static void main(String[] args) {
		String seq = "abcd";
		int data[][] = {{0,2,5,7},{2,0,8,3},{5,8,0,1},{7,3,1,0}};
		System.out.println(seq.indexOf('a'));
	}
}

  

第二个方法执行结果:

原文地址:https://www.cnblogs.com/cutter-point/p/6775079.html