算法导论之第十五章-动态规划之装配线调度

装配线调度只有两条n个节点的装配线,如果把所有可能枚举出来,那就是2^n,当n很大时,将是个很大的数量级,所以不能把所有可能都枚举,这时候可以如此考虑,经过S(0,j)的节点只有两条路,要么从S(0,j-1),要么从S(1,j-1),我们只要知道这两个节点最短路径就行,以此推理,两条n个节点的装配线,我们只要知道各个节点的最短时间,计算量将是2n,数量级完全不一样了。
但是我的代码还是用的递归,如果不加限制,将还是2^n数量级,所以我用静态变量来保存部分返回值,这样就做到将时间缩短的要求。
枚举有个缺陷,就是深度不能太深,所以当n过大时,还是会抛错。
当然不过不用递归,也不能太大n,因为为了保留路径,我创建了过多的对象。
现在保存一些代码
轨道对象

package test2019.mon02.动态规划.装配线调度;

import java.util.Arrays;

/** 
 * Filename:  S.java 
 * Description: 流水线
 * Company:     sendinfo.com.cn Inc.
 * @author: guzhangyan
 * @date: 2019年2月13日 上午9:02:46 
 */
public class S {

	private int e;//进入流水线的时间
	
	private int x;//离开流水线时间
	
	private int[] a;//在每个节点逗留时间
	
	private int[] t;//在每个节点跳转到另一条线路的时间(因为在最后一个节点无需跳转,所以长度比a长度少1)

	public int getE() {
		return e;
	}

	public void setE(int e) {
		this.e = e;
	}

	public int getX() {
		return x;
	}

	public void setX(int x) {
		this.x = x;
	}

	public int[] getA() {
		return a;
	}

	public void setA(int[] a) {
		this.a = a;
	}

	public int[] getT() {
		return t;
	}

	public void setT(int[] t) {
		this.t = t;
	}

