A Simple Example of Dynamic Programming using perl scripts

来源:互联网 发布:本科大数据毕业设计 编辑:程序博客网 时间:2024/06/06 03:28
【备注】:借鉴《Introduction of Algorithm》seconde edition第十五章的内容,可以在书上找到原实例。

1、概念和意义:
动态规划(dynamic programming)是通过组合子问题的解而解决整个问题的。programming是指一种规划,而不是指写计算机代码。
分治算法是指将问题划分为一些独立的子问题,递归地求解各子问题,然后合并子问题的解而得到原问题的解。动态规划适用于子问题不是独立的情况,也就是各子问题包括公共的子子问题。在这种情况下,若用分治法则会做许多不必要的工作,即重复地求解公共的子子问题。动态规划算法对每个子子问题只求解一次,将其结果保存在一张表中,从而避免每次遇到各个子问题重新计算答案。
动态规划通常应用于最优化问题。此类问题可能有很多种可行解。每个解有一个值,而我们希望找出一个具有最优(最大或最小)值的解。称这样的解为该问题的一个最优解(而不是确定的最优解)。
动态规划算法的设计可以分为如下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/perluse strict;use warnings;use Data::Dumper;my @stations = ([2,7,9,3,4,8,4,3], [4,8,5,6,4,5,7,2] ); # 0,1,2,3,4,5,6,7my @transfer = ([2,3,1,3,4], [2,1,2,2,1] ); # 0,1,2,3,4,5my (@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,7,9,3,4,8,4,3], [4,8,5,6,4,5,7,2]]transfer = [[2,3,1,3,4], [2,1,2,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 = 0line[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数组。

祝馒头天天开心!!

0 0
原创粉丝点击