回溯法解决批处理作业调度问题

唉,这是作为一个失败的开端。但是,我不害怕失败的!今天稍微晚点睡觉,因为中午多睡啦~最近被王晓东老师的《计算机算法设计与分析》(第4版)折磨得够呛。不会说些文雅的话,这的确是事实。基础差,不仅仅将学会的东西忘记了,而且还以为自己曾经不会的东西,现在稍微看看就能懂。人是有多么自大啊!废话不多说。先放上原问题。

一、问题

给定n个作业的集合J={J1,J2,...,Jn}。每一个作业Ji都有两项任务分别在2台机器上完成。每个作业必须先由机器1处理,然后再由机器2处理。作业Ji需要机器j的 处理时间为tji,i=1,2,...,n;j=1,2。对于一个确定的作业调度,设Fji是作业i在机器j上完成处理的时间。则所有作业在机器2上完成处理的时间和f=F2i的加和为该作业调度的完成和。

批处理作业调度问题要求对于给定的n个作业,制定最佳作业调度方案,使其完成时间和达到最短。

不行,我整不了这表格。先不弄了。我先把代码放上。

二、代码

</pre><pre name="code" class="html">批处理作业调度类FlowShop<pre name="code" class="java">
/** * 问题描述: * 给定n个作业的集合J={J1,J2,...,Jn}。每一个作业Ji都有两项任务分别在2台机器上完成。每个作业必须先由机器1处理,然后再由机器2处理。作业Ji需要机器j的 * 处理时间为tji,i=1,2,...,n;j=1,2。对于一个确定的作业调度,设Fji是作业i在机器j上完成处理的时间。则所有作业在机器2上完成处理的时间和f=F2i的加和成 * 为该作业调度的完成和。 * 批处理作业调度问题要求对于给定的n个作业,制定最佳作业调度方案,使其完成时间和达到最短。 * @author noonTree * */public class FlowShop {static int Max = 200;static int M[][];//各作业所需的处理时间static int[] x;//当前作业调度static int[] bestx;//当前最优作业调度static int[] f2;//机器2完成的处理时间static int f1;//机器1完成处理的时间static int f;//完成时间和static int bestf;//当前最优值static int n;//作业数void BackTrack(int i){if(i > n){//n次循环,让当前最优调度为bestx[]为当前最优调度x[]for(int j = 1;j <= n;j++)bestx[j] = x[j];//当前最优值为完成时间和bestf = f;}else{/*i到n次的循环 *j用来指示选择了哪个任务(也就是执行顺序) tb(0)进来了,不管怎么递归,就有j=1,2,3这三个过程,因此肯定能遍历完全(这句话是我抄的别人的) */for(int j = i;j <= n;j++){//f1等于第i次作业在第一个机器上的时间加和f1 += M[x[j]][1];/*f2分两种情况: * (1)如果上一个作业在第二个机器上所用时间大于下一个作业在机器一上的作业时间,那么当前作业时间等于上一个作业在机器2所用时间加上当前作业 * 在机器2所用时间; * (2)如果是小于,那么当前作业等于机器1的完成处理时间加上当前作业在机器2所用时间。 */f2[i] = ((f2[i - 1] > f1)? f2[i - 1]:f1) + M[x[j]][2];//总时间等于作业在机器2上的作用时间f += f2[i];//如果总时间小于最优值则有:if(f < bestf){//交换此时的作业调度Swap(x,i,j);//回溯到i+1BackTrack(i + 1);//回溯不懂啊!!!//交换此时的作业调度Swap(x,i,j);}//回溯完成后,当前机器1完成处理时间等于上一次的机器1完成处理时间减去当前的xf1 -= M[x[j]][1];f -= f2[i];}}}void Swap(int[] x, int i, int j) {int temp = x[j];x[j] = x[i];x[i] = temp;}int Flow(int[][] MM,int nn,int bbestx[]){int ub = Max;//这是什么?确定一个最大值n = nn;M = MM;x = new int[n + 1];f2 = new int[n + 1];bestx = bbestx;bestf = ub;f1 = 0;f = 0;for(int i = 0;i <= n;i++){f2[i] = 0;x[i] = i;}BackTrack(1);return bestf;}}
 
  
测试类TestFlowShop
import java.util.Scanner;

public class TestFlowShop {

	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		System.out.printf("\t批处理作业调度\n");
		System.out.print("输入作业数目:");
		int n = input.nextInt();
		System.out.println("输入各作业所需的处理时间:");
		//让数组下标从1开始输入数据,第零行不用
		int M[][] = new int[n + 1][3];
		for(int i = 1;i <= n;i++){
			for(int j = 1;j < 3;j++){
				M[i][j] = input.nextInt();
			}
		}
		//当前的最优调度
		int bestx[] = new int[n + 1];
		FlowShop Fls = new FlowShop();
		//当前最优值
		int bestf = Fls.Flow(M,n,bestx);
		System.out.print("输出当前最优调度:");
		for(int i = 1;i <= n;i++){
			if(i != n){
				System.out.print(bestx[i] + " ");
			}else{
				System.out.print(bestx[i]);
			}
		}
		System.out.println();
		System.out.print("输出当前最优值:" + bestf);
		
		
	}

}
/*出现的问题:
 * (1)在未初始化变量的时候就使用
 * (2)坑死人了,下标的位置,烦死我了。我就是看不出来。觉得就是那样。说出来会被嘲笑心里不舒服,大概这就是我不懂得变通的地方。但是,我不会认输的。在自制力上,
 * 我 有优势。
 * (3)我还发现了一个问题,为什么会出现(1)情况呢?是因为在C++的方法中,在类外的方法里用类的方法要声明这个类,然后默认的两个名字相同的变量,当然默认调用的
 * 是当前这个方法的变量而不是类中的变量,要调用类的变量则是“类名.方法”。我没有理解这个,所以走了弯路。罢了罢了,这也是一大教训!!
 * */



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值