標籤:
裝配線問題: 韓雞雞一直強調的裝配線問題其實很簡單,也算是動態規劃裡面比較簡單的問題了。
在上面的圖中,我們可以看到也就是一個車間有兩條裝配線,每一個相對位置的功能是相同的。。中a11和a21,它們的功能是相同的,都是裝配一個零件,但是它們所需的時間卻不相同。而且不同裝配線間的移動是要花時間的。但是在同一條裝配線上移動是不需要花時間的,當然了,我們只能從左往右依次裝配零件。那麼問題來了,怎麼樣選擇裝配路線使得時間最少?當然每件裝配線都有它的進入時間和移出時間,這個就不多說了。那麼對於這個問題的解,我們還是可以採用典型的動態規劃的問題解法,裝原問題劃分為子問題,找到原問題與子問題的關係,然後子問題再劃分為子問題了。那麼對於這個問題,原問題是我們在離開裝配線1和2時,所花時間最少。當然我們可以有多種離開的方法,從裝配線1離開或者2離開,我們暫且不考慮離開的時間x1和x2.假設是從裝配線1離開,離開最後的點a1n ?所花的時間為Sn,?它花的時間假設是最少的,於是那麼這個問題的子問題是會麼呢?那麼Sn和Sn-1?有何聯絡呢,對於Sn的到達,其實有兩條中徑可以選第一條呢,就是通過a?1n-1,?第二條呢,就是通過從裝配線2過來嘛,也就是?a?2n-1?於是問題來了,S?n?和它們有什麼關係呢,其實關係是有的。也就是我們的Sn肯定那兩條選擇的路徑中所花時間最少的那條了,也就是
就是演算法導論(第二版)中間的原話了。我們可以看到其中還有一個f2,以及一個f1,那麼,它們有什麼關係呢?其實f1和f2的引入是為了假設我們不知道最後是從第一條裝配線出來還是從第二條裝配線出來,那麼我們就可以假設了,兩者都要假設,然後求兩者的最小值,就可以了,而且求這兩條裝配線並不是獨立的,而是它們間相互有關係。你們看,我們的f1[j]是括弧裡面兩者的較小值,也就是兩條路徑中選擇時間最少的。這當然是肯定的。那麼其中涉及到的f1[j-1]和f2[j-1]呢,那麼它們肯定也是在它們的情況選擇兩條可以到達它們路徑中的較小值啊。。有點像“貪心演算法”的問題,也就是每次總是選擇是好的那種情況了。剛剛我們是反著來,那麼正著來呢,也就是從左邊開始,往右邊走,還是由
同理:
我們總是選擇最好的那條路線。
#ifndef ASSEMBLE_LINE_H#define ASSEMBLE_LINE_H#include<iostream>#include<string>class AssembleLine{private:int AssOneIn; //第一條裝配線輸入的代價int AssTwoIn; //第二條裝配線輸入的代價int AssOneOut; //第一條裝配線輸出的代價int AssTwoOut; //第二條裝配線輸出的代價int *Ass_one; //第一條裝配線零件裝配代價int Len_one; //第一條裝配線的長度int *Ass_two; //第二條裝配線零件的裝配代價int Len_two; //第二條裝配線的長度int *AssOneToTwo; //第一條裝配線轉入第二條的代價int *AssTwoToOne; //第二條裝配線轉入第一條的代價int *f1; //記錄第一條裝配線int *f2; //記錄第二條裝配線public:AssembleLine(int *&ass1,int len1,int *&ass2,int len2):Ass_one(ass1),Ass_two(ass2),Len_one(len1),Len_two(len2){}int assembleMin(); };
#include"AssembleLine.h"#define Min(a,b) a<b? a:bint AssembleLine::assembleMin(){f1[0]=this->AssOneIn+this->Ass_one[0]; f2[0]=this->AssTwoIn+this->Ass_two[0]; for(int i=1;i<this->Len_one; i++){f1[i]=Min((f1[i-1]+this->Ass_one[i]),(f2[i-1]+this->Ass_one[i]+this->AssTwoToOne[i-1])); f2[i]=Min((f2[i-1]+this->Ass_two[i]),(f2[i-1]+this->Ass_two[i]+this->AssOneToTwo[i-1])); }return Min((f1[this->Len_one-1]+this->AssOneOut),(f2[this->Len_two-1]+this->AssTwoOut)); }
來自為知筆記(Wiz)
裝配線問題