- 動態規劃
- 有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();
}
}