	public void show() {
		System.out.print("E:"+e);
		System.err.print(" A:"+Arrays.toString(a));try {
			Thread.sleep(1l);
		} catch (InterruptedException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		System.err.print(" T:"+Arrays.toString(t));
		try {
			Thread.sleep(1l);
		} catch (InterruptedException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		System.out.println(" X:"+x);
		
	}

	public int getLength() {
		int length = this.e;
		for (int i = 0; i < a.length; i++) {
			length += a[i];
		}
		length += this.x;
		return length;
	}
	
}

为了保留路径建的对象

package test2019.mon02.动态规划.装配线调度;
/** 
 * Filename:  L.java 
 * Description: 
 * Company:     sendinfo.com.cn Inc.
 * @author: guzhangyan
 * @date: 2019年2月13日 上午9:59:14 
 */
public class L {

	public int l = 0;
	
	public String lName = "";

	public L(int l, String lName) {
		this.l = l;
		this.lName = lName;
	}

	public L() {
	}

	public boolean isNotNull() {
		return this.l!=0;
	}

	public static L newL() {
		return new L();
	}

	@Override
	public String toString() {
		System.out.println("length:"+this.l);
		return lName;
	}

	public static L newL(int l, String lName) {
		return new L(l,lName);
	}
	
	
}

Action

package test2019.mon02.动态规划.装配线调度;
/** 
 * Filename:  DDAction.java 
 * Description: 
 * Company:     sendinfo.com.cn Inc.
 * @author: guzhangyan
 * @date: 2019年2月13日 上午9:32:52 
 */
public class DDAction {

	private static L[][] min_Length = new L[0][0];

	public static void setMinLength(int[][] minLength) {
		min_Length = new L[minLength.length][minLength[0].length];
		for (int i = 0; i < minLength.length; i++) {
			for (int j = 0; j < minLength[i].length; j++) {
				min_Length[i][j] = L.newL();
			}
		}
	}

	/**
	 * @param s1
	 * @param s2
	 * @return
	 * @author: guzhangyan
	 * @version:2019年2月13日 上午11:25:49 
	 * 方法说明 :到达终点最近
	 */
	public static L getMinLength(S s1, S s2) {
		L L1 = getMinLength(s1,s2,0,s1.getA().length-1);
		L L2 = getMinLength(s1,s2,1,s2.getA().length-1);
		int l1 = s1.getA()[s1.getA().length-1]+s1.getX()+L1.l;
		int l2 = s2.getA()[s2.getA().length-1]+s2.getX()+L2.l;
		if(l1>l2) {
			L2.l = l2;
			L2.lName += ",退出走s2:"+l2;
			return L2;
		}else {
			L1.l = l1;
			L1.lName += ",退出走s1:"+l1;
			return L1;
		}
	}

	/**
	 * @param s1
	 * @param s2
	 * @param i
	 * @param j
	 * @return
	 * @author: guzhangyan
	 * @version:2019年2月13日 上午11:26:08 
	 * 方法说明 到达第i轨道第j节点所需最短时间
	 */
	public static L getMinLength(S s1, S s2, int i, int j) {
		if(min_Length[i][j].isNotNull()) {
			return min_Length[i][j];
		}
		if(j==0) {
			if(i==0) {
				min_Length[i][j].l = s1.getE();
				min_Length[i][j].lName = "起点s1:"+s1.getE();
			}else {
				min_Length[i][j].l = s2.getE();
				min_Length[i][j].lName = "起点s2:"+s2.getE();
			}
			return min_Length[i][j];
		}
		L L1 = getMinLength(s1,s2,0,j-1);
		L L2 = getMinLength(s1,s2,1,j-1);
		if(i==0) {
			int l1 = s1.getA()[j-1]+L1.l;
			int l2 = s2.getA()[j-1]+s2.getT()[j-1]+L2.l;
			if(l1>l2) {
				min_Length[i][j] = L.newL(l2,L2.lName+","+j+"走s2:"+l2);
			}else {
				min_Length[i][j] = L.newL(l1,L1.lName+","+j+"走s1:"+l1);
			}
		}else {
			int l1 = s1.getA()[j-1]+s1.getT()[j-1]+L1.l;
			int l2 = s2.getA()[j-1]+L2.l;
			if(l1>l2) {
				min_Length[i][j] = L.newL(l2,L2.lName+","+j+"走s2:"+l2);
			}else {
				min_Length[i][j] = L.newL(l1,L1.lName+","+j+"走s1:"+l1);
			}
		}
		return min_Length[i][j];
	}

}

Test

package test2019.mon02.动态规划.装配线调度;

import java.util.Random;

/**
 * Filename: Test.java Description: Company: sendinfo.com.cn Inc.
 * 
 * @author: guzhangyan
 * @date: 2019年2月13日 上午8:59:10
 */
public class Test {

	public static void main(String[] args) throws InterruptedException {
		Random random = new Random();
		S s1 = new S();
		s1.setE(random.nextInt(100) + 1);
		s1.setX(random.nextInt(100) + 1);
		S s2 = new S();
		s2.setE(random.nextInt(100) + 1);
		s2.setX(random.nextInt(100) + 1);
		int n = 20000;
		int[] a1 = new int[n];
		int[] a2 = new int[n];
		int[] t1 = new int[n - 1];
		int[] t2 = new int[n - 1];
		for (int i = 0; i < n; i++) {
			a1[i] = random.nextInt(100) + 1;
			a2[i] = random.nextInt(100) + 1;
			if (i < t1.length) {
				t1[i] = random.nextInt(100) + 1;
				t2[i] = random.nextInt(100) + 1;
			}
		}
		s1.setA(a1);
		s2.setA(a2);
		s1.setT(t1);
		s2.setT(t2);
		//s1.show();
		Thread.sleep(10l);
		//s2.show();
		Thread.sleep(10l);
		int[][] minLength = new int[2][n];
		DDAction.setMinLength(minLength);
		for (int i = 0; i < minLength[0].length; i++) {
			DDAction.getMinLength(s1,s2,0,i);
			DDAction.getMinLength(s1,s2,1,i);
		}
		DDAction.getMinLength(s1,s2).toString();
		//直走s1
		System.out.println("直走s1:"+s1.getLength());
		//直走s2
		System.out.println("直走s2:"+s2.getLength());
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值