- 动态规划
- 有n个工件,j1, j2, …, jn, 每个工件有一个给定的最小加工时间pj , 以及一个权重wj
1 j n。有一个用来加工这些工件的机器。假设这个机器一次可以加工任意多的工件, 同时加工的工件组成一个批B。
在同一批B里加工的工件必须同时开始,同时结束,即它们有同样的开始时间sj, 同样的结束时间Cj = sj + p(B)jB,
这里 。 从一批工件开始加工到结束中间不允许中断。
请问:如何给这些工件分批,以及如何对这些批进行排序使得所有工件的加权完成时间之和最小。
这是代码:
用三个一维数组来记录,分别为 前i个点的完成时间:finish[i],前i个点的总权重result[i], 第i个点的前一批的最后一个,用于分批
ps:代码和注释感觉挺清楚了,如果还有疑问,请在底下留言
public class Fifth {
//time;
int a[]={1,5,2,4,5,9,5,10,5,6,6,7,8,7,11,6,6,7,11,10,7,12,8,8,8,6,5,13,14,9,8,
9,3,3,11,2,9,13,4,6,4,4,8,9,6,15,5,7,9,3};
//value
int b[]={2,3,2,5,4,4,6,8,5,7,7,4,6,9,12,4,
4,3,5,5,3,6,9,5,9,12,3,7,12,11,11,3,4,5,3,12,
2,6,6,4,9,15,12,4,8,31,1,12,3,4};
static int [][] res;
static int [][] fin;
static int [][] pre;
Workpiece all[];
void Create() {
all=new Workpiece[50];
res =new int[all.length][all.length]; //记录权重结果
fin = new int[all.length][all.length];//每个工件的完成时间
pre=new int [all.length][all.length];//每个工件前一个的时间
for (int i = 0; i < a.length; i++) {
all[i]=new Workpiece();
all[i].setTime(a[i]);
all[i].setWeight(b[i]);
all[i].setFinish(0);
}
for (int i = 0; i < all.length; i++) {
int sum=0;
Workpiece temp=new Workpiece();
temp.setTime(100);
for (int j = i; j < all.length; j++) {
if (all[j].getTime()<temp.getTime()) {
temp=all[j];
sum=j;
}
}
Workpiece temps=new Workpiece();
temps=all[i];
all[i]=all[sum];
all[sum]=temps;
}
}
void cal() {
//前一个的标号
int index[]=new int [50];
//all数组有每个工件的时间.finsh为每个工件的完成时间
int finish[]=new int [50];
int result[]=new int [50];//每一步的最优结果
for (int i = 0; i < finish.length; i++) {
index[i]=0;
finish[i]=0;
result[i]=0;
}
finish[0]=all[0].getTime();
index[0]=0;
result[0]=all[0].getTime()*all[0].getWeight();
//从一开始更新并记录
for (int i = 1; i < result.length; i++) {
//最后一个和之前的分开的时间
result[i]=(finish[i-1]+all[i].getTime())*(all[i].getWeight())+result[i-1];
finish[i]=finish[i-1]+all[i].getTime();
index[i]=i-1;
//逐渐合并更新
int all_weight=all[i].getWeight();
for (int j = i-1; j>0; j--) {
all_weight+=all[j].getWeight();
int results=(finish[j-1]+all[i].getTime())*(all_weight)+result[j-1];
//成功和j合并
if (results<result[i]) {
result[i]=results;
index[i]=j-1;
//index[j]=j-1;
//更新合并后的合并点的finish时间
for (int k = j; k <=i; k++) {
finish[k]=finish[j-1]+all[i].getTime();
}
}
}
// 和0合并
int result_0=(all_weight+all[0].getWeight())*all[i].getTime();
if (result_0<result[i]) {
index[i]=0;
result[i]=result_0;
finish[i]=all[i].getTime();
for (int j_2 = 0; j_2 <i; j_2++) {
finish[j_2]=all[i].getTime();
}
}
}
for (int k = 0; k < result.length; k++) {
System.out.print(finish[k]+" ");
}
System.out.println();
for (int i = 0; i < result.length; i++) {
//System.out.print(index[i]+" ");
System.out.print(result[i]+" ");
}
}
class Workpiece{
public int getFinish() {
return finish;
}
public void setFinish(int finish) {
this.finish = finish;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
public int getTime() {
return time;
}
public void setTime(int time) {
this.time = time;
}
int weight;
int time;
int finish;//完成时间
}
public static void main(String[] args) {
Fifth aFifth=new Fifth();
aFifth.Create();
aFifth.cal();
}
}