深入理解動態(tài)規(guī)劃的一系列問題(7)
本周更新的動態(tài)規(guī)劃問題是裝配線問題(Assembly Line Balancing (ASMBAL))。裝配線問題沒記錯的話應該是算導中的動態(tài)規(guī)劃的第一題,具體描述大概是:一件產(chǎn)品從生產(chǎn)到出品要經(jīng)歷一系列過程,其中每個步驟都會有成本開銷,而這些過程在流轉(也就是說步驟轉換)過程也有成本損失,如何平衡選擇,可以最小化產(chǎn)品的出品成本。
算導的原題:
某汽車工廠有2個裝配線,每個裝配線有n 個裝配站(按順序編號1~n )標記為Si,j,表示第i個裝配線的第j個裝配站,兩個裝配線的對應的裝配站執(zhí)行相同的功能,但所用的時間可能不同。經(jīng)過第i條流水線(i=1,2)的第j 個裝配站所花的時間為a[i][j]。從第i條流水線的第j 個裝配站移到第j+1個裝配站的時間可以忽略,而移到另外一個流水線的下一個裝配站則需要一定的時間t[i][j]。汽車進入流水線需要花時間,進入裝配線1需要時間e[1],進入裝配線2需要時間e[2]; 汽車出流水線時需要花時間,出裝配線1需要時間x[1],出裝配線2需要時間x[2] 。汽車的裝配需要按順序經(jīng)過所有裝配站。
現(xiàn)在已知裝配時間a[i][j] 、轉移時間t[i][j]、進入裝配線的時間e[i]、出裝配線的時間x[i],要求輸出裝配一輛汽車所需要的最短時間,以及經(jīng)過的裝配站。
對于這個問題,可以將其與之前所解的有向無環(huán)圖對比,非常類似,不同的是這個在計算轉移成本的時候,不僅需要算路徑(也就是轉移的成本),還要疊加節(jié)點本身的生產(chǎn)成本。以具體為例,裝配線有14個裝配站,其中0號和13號分別是起點和終點,而剩余12個站平均分配在兩條流水線上,具體各計算成本如下圖:
其中節(jié)點權重為v=[0,7,8,9,5,3,6,4,4,8,5,4,7,0],即代表裝配時間,而轉移時間表示為矩陣形式:
因為已經(jīng)將過程打上了stage的標簽,我們定義一個狀態(tài)為(k,i),表示在第k個階段的第i條裝配線上,那么轉移時間就表示為(k,i)->(k+1,j)的一個成本c(k,i,j)。當然由題圖可見在同線轉移時是沒有成本的即c(i,k,k)=0。具體的,定義總成本R(k,i,j)=v(k,i)+c(k,i,j),其中v(k,i)即i裝配線的編號為k的節(jié)點權重。定義f(k,i)為狀態(tài)值,即在k階段時的i裝配線到出產(chǎn)時的總成本,那么DPFE為:f(k,i)=min j{R(k,i,j)+f(k+1,j)}。f(N+1,0)=0是初始條件,表示在最后一個節(jié)點時的成本,那么往前遞推,f(0,0)作為在起點處的成本就是目標函數(shù),于是f(0,0)=(0+2)+(7+2)+(5+1)+(3+1)+(4+0)+(5+1)+(4+3)=38.
解題程序:
1: /*
2: * Copyright (C) 2013 changedi
3: *
4: * Licensed under the Apache License, Version 2.0 (the "License");
5: * you may not use this file except in compliance with the License.
6: * You may obtain a copy of the License at
7: *
8: * http://www.apache.org/licenses/LICENSE-2.0
9: *
10: * Unless required by applicable law or agreed to in writing, software
11: * distributed under the License is distributed on an "AS IS" BASIS,
12: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13: * See the License for the specific language governing permissions and
14: * limitations under the License.
15: */
16: package com.jybat.dp;
17:
18: public class ASMBAL {
19:
20: private static int[][] cost = // (stage,line)
21: {
22: { 2, 4 }, // to next line
23: { 2, 2 }, { 1, 3 }, { 2, 1 }, { 2, 3 }, { 1, 4 }, // to next line
24: { 3, 2 } // from line
25: };
26: private static int[][] vertexcost = // (stage,line)
27: {
28: { 0, 0 }, { 7, 8 }, { 9, 5 }, { 3, 6 }, { 4, 4 }, { 8, 5 }, { 4, 7 }
29: };
30: private static int N = vertexcost.length - 1;
31:
32: private static int arccost(int g, int x, int d) {
33: if (g == 0)
34: return cost[g][d]; // to next line d
35: else if (g == N)
36: return cost[g][x]; // from line x
37: else if (x == d)
38: return 0; // stay same line
39: else
40: return cost[g][d]; // to next line d
41: }
42:
43: public static double f(int g, int x) {
44: if (g > N)
45: return 0.0;
46: double min = Double.MAX_VALUE;
47: for (int d = 0; d <= 1; d++) {
48: double c = vertexcost[g][x] + arccost(g, x, d) + f(g + 1, d);
49: if (c < min)
50: min = c;
51: }
52: return min;
53: }
54: /**
55: * @param args
56: */
57: public static void main(String[] args) {
58: System.out.println(f(0,0));
59: }
60:
61: }
posted on 2014-04-21 13:25 changedi 閱讀(1239) 評論(1) 編輯 收藏 所屬分類: 算法