微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

A Simple Example of Dynamic Programming using perl scripts

【备注】:借鉴《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/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数组。

祝馒头天天开心!!

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