算法2 : 动态规划

动态规划最优化原理中的一种重要的方法。

动态规划在查找有很多重叠子问题的情况的最优解时有效。它将问题重新组合成子问题。为了避免多次解决这些子问题,它们的结果都逐渐被计算并被保存,从简单的问题直到整个问题都被解决。因此,动态规划保存递归时的结果,因而不会在解决同样的问题时花费时间。

动态规划只能应用于有最优子结构的问题。最优子结构的意思是局部最优解能决定全局最优解。简单地说,问题能够分解成子问题来解决。

总的来说,动态规划的优势在于:

  • 重叠子问题
  • 最优子结构
  • 记忆化


问题描述:
动态规划举例
图10-3(a)示出了一个数字三角形,请编一个程序,
计算从顶至底的某处的一条路劲,
使该路劲所经过的数字的总和最大。
(1) 每一步可沿左斜线向下或右斜线向下;
(2) 1<三角形行数≤100;
(3) 三角形中的数字为0,1,……99。
输入数据:
由INPUT.TXT文件中首先读到的是三角形的行数,
在例子中INPUT.TXT表示如图13-3(b). 
                               
                               7 
                              3 8 
                             8 1 0 
                            2 7 4 4 
                           4 5 2 6 5
                          5 6 9 5 9 8



从别人blog里看到这个题目,手上痒痒,就写了一个.用的是逆向递推法从顶部往下.
分2个文件,一个主程序和一个用于读取文件的辅助类.


思路:
  1.算出每个节点的规划值(也就是待比较的最大值),并记录搜索路径
  2.取三角形底边所有规划值中的最大值
  3.输出路径

主程序

None.gif package  test;
None.gif
import  java.util. * ;
None.gif
ExpandedBlockStart.gifContractedBlock.gif
/** */ /**
InBlock.gif *  用动态规划法求出最优路径
InBlock.gif *  
@author  zqc
ExpandedBlockEnd.gif * 
*/

