M台机器处理n个任务 java_贪心算法实例(三):多机调度问题

本文介绍了一个使用Java实现的贪心算法来解决M台机器处理n个任务的多机调度问题。当n≤m时,直接分配;当n>m时,按作业时间从大到小排序并分配给空闲机器。代码包含任务节点和机器节点的定义及排序逻辑。
摘要由CSDN通过智能技术生成

n个作业组成的作业集,可由m台相同机器加工处理。要求给出一种作业调度方案,使所给的n个作业在尽可能短的时间内由m台机器加工处理完成。作业不能拆分成更小的子作业;每个作业均可在任何一台机器上加工处理。

这个问题是NP完全问题,还没有有效的解法(求最优解),但是可以用贪心选择策略设计出较好的近似算法(求次优解)。当n<=m时,只要将作业时间区间分配给作业即可;当n>m时,首先将n个作业从大到小排序,然后依此顺序将作业分配给空闲的处理机。也就是说从剩下的作业中,选择需要处理时间最长的,然后依次选择处理时间次长的,直到所有的作业全部处理完毕,或者机器不能再处理其他作业为止。如果我们每次是将需要处理时间最短的作业分配给空闲的机器,那么可能就会出现其它所有作业都处理完了只剩所需时间最长的作业在处理的情况,这样势必效率较低。在下面的代码中没有讨论n和m的大小关系,把这两种情况合二为一了。

具体实现代码如下所示:

/**

*@Title: MultiMachineSchedule.java

*@Package greedyalgorithm

*@Description: TODO

*@author peidong

*@date 2017-5-17 上午9:42:01

*@version V1.0

*/

packagegreedyalgorithm;

importjava.util.ArrayList;

importjava.util.Collections;

importjava.util.LinkedList;

importjava.util.List;

/**

* @ClassName: MultiMachineSchedule

* @Description: 多机调度问题

* @date 2017-5-17 上午9:42:01

*

*/

publicclass MultiMachineSchedule {

/**

*

* @ClassName: TaskNode

* @Description: 任务结点

* @date 2017-5-17 上午9:58:10

*

*/

public static class TaskNode implementsComparable{

int id; //作业标号

int time;  //作业时间

/**

*

*

Title:

*

Description:构造函数

* @param id

* @param time

*/

public TaskNode(int id, int time){

this.id = id;

this.time = time;

}

/*

*

Title:compareTo

*

Description: 按时间长短从大到小排列作业

* @param o

* @return

* @seejava.lang.Comparable#compareTo(java.lang.Object)

*/

public int compareTo(Object o) {

// TODO Auto-generatedmethod stub

int times =((TaskNode)o).time;

if(time > times)

return -1;

if(time == times)

return 0;

return 1;

}

}

/**

*

* @ClassName: MachineNode

* @Description: 机器结点

* @date 2017-5-17 上午10:02:30

*

*/

public static class MachineNodeimplements Comparable{

int id;//机器标号

int avail; //机器空闲时间

/**

*

*

Title:

*

Description:构造函数

* @param id

* @param avail

*/

public MachineNode(int id, intavail){

this.id = id;

this.avail = avail;

}

/*

*

Title:compareTo

*

Description:升序排序,LinkedList的first为最小的

* @param o

* @return

* @seejava.lang.Comparable#compareTo(java.lang.Object)

*/

public int compareTo(Object o) {

// TODO Auto-generatedmethod stub

int xs =((MachineNode)o).avail;

if(avail < xs)

return -1;

if(avail == xs)

return 0;

return 1;

}

}

public static int greedy(int[] a, int m){

int n = a.length – 1; a的下标从1开始,所以n(作业的数目)=a.length-1

int sum = 0;

//如果作业数量小于机器数量

if(n <= m){

for(int i = 0; i < n;i++){

sum+= a[i+1];

System.out.println(“为每个作业分别分配一台机器”);

return sum;

}

}

List d = newArrayList();  //保存所有的作业

for(int i = 0; i < n; i++){//将所有的作业存入List中,保存id和时间

TaskNode tn = newTaskNode(i+1,  a[i+1]);

d.add(tn); //入队

}

Collections.sort(d); //对作业进行排序

LinkedList h =new LinkedList(); //h保存所有的机器

for(int i = 1; i < m; i++){ //将所有的机器存入链表中

MachineNode mn = newMachineNode(i,0); //初始化时,每台机器的空闲时间为0

h.add(mn); //入队

}

int len = h.size();

for(int i = 0; i < n; i++){

Collections.sort(h);  //对机器进行排序

MachineNode temp =h.peek();

System.out.println(“将机器”+temp.id+”从”+temp.avail+”到”+(temp.avail+d.get(i).time)+”的时间段分配给作业”+d.get(i).id);

temp.avail+=d.get(i).time;

sum = temp.avail;

}

return sum;

}

/**

*@Title: main

*@Description: TODO

*@param args

*@return void

*@throws

*/

public static void main(String[] args) {

// TODO Auto-generated method stub

int[] a={0,2,14,4,16,6,5,3};

int m=5;

int sum=greedy(a,m);

System.out.println(“总时间为:”+sum);

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值