【备注】:借鉴《Introduction of Algorithm》seconde edition第十五章的内容,可以在书上找到原实例。
1、概念和意义:
分治算法是指将问题划分为一些独立的子问题,递归地求解各子问题,然后合并子问题的解而得到原问题的解。动态规划适用于子问题不是独立的情况,也就是各子问题包括公共的子子问题。在这种情况下,若用分治法则会做许多不必要的工作,即重复地求解公共的子子问题。动态规划算法对每个子子问题只求解一次,将其结果保存在一张表中,从而避免每次遇到各个子问题重新计算答案。
动态规划算法的设计可以分为如下4个步骤:
(a)描述最优解的结构。
(b)递归定义最优解的值。
(c)按自底向上的方式计算最优解的值。
(d)由计算出的结果构造一个最优解。
2、一个简单例子,装配线调度,只有两条可选路径。
(1)问题描述:
汽车公司又两条装配线:assembly line1,assembly line2.
一条装配线有六个装配站,station1,...,station6
进入(chassis enter)和离开(complete exit) assembly line 的时间不一致.
产品必须依次经过装配站,同一条assembly line1上station转换不计时间,但是不同的assemblyline转换是要消耗时间。
具体标记如下:
一个简单实例:
伪代码:
perl代码简单执行,仅仅是简单执行,不具有一般性。
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
my @stations = ([2,7,9,3,4,8,3],[4,5,6,2] ); # 0,1,2,7
my @transfer = ([2,4],[2,1] ); # 0,5
my (@fastway,@line);
($fastway[0][0],$fastway[0][1]) = ($stations[0][0],$stations[0][0]+$stations[0][1] );
($fastway[1][0],$fastway[1][1]) = ($stations[1][0],$stations[1][0]+$stations[1][1] );
($line[0][0],$line[0][1]) = (0,0);
($line[1][0],$line[1][1]) = (1,1);
for( my $i=2; $i<=6; $i++ ){
# for line one
if( $fastway[0][$i-1] <= $fastway[1][$i-1] + $transfer[1][$i-2] ){
$fastway[0][$i] = $fastway[0][$i-1] + $stations[0][$i];
$line[0][$i] = 0;
}else{
$fastway[0][$i] = $fastway[1][$i-1] + $transfer[1][$i-2] + $stations[0][$i];
$line[0][$i] = 1;
}
# for line two
if( $fastway[1][$i-1] <= $fastway[0][$i-1] + $transfer[0][$i-2] ){
$fastway[1][$i] = $fastway[1][$i-1] + $stations[1][$i];
$line[1][$i] = 1;
}else{
$fastway[1][$i] = $fastway[0][$i-1] + $transfer[0][$i-2] + $stations[1][$i];
$line[1][$i] = 0;
}
}
$fastway[0][7] = $fastway[0][6] + $stations[0][7];
$fastway[1][7] = $fastway[1][6] + $stations[1][7];
my $line = 0;
$line[$line][7] = $line;
$line[$line][7] = $line = 1 if( $fastway[0][7] >= $fastway[1][7] );
print "StepMarker\tStations\tTimeCost\n";
for( my $i=0; $i<8; $i++ ){
my $index;
if( $i==0 ) {
$index = "EnterTimeCost";
}elsif( $i==7 ) {
$index = "TotalTimecost";
}else{
$index = "FinishStation";
}
print join("\t","$index$i",$line[$line][$i]+1,$fastway[$line][$i],"\n" );
}
python代码:
stations = [[2,2]] transfer = [[2,1]] fastway = [ [stations[0][0],stations[0][0]+stations[0][1]],[stations[1][0],stations[1][0]+stations[1][1]] ] line = [ [0,0],[1,1] ] for i in range(2,7): # for line one if fastway[0][i-1] <= (fastway[1][i-1] + transfer[1][i-2]): fastway[0].append( fastway[0][i-1] + stations[0][i] ) line[0].append( 0 ) else: fastway[0].append( fastway[1][i-1] + transfer[1][i-2] + stations[0][i] ) line[0].append( 1 ) #for line two if fastway[1][i-1] <= (fastway[0][i-1] + transfer[0][i-2]): fastway[1].append( fastway[1][i-1] + stations[1][i] ) line[1].append( 1 ) else: fastway[1].append( fastway[0][i-1] + transfer[0][i-2] + stations[1][i] ) line[1].append( 0 ) fastway[0].append( fastway[0][6] + stations[0][7] ) fastway[1].append( fastway[1][6] + stations[1][7] ) li = 0 line[li].append( 0 ) if fastway[0][7] >= fastway[1][7]: li = 1 line[li].append( 1 ) print "StepMarker\tStations\tTimeCost" for i in range(8): if i==0: index = "EnterTimeCost" elif i==7: index = "TotalTimecost" else: index = "FinishStation" print '%s%d\t%d\t%d' % (index,i,line[li][i]+1,fastway[li][i])
难点有两个:一个是递推公式的归纳,二是进程的表示,比如line数组。
祝馒头天天开心!!