ExpandedBlockStart.gifContractedBlock.gif
public   class  DynamicSolveTrianglePath  dot.gif {
InBlock.gif    
InBlock.gif    
private  String[][] str_triangle  =   null ;
InBlock.gif    
private  Node[][] triangle_nodes  =   null ;
InBlock.gif    
private  List nodes;
InBlock.gif    
private  List paths;
InBlock.gif    
InBlock.gif    
// 节点
ExpandedSubBlockStart.gifContractedSubBlock.gif
     static   class  Node dot.gif {
InBlock.gif        
private   int  value;
InBlock.gif        
private  List path  =   new  Vector();
ExpandedSubBlockStart.gifContractedSubBlock.gif        
public  List getPath()  dot.gif {
InBlock.gif            
return  path;
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockStart.gifContractedSubBlock.gif        
public   void  setPath(List p) dot.gif {
InBlock.gif            path 
=  p;
ExpandedSubBlockEnd.gif        }

InBlock.gif        
// n=(0,0) or (0,1) or (2,2)dot.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif
         public   void  addPath(String n) dot.gif {
InBlock.gif            path.add(n);
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockStart.gifContractedSubBlock.gif        
public   void  addPath(List pa) dot.gif {
InBlock.gif            path.addAll(pa);
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockStart.gifContractedSubBlock.gif        
public   int  getValue()  dot.gif {
InBlock.gif            
return  value;
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockStart.gifContractedSubBlock.gif        
public   void  setValue( int  value)  dot.gif {
InBlock.gif            
this .value  =  value;
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

InBlock.gif    
ExpandedSubBlockStart.gifContractedSubBlock.gif    
public  DynamicSolveTrianglePath() dot.gif {
InBlock.gif        initNodes();
InBlock.gif        findPath();
ExpandedSubBlockEnd.gif    }

InBlock.gif    
InBlock.gif    
//根节点开始,逆向推解出到达所有节点的最佳路径
ExpandedSubBlockStart.gifContractedSubBlock.gif
    private void initNodes()dot.gif{
InBlock.gif        
this.str_triangle = ReadTriangle.getTriangle();
InBlock.gif        triangle_nodes 
= new Node[str_triangle.length][];
InBlock.gif        nodes 
= new Vector();
ExpandedSubBlockStart.gifContractedSubBlock.gif        
for(int i = 0 ; i < str_triangle.length; i++)dot.gif{
InBlock.gif            triangle_nodes[i] 
= new Node[str_triangle[i].length];
ExpandedSubBlockStart.gifContractedSubBlock.gif            
for(int j = 0 ; j<str_triangle[i].length;j++)dot.gif{
InBlock.gif                String currentPath 
= "("+i+","+j+")";
InBlock.gif                Node n 
= new Node();
ExpandedSubBlockStart.gifContractedSubBlock.gif               
if(i==0&&j==0)dot.gif{
InBlock.gif                   n.setValue(
InBlock.gif                              c(str_triangle[
0][0])        
InBlock.gif                            );
InBlock.gif                   n.addPath(currentPath);
InBlock.gif                   triangle_nodes[i][j] 
= n;
InBlock.gif                   
continue;
ExpandedSubBlockEnd.gif               }

InBlock.gif               
//左右边界节点
ExpandedSubBlockStart.gifContractedSubBlock.gif
               if((j==0||j==str_triangle[i].length-1))dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif                   
if(i==1)dot.gif{//第2行的节点
InBlock.gif
                       int value = c(str_triangle[0][0])+c(str_triangle[i][j]);
InBlock.gif                       List ph 
= triangle_nodes[0][0].getPath();
InBlock.gif                       n.addPath(ph);
InBlock.gif                       n.addPath(currentPath);
InBlock.gif                       n.setValue(value);
InBlock.gif                       ph 
= null;
ExpandedSubBlockStart.gifContractedSubBlock.gif                   }
elsedot.gif{//0,1行以下的其他边界节点
InBlock.gif
                     int value = j==0?c(str_triangle[i][j])+triangle_nodes[i-1][j].getValue():
InBlock.gif                         c(str_triangle[i][j])
+triangle_nodes[i-1][j-1].getValue();
InBlock.gif                     List ph 
= j==0?triangle_nodes[i-1][j].getPath():
InBlock.gif                         triangle_nodes[i
-1][j-1].getPath();
InBlock.gif                     n.addPath(ph);
InBlock.gif                     n.addPath(currentPath);
InBlock.gif                     n.setValue(value);
ExpandedSubBlockEnd.gif                   }

ExpandedSubBlockStart.gifContractedSubBlock.gif               }
elsedot.gif{//除边界节点外其他节点
InBlock.gif
                       Node node1 = triangle_nodes[i-1][j-1];
InBlock.gif                       Node node2 
= triangle_nodes[i-1][j];
InBlock.gif                       Node bigger 
= max(node1,node2);
InBlock.gif                       List ph 
= bigger.getPath();
InBlock.gif                       n.addPath(ph);
InBlock.gif                       n.addPath(currentPath);
InBlock.gif                       
int val = bigger.getValue()+c(str_triangle[i][j]);
InBlock.gif                       n.setValue(val);
ExpandedSubBlockEnd.gif               }

InBlock.gif              triangle_nodes[i][j] 
= n; 
InBlock.gif              n 
= null;
ExpandedSubBlockEnd.gif            }
//end of for j
ExpandedSubBlockEnd.gif
        }
//end of for i
ExpandedSubBlockEnd.gif
    }

InBlock.gif    
ExpandedSubBlockStart.gifContractedSubBlock.gif    
private Node max(Node node1,Node node2)dot.gif{
InBlock.gif        
int i1 = node1.getValue();
InBlock.gif        
int i2 = node2.getValue();
InBlock.gif        
return i1>i2?node1:node2;
ExpandedSubBlockEnd.gif    }

InBlock.gif    
ExpandedSubBlockStart.gifContractedSubBlock.gif    
private int c(String s)dot.gif{
InBlock.gif        
return Integer.parseInt(s);
ExpandedSubBlockEnd.gif    }

InBlock.gif    
InBlock.gif    
//找出最佳路径
ExpandedSubBlockStart.gifContractedSubBlock.gif
    private void findPath()dot.gif{
InBlock.gif        
if(this.triangle_nodes==null)return;
InBlock.gif        
int max = 0;
InBlock.gif        
int mi = 0;
InBlock.gif        
int mj = 0;
ExpandedSubBlockStart.gifContractedSubBlock.gif        
for(int i = 0 ; i < triangle_nodes.length; i++)dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
for(int j = 0 ; j<triangle_nodes[i].length;j++)dot.gif{
InBlock.gif                
int t = triangle_nodes[i][j].getValue();
ExpandedSubBlockStart.gifContractedSubBlock.gif                
if(t>max)dot.gif{
InBlock.gif                    max 
= t;
InBlock.gif                    mi 
= i;
InBlock.gif                    mj 
= j;
ExpandedSubBlockEnd.gif                }

ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif        System.out.println(
"Max Path:"+triangle_nodes[mi][mj].getPath());
InBlock.gif        System.out.println(
"Max Value:"+max);
ExpandedSubBlockEnd.gif    }

InBlock.gif    
ExpandedSubBlockStart.gifContractedSubBlock.gif    
public static void main(String[] args)throws Exceptiondot.gif{
InBlock.gif        DynamicSolveTrianglePath dsp 
= new
InBlock.gif           DynamicSolveTrianglePath();
ExpandedSubBlockEnd.gif    }

InBlock.gif    
ExpandedBlockEnd.gif}

None.gif

用于读取文件的辅助类

None.gif package  test;
None.gif
import  java.io. * ;
None.gif
import  java.util. * ;
None.gif
ExpandedBlockStart.gifContractedBlock.gif
/** */ /**
InBlock.gif *  输入文本格式为
InBlock.gif *  类似这样一个数字三角形
InBlock.gif *  
InBlock.gif *          x
InBlock.gif *         x x
InBlock.gif *        x x x
InBlock.gif *       x x x x
InBlock.gif *      x x x x x 
InBlock.gif *      
InBlock.gif *  
@author  zqc
ExpandedBlockEnd.gif * 
*/

ExpandedBlockStart.gifContractedBlock.gif
public   class  ReadTriangle  dot.gif {
InBlock.gif
InBlock.gif    
public   static
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值