我是靠谱客的博主 坚定高跟鞋,最近开发中收集的这篇文章主要介绍【算法】算法-独立任务最优调度问题(双机调度问题)1,问题2,分析3,复杂度4,代码,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

1,问题

(问题来自:《计算机算法设计与分析(第4版)》王晓东 编著)
用2台处理机A和B处理n个作业。设第i个作业交给机器A处理时所需要的时间是a[i],若由机器B来处理,则所需要的时间是b[i]。现在要求每个作业只能由一台机器处理,每台机器都不能同时处理两个作业。设计一个动态规划算法,使得这两台机器处理完这n个作业的时间最短(从任何一台机器开工到最后一台机器停工的总的时间)。研究一个实例:n=6, a = {2, 5, 7, 10, 5, 2}, b = {3, 8, 4, 11, 3, 4}.
要求:用文件input.txt输入数据,文件output.txt输出数据。
输入文件示例:input.txt

6
2 5 7 10 5 2
3 8 4 11 3 4

输出文件示例:output.txt

15

2,分析

1)函数

当完成k个作业,设:
机器A花费了x时间
机器B所花费时间的最小值肯定是x的一个函数,设:
F[k][x]表示机器B所花费时间的最小值
则:
F[k][x]=Min{ F[k-1][x]+b[k], F[k-1][x-a[k]] }
其中F[k-1][x]+b[k]表示第k个作业由机器B来处理(完成k-1个作业时机器A花费的时间仍是x),F[k-1][x-a[k]]表示第k个作业由机器A处理(完成k-1个作业时机器A花费的时间是x-a[k])。

那么单个点对较大值即:
Max(x, F[k][x]),表示此时(即机器A花费x时间的情况下)所需要的总时间
而机器A花费的时间x是变化的,即x=0,1,2……x(max),(理论上x的取值是离散的,但为编程方便,设为整数连续的)由此构成了点对较大值序列。要求整体时间最短,取这些点对较大值序列中最小的即是。

2)举例:

对于a = {2, 5, 7, 10, 5, 2}, b = {3, 8, 4, 11, 3, 4}。
完成一个作业,求完成时两台机器花费的最少时间 :
则0<=x<=a[0]
x=0时,F[0][0]=3,则Max(0,3)=3,机器A花费0时间,机器B花费3时间,而此时两个机器所需时间为3;
x=1时,F[0][1]=3,Max(1,3)=3;
x=2时,F[0][2]=0,则Max(2,0)=2;
当x=2时,完成第一个作业两台机器花费最少的时间为2,此时机器A花费2时间,机器B花费0时间。

完成2个作业,0<=x<=(a[0]+a[1])
令x<0时,F[1][x] = ∞(数组下标不能小于0)
x=0,则F[1][0]= Min{ F[0][0]+b[2], F[0][0-a[1]] }= Min{3+8,∞}=11,进而Max(0,11)=11;
x=1,则F[1][1]= Min{ F[0][1]+b[2], F[0][1-a[1]] }= Min{3+8,∞}=11,进而Max(11)=11;
x=2,则F[1][2]= Min{ F[0][2]+b[2], F[0][2-a[1]] }= Min{0+8,∞}=8,进而Max(2,8)=8;
x=3,则F[1][3]= Min{ F[0][3]+b[2], F[0][3-a[1]] }= Min{0+8,∞}=8,进而Max(3,8)=8;
x=4,则F[1][4]= Min{ F[0][4]+b[2], F[0][4-a[1]] }= Min{0+8,∞}=8,进而Max(4,8)=8;
x=5,则F[1][5]= Min{ F[0][5]+b[2], F[0][5-a[1]] }= Min{0+8,3}=3,进而Max(5,3)=5;
x=6,则F[1][6]= Min{ F[0][6]+b[2], F[0][6-a[1]] }= Min{0+8,3}=3,进而Max(6,3)=6;
x=7,则F[1][7]= Min{ F[0][7]+b[2], F[0][7-a[1]] }= Min{0+8,0}=0,进而Max(7,0)=7;

3,复杂度

O(n*Sum) 其中Sum为a中所有元素之和与b中所有元素之和的最小值。

4,代码

动态规划,java语言。
输入:input.txt

6,
2,5,7,10,5,2,
3,8,4,11,3,4,
package task_scheduling;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class Main {

	private final static int SIZE = 50;
	private final static int MAXINT = 999;

	/** 任务 */
	private static TaskBean taskA;
	private static TaskBean taskB;

	public static void main(String[] args) throws IOException {

		int data;

		ReadFile();

		int temp = TaskScheduling.TaskScheduling(taskA, taskB);

		if (0 == temp) {
			System.out.println("计算出错");
		} else {

			// out.txt
			FileUtil.writeFile("output.txt", temp + "");
		}
	}

	/**
	 * Read input.txt
	 * 
	 * @throws IOException
	 */
	private static void ReadFile() throws IOException {

		int[] Data = new int[SIZE];// 文件读取到的数据转换为int存储
		String[] Data_str = new String[SIZE];// 文件读取到的数据

		Data_str = FileUtil.readFile("input.txt").split("\,");

		int index = 0;
		for (String item : Data_str) {

			Data[index++] = Integer.parseInt(item);
		}

		int N = (int) Data[0];
		int[] a = new int[SIZE], b = new int[SIZE];
		for (int i = 1; i <= N; i++) {
			a[i] = Data[i];
		}
		for (int i = 1, j = N + 1; j <= 2 * N; j++, i++) {
			b[i] = Data[j];
		}

		taskA = new TaskBean(N, a);
		taskB = new TaskBean(N, b);
	}
}
package task_scheduling;

public class TaskBean {

	private final int SIZE = 50;// 数组大小
	private final int MAXINT = 999;

	private int N;// 任务数量
	private int[] task = new int[SIZE];// 处理机处理任务的时间

	// 存储的计算后的数据
	private int[] Sum = new int[SIZE];// 处理到第i个作业累加的时间和
	private int tempSum = 0;// 和

	public TaskBean(int N, int[] task) {
		this.setN(N);
		this.setTask(task);

		for (int i = 1; i <= N; i++) {
			tempSum += task[i];
			Sum[i] = tempSum;
		}
	}

	public int getN() {
		return N;
	}

	public void setN(int n) {
		N = n;
	}

	public int[] getTask() {
		return task;
	}

	public void setTask(int[] task) {
		this.task = task;
	}

	public int[] getSum() {
		return Sum;
	}

	public void setSum(int[] sum) {
		Sum = sum;
	}

	public int getTempSum() {
		return tempSum;
	}

	public void setTempSum(int tempSum) {
		this.tempSum = tempSum;
	}
}

核心算法:

package task_scheduling;

/**
 * 独立任务最优调度问题
 * 
 * @author luo
 *
 */
public class TaskScheduling {

	private final static int SIZE = 50;
	private final static int MAXINT = 999;// 无穷大

	public static int TaskScheduling(TaskBean taskA, TaskBean taskB) {
		int temp = 0;// 返回的数
		int N = taskA.getN();// 任务数
		int[] SumA = taskA.getSum();
		int[] SumB = taskB.getSum();
		int[] a = taskA.getTask();
		int[] b = taskB.getTask();
		// a的和、b的和min
		int MinSum = (taskB.getTempSum() > taskA.getTempSum()) ? taskA.getTempSum() : taskB.getTempSum();


		/// 动态二维数组
		int[] MaxTime = new int[MinSum + 1];
		int[][] F = new int[SIZE][N + 1];
		// 初始化
		SumB[0] = 0;
		for (int i = 0; i < N + 1; i++) {
			F[i] = new int[MinSum + 1];
			F[i][0] = SumB[i];// SumB[0]没赋值,调试时会输出地址
			for (int j = 1; j <= MinSum; j++) {
				F[i][j] = 0;
			}
		}
		// 计算F矩阵
		for (int k = 1; k <= N; k++) {
			temp = (SumA[k] > SumB[k]) ? SumB[k] : SumA[k];
			for (int x = 1; x <= temp; x++) { // A最多用AB前k任务的最小值,如果B最少就全用B做。
				if (x >= a[k])// 等于号不能少
					F[k][x] = (F[k - 1][x] + b[k] < F[k - 1][x - a[k]]) ? F[k - 1][x] + b[k] : F[k - 1][x - a[k]];
				else
					F[k][x] = F[k - 1][x] + b[k];
			}
		}

		temp = MAXINT;
		//得出最优调度
		for (int i = 0; i <= MinSum; i++) {
			MaxTime[i] = (i > F[N][i]) ? i : F[N][i];
			if (temp > MaxTime[i])
				temp = MaxTime[i];
		}

		return temp;
	}
}

package task_scheduling;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;

public class FileUtil {

	/**
	 * 读文件 返回字符串
	 * @param url
	 *            文件地址,如:"/sdcard/test.txt"
	 * @return
	 * @throws IOException 
	 */
	public static String readFile(String url) throws IOException {
		// 读取
		String str = ""; // 读取到的内容
		File urlFile = new File(url);
		InputStreamReader isr = new InputStreamReader(new FileInputStream(urlFile), "UTF-8");
		BufferedReader br = new BufferedReader(isr);

		String mimeTypeLine = null;
		while ((mimeTypeLine = br.readLine()) != null) {
			str = str + mimeTypeLine;
		}
		System.out.println("FileUtil读取内容:" + str);
		return str;
	}
	/**
	 * 写文件,成功返回true
	 * @param filePath 文件地址
	 * @param sourceString 待写入字符串
	 * @return
	 */
	public static boolean writeFile(String filePath, String sourceString){
		//写入
		try{
			System.out.println("写入文件信息:" + sourceString);
			byte[] sourceByte = sourceString.getBytes();  
			if(null != sourceByte){  
			        File file = new File(filePath);     //文件路径(路径+文件名)  
			        if (!file.exists()) {   //文件不存在则创建文件,先创建目录  
			         
			            file.createNewFile();  
			        }  
			        FileOutputStream outStream = new FileOutputStream(file);    //文件输出流用于将数据写入文件  
			        outStream.write(sourceByte);  
			        outStream.close();  //关闭文件输出流  
			}  
		}catch(Exception e){
			System.out.println("写入失败");
			return false;
		}
		System.out.println("写入成功");
		return true;
	}
}

最后

以上就是坚定高跟鞋为你收集整理的【算法】算法-独立任务最优调度问题(双机调度问题)1,问题2,分析3,复杂度4,代码的全部内容,希望文章能够帮你解决【算法】算法-独立任务最优调度问题(双机调度问题)1,问题2,分析3,复杂度4,代码所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(64)

评论列表共有 0 条评论

立即
投稿
返回
顶部