【算法分析与设计】动态规划(下)(二)

简介: 【算法分析与设计】动态规划(下)

五、电路布线

  在一块电路板的上、下2端分别有n个接线柱。根据电路设计,要求用导线(i,π(i))将上端接线柱与下端接线柱相连,如图所示。其中π(i)是{1,2,…,n}的一个排列。导线(i,π(i))称为该电路板上的第i条连线。对于任何1≤i<j≤n第i条连线和第j条连线相交的充分且必要的条件是π(i)>π(j)

  电路布线问题要确定将哪些连线安排在第一层上,使得该层上有尽可能多的连线。换句话说,该问题要求确定导线集Nets={(i,π(i)),1≤i≤n}的最大不相交子集

  记

  N(i,j)的最大不相交子集为MNS(i,j)。Size(i,j)=|MNS(i,j)|。

  (1)当i=1时

  (2)当i>1时

  若j<π(i)。此时,

  故在这种情况下,N(i,j)=N(i-1,j),从而Size(i,j)=Size(i-1,j)。

2.2 j≥π(i),(i,π(i))∈MNS(i,j) 。 则对任意(t,π(t)) ∈MNS(i,j)有t<i且π(t)<π(i)。在这种情况下MNS(i,j)-{(i,π(i))}是N(i-1,π(i)-1)的最大不相交子集。

  若

  则对任意(t,π(t)) ∈MNS(i,j)有t<i。从而

  因此,Size(i,j)≤Size(i-1,j)。

  另一方面,

  故又有Size(i,j)≥Size(i-1,j),从而Size(i,j)=Size(i-1,j)。


5.1 代码

void MNS(int C[],int n){
  int i,j;
  for(j=0;j<C[1];j++){
    size[1][j]=0;
  }
  for(j=C[1];j<=n;j++){
    size[1][j]=1;
  }
  for(i=2;i<n;i++){
    for(j=0;j<C[i];j++){
      size[i][j]=size[i-1][j];
    }
    for(j=C[i];j<=n;j++){
      size[i][j]=size[i-1][j]>(size[i-1][C[i]-1]+1)?size[i-1][j]:(size[i-1][C[i]-1]+1);
    }
  }
  size[n][n]=size[n-1][n]>(size[n-1][C[n]-1]+1)?size[n-1][n]:(size[n-1][C[n]-1]+1);
}
void Traceback(int C[],int n,int NET[]){
  int i,j=n;
  int m=0;
  for(i=n;i>1;i--){
    if(size[i][j]!=size[i-1][j]){
      NET[m++]=i;
      j=C[i]-1;
    }
  if(j>=C[1])
    NET[m++]=1;
  }
} 

六、流水作业调度

  n个作业{1,2,…,n}要在由2台机器M1和M2组成的流水线上完成加工。每个作业加工的顺序都是先在M1上加工,然后在M2上加工。M1和M2加工作业i所需的时间分别为ai和bi。

  流水作业调度问题要求确定这n个作业的最优加工顺序使得从第一个作业在机器M1上开始加工,到最后一个作业在机器M2上加工完成所需的时间最少

  分析:

  直观上,一个最优调度应使机器M1没有空闲时间,且机器M2的空闲时间最少。在一般情况下,机器M2上会有机器空闲作业积压2种情况。

  设全部作业的集合为N={1,2,…,n}。S⊆N是N的作业子集。在一般情况下,机器M1开始加工S中作业时,机器M2还在加工其它作业,要等时间t后才可利用。将这种情况下完成S中作业所需的最短时间记为T(S,t)。流水作业调度问题的最优值为T(N,0)

  设π是所给n个流水作业的一个最优调度,它所需的加工时间为 aπ(1)+T’。其中T’是在机器M2的等待时间为bπ(1)时,安排作业π(2),…,π(n)所需的时间。

  记S=N-{π(1)},则有T’=T(S,bπ(1))。

  证明:事实上,由T的定义知T’≤T(S,bπ(1))。若T’>T(S,bπ(1)),设π’是作业集S在机器M2的等待时间为bπ(1)情况下的一个最优调度。则π(1), π’(2),…, π’(n)是N的一个调度,且该调度所需的时间为aπ(1)+T(S,bπ(1))<aπ(1)+T’。这与π是N的最优调度矛盾。故T’≤T(S,bπ(1))。从而T’=T(S,bπ(1))。这就证明了流水作业调度问题具有最优子结构的性质

  由 流水作业调度问题的最优子结构性质 可知,


七、投资问题

  问题:m元钱,n项投资,fi(x):将x元投入第i个项目的效益。求使得总效益最大的投资方案

  建模:问题的解是向量<x1,x2,…xn>,xi是投给项目i的钱数,i=1,2,…,n

  目标函数max{f1(x1)+f2(x2)+…+fn(xn)}

  约束条件x1+x2+…+xn=m,xi∈N


7.1 实例

  5万元钱,4个项目,效益函数如下表所示


7.2 子问题界定和计算顺序

  子问题界定:由参数k和x界定

  k:考虑对项目1,2,…,k的投资

  x:投资总钱数不超过x

  原始输入:k=n,x=m

  子问题计算顺序:

  k=1,2,…,n

  对于给定的k,x=1,2,…,m


7.3 优化函数的递推方程

  Fk(x):x元钱投给前k个项目的最大效益

  多步判断若知道p元钱(p<=x)投给前k-1个项目的最大效益Fk-1§,确定x元钱投给前k个项目的方案

  递推方程和边界条件

  Fk(x)=max{fk(xk)+Fk-1(x-xk)} k>1

  F1(x)=f1(x)


7.5 k=1时实例的计算

  F1(1)=11。

  F1(2)=12。

  F1(3)=13。

  F1(4)=14。

  F1(5)=15。


7.6 k=2时的实例计算

  方案(其它,项目2):(0,1),(1,0)

  F2(1)=max{f2(1),f1(1)}=11

  方案:(0,2),(1,1),(2,0)

  F2(2)=max{f2(2),F1(1)+f2(1),F1(2)}=12

  方案:(0,3),(1,2),(2,1),(3,0)

  F2(3)=max{f2(3),F1(1)+f2(2), F1(2)+f2(1), F1(3)}=16

  类似的计算

  F2(4)=21, F2(5)=26


7.7 备忘录和解


八、0-1背包问题

  给定n种物品和一背包。物品i的重量是wi,其价值为vi,背包的容量为C。问应如何选择装入背包的物品,使得装入背包中物品的总价值最大?

  0-1背包问题是一个特殊的整数规划问题

  设所给0-1背包问题的子问题

  算法复杂度分析:

  从m(i,j)的递归式容易看出,算法需要O(nc)计算时间。当背包容量c很大时,算法需要的计算时间较多。例如,当c>2n时,算法需要Ω(n2n)计算时间

  最优值为m(i,j),即m(i,j)是背包容量为j,可选择物品为i,i+1,…,n时0-1背包问题的最优值。由0-1背包问题的最优子结构性质,可以建立计算m(i,j)的递归式如下。

相关实践学习
消息队列RocketMQ版:基础消息收发功能体验
本实验场景介绍消息队列RocketMQ版的基础消息收发功能,涵盖实例创建、Topic、Group资源创建以及消息收发体验等基础功能模块。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
相关文章
|
2月前
|
机器学习/深度学习 算法 搜索推荐
从理论到实践,Python算法复杂度分析一站式教程,助你轻松驾驭大数据挑战!
【10月更文挑战第4天】在大数据时代,算法效率至关重要。本文从理论入手,介绍时间复杂度和空间复杂度两个核心概念,并通过冒泡排序和快速排序的Python实现详细分析其复杂度。冒泡排序的时间复杂度为O(n^2),空间复杂度为O(1);快速排序平均时间复杂度为O(n log n),空间复杂度为O(log n)。文章还介绍了算法选择、分而治之及空间换时间等优化策略,帮助你在大数据挑战中游刃有余。
91 4
|
2天前
|
缓存 算法 搜索推荐
Java中的算法优化与复杂度分析
在Java开发中,理解和优化算法的时间复杂度和空间复杂度是提升程序性能的关键。通过合理选择数据结构、避免重复计算、应用分治法等策略,可以显著提高算法效率。在实际开发中,应该根据具体需求和场景,选择合适的优化方法,从而编写出高效、可靠的代码。
15 6
|
26天前
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
57 1
|
1月前
|
算法 Python
在Python编程中,分治法、贪心算法和动态规划是三种重要的算法。分治法通过将大问题分解为小问题,递归解决后合并结果
在Python编程中,分治法、贪心算法和动态规划是三种重要的算法。分治法通过将大问题分解为小问题,递归解决后合并结果;贪心算法在每一步选择局部最优解,追求全局最优;动态规划通过保存子问题的解,避免重复计算,确保全局最优。这三种算法各具特色,适用于不同类型的问题,合理选择能显著提升编程效率。
53 2
|
2月前
|
算法
动态规划算法学习三:0-1背包问题
这篇文章是关于0-1背包问题的动态规划算法详解,包括问题描述、解决步骤、最优子结构性质、状态表示和递推方程、算法设计与分析、计算最优值、算法实现以及对算法缺点的思考。
104 2
动态规划算法学习三:0-1背包问题
|
2月前
|
并行计算 算法 IDE
【灵码助力Cuda算法分析】分析共享内存的矩阵乘法优化
本文介绍了如何利用通义灵码在Visual Studio 2022中对基于CUDA的共享内存矩阵乘法优化代码进行深入分析。文章从整体程序结构入手,逐步深入到线程调度、矩阵分块、循环展开等关键细节,最后通过带入具体值的方式进一步解析复杂循环逻辑,展示了通义灵码在辅助理解和优化CUDA编程中的强大功能。
|
2月前
|
算法
动态规划算法学习四:最大上升子序列问题(LIS:Longest Increasing Subsequence)
这篇文章介绍了动态规划算法中解决最大上升子序列问题(LIS)的方法,包括问题的描述、动态规划的步骤、状态表示、递推方程、计算最优值以及优化方法,如非动态规划的二分法。
80 0
动态规划算法学习四:最大上升子序列问题(LIS:Longest Increasing Subsequence)
|
2月前
|
算法
动态规划算法学习二:最长公共子序列
这篇文章介绍了如何使用动态规划算法解决最长公共子序列(LCS)问题,包括问题描述、最优子结构性质、状态表示、状态递归方程、计算最优值的方法,以及具体的代码实现。
175 0
动态规划算法学习二:最长公共子序列
|
2月前
|
算法
PID算法原理分析
【10月更文挑战第12天】PID控制方法从提出至今已有百余年历史,其由于结构简单、易于实现、鲁棒性好、可靠性高等特点,在机电、冶金、机械、化工等行业中应用广泛。
|
2月前
|
算法
PID算法原理分析及优化
【10月更文挑战第6天】PID控制方法从提出至今已有百余年历史,其由于结构简单、易于实现、鲁棒性好、可靠性高等特点,在机电、冶金、机械、化工等行业中应用广泛。