货物运输问题

递归方程为:

更为一般形式的递归方程

看起来是不是像可以使用分治的策略实现,但是min里面子问题太多了,只能使用动态规划的招了。

i,j是什么含义了?动态规划里i,j都是指的是问题规模,对应到货物运输问题指的是什么了?我们从数学上理解i,j是指数组arr = [1,2,3,4,5,6,7,8]两边的标号,或者子问题对应的起始和终止标号,类似与快排里面的数组的标号,实际问题抽象为数组之后,就比较容易理解,在实际问题里面i,j就非常不好理解,i,j是指的是子问题的起始标号和终止标号。

不是动态规划里[i,j]指的是问题规模吗?这里怎么是子问题的起始标号和终止标号,起始标号和终止标号实际上对应的就是问题的规模,j-i就是问题规模,也就是使用了二维表示了一维的规模,快排里也可以不适用quick_sort(arr,p,q),直接使用quick_sort(left_or_right_arr)内部直接使用的left_or_right_arr的0和end。要想原地操作就需要借助于p,q。

假如一个实际问题已经抽象成了一个数组问题,就可以直接从数组的思路考虑,暂时忘记实际的问题,从建立的模型考虑,这样就可以回到熟悉的套路上来。

现在考虑如何实现:

m[i,j] = min{m[i,k-1] + m[k,j] } + w[i,j] i<k<=j;i ==j ,m[i,j] =0

代码实现如下,这种动态规划,根据约束调价i<j,他扫描是沿着对角线方向扫描,对角线从左往右平移,直到扫描到右上角最后一个点,就是最终的解,时间复杂度为O(n^3)

# -*- coding: utf-8 -*-
import numpy as np
# 任意点到第一个点的和
def sum_(arr,n):    b = [0]*(n+1)    for i in range(1,n+1):b[i] = b[i-1] + arr[i-1]        return b
# 任意两点之间的数组和
def weight_i_j(b,i,j):return b[j+1]-b[i]#  m[i,j] = min{m[i,k-1] + m[k,j] } + w[i,j]  i<k<=j,0<i<j<n+1
# i ==j ,m[i,j] =0def DynamicProgramming(arr):n = len(arr)b = sum_(arr,n)print(b)# 初始化,这个问题初始化为i==j时为0,也就是对角线上均为0m = np.zeros((n,n),int)solution = np.full((n,n),-1)# 扫描的时候注意了,这种类型的问题,扫描顺序不是从左到右,从上到下# 扫描的基准是j-i的间距,沿着对角线往右上扫描,这里的i就是为j-i的长度,扫描的最后就是# m[0,n-1],这个就是最后的解# i <j 所以间距为从1 到 n-1for r in range(1,n):# 沿着对角线往下走for i in range(n-r):j = i + r        # 首先取第一个k = i+1m[i][j] = m[i][i] + m[i+1][j]# 用于解的追踪solution[i][j] = i# 比较求最小的for k in range(i+2,j+1):temp = m[i][k-1] + m[k][j]if temp < m[i][j]:m[i][j] = tempsolution[i][j] = k-1# min{m[i,k-1] + m[k,j] } + w[i,j]       m[i][j] += weight_i_j(b,i,j)return m,solutionarr = [1000,22,13,4,5000,86,57,18]
print(arr)
m,s = DynamicProgramming(arr)
print(m)
print(end='\n')
print(s)runfile('D:/share/test/dp.py', wdir='D:/share/test')
[1000, 22, 13, 4, 5000, 86, 57, 18]
[0, 1000, 1022, 1035, 1039, 6039, 6125, 6182, 6200]
[[    0  1022  1070  1095  7134 12306 12563 12692][    0     0    35    56  5095 10220 10420 10531][    0     0     0    17  5034 10137 10337 10448][    0     0     0     0  5004 10094 10294 10405][    0     0     0     0     0  5086  5286  5397][    0     0     0     0     0     0   143   236][    0     0     0     0     0     0     0    75][    0     0     0     0     0     0     0     0]][[-1  0  0  0  3  3  3  3][-1 -1  1  1  3  4  4  4][-1 -1 -1  2  3  4  4  4][-1 -1 -1 -1  3  4  4  4][-1 -1 -1 -1 -1  4  4  4][-1 -1 -1 -1 -1 -1  5  5][-1 -1 -1 -1 -1 -1 -1  6][-1 -1 -1 -1 -1 -1 -1 -1]]

四边形不等式

结论


回到实际的问题

代码实现如下,实现的时候,只要把原来的i<k<=j,修改成s[i,j-1]<=k<=s[i+1,j]就可以了,时间复杂度为O(n^2),加速算法有点问题,s初始化都为0,那k不是只能取0吗?程序还怎么走?

def DynamicProgrammingSpeed(arr):n = len(arr)b = sum_(arr,n)print(b)# 初始化,这个问题初始化为i==j时为0,也就是对角线上均为0m = np.zeros((n,n),int)solution = np.full((n,n),0)# 扫描的时候注意了,这种类型的问题,扫描顺序不是从左到右,从上到下# 扫描的基准是j-i的间距,沿着对角线往右上扫描,这里的i就是为j-i的长度,扫描的最后就是# m[0,n-1],这个就是最后的解# i <j 所以间距为从1 到 n-1for r in range(1,n):# 沿着对角线往下走for i in range(n-r):j = i + r        # 利用四边形不等式,把范围缩小为s[i][j-1]到s[i+1][j]i1 = solution[i][j-1]j1 = solution[i+1][j]# 首先取第一个k = i1m[i][j] = m[i][i1-1] + m[i1][j]# 用于解的追踪solution[i][j] = i1-1# 比较求最小的for k in range(i1+1,j1+1):temp = m[i][k-1] + m[k][j]if temp < m[i][j]:m[i][j] = tempsolution[i][j] = k-1# min{m[i,k-1] + m[k,j] } + w[i,j]       m[i][j] += weight_i_j(b,i,j)return m,solution   

算法优化:动态规划加速,货物运输问题,四边形不等式, 从O(n^2)到O(n^3)相关推荐

  1. 【面向对象】记一次错误的Dijkstra算法优化—动态规划与贪心

    目录 Floyd(弗洛伊德)算法 Dijkstra(迪杰斯特拉)算法 联想:贪心与动态规划--不恰当的贪心导致出错 没有学过算法,请各位大佬们轻拍 本文将简单比较一下图论中最短路的两大最短路算法:Fl ...

  2. 四边形不等式优化 --算法竞赛专题解析(10)

    本系列文章将于2021年整理出版,书名<算法竞赛专题解析>. 前驱教材:<算法竞赛入门到进阶> 清华大学出版社 2019.8 网购:京东 当当      作者签名书 如有建议, ...

  3. Loj#6039-「雅礼集训 2017 Day5」珠宝【四边形不等式,dp】

    正题 题目链接:https://loj.ac/p/6039 题目大意 有nnn个物品,第iii个费用为wiw_iwi​,价值为viv_ivi​,对于k∈[1,m]k\in[1,m]k∈[1,m]求费用 ...

  4. P1912-[NOI2009]诗人小G【四边形不等式,单调队列】

    正题 题目链接:https://www.luogu.com.cn/problem/P1912 题目大意 给出nnn个字符串,把这些字符串依次用空格(算一个长度)连接分成若干段,若一段长度为xxx,那么 ...

  5. 【算法】【动态规划】【四边形不等式】画匠问题(附带问题类型总结)

    目录 前言 问题介绍 解决方案 代码编写 java语言版本 c语言版本 c++语言版本 思考感悟 写在最后 前言 当前所有算法都使用测试用例运行过,但是不保证100%的测试用例,如果存在问题务必联系批 ...

  6. 合并石子 四边形不等式优化

    题目描述 有一排石子,共n 堆.现要将石子有次序地合并成一堆.规定每次只能选相邻的2 堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的得分.试设计一个算法,计算出将n堆石子合并成一堆的最小得分. ...

  7. [转]四边形不等式优化dp(POJ1160)

    四边形不等式优化动态规划原理: 1.当决策代价函数w[i][j]满足w[i][j]+w[i'][j']<=w[I;][j]+w[i][j'](i<=i'<=j<=j')时,称w ...

  8. 线性DP 四边形不等式优化 hdu3506

    当函数w(i,j)满足 w(a,c)+w(b,d) <= w(b,c)+w(a,d) 且a<=b< c <=d 时,我们称w(i,j)满足四边形不等式..   当函数w(i, ...

  9. 四边形不等式算法证明

    ps:本人小白,文章可能存在错误,希望大佬谅解或指出错误 先来看一道常规的区间dp,在这里以石子合并为例题 题目描述: 有N堆石子排成一排,每堆石子有一定的数量.现要将N堆石子并成为一堆.合并的过程只 ...

最新文章

  1. SpringBoot conditional注解和自定义conditional注解使用
  2. powerdesigner 概念模型_“使用满足”分析框架下社交媒体用户持续使用行为的概念模型研究...
  3. 。。。。。。想不通的ADO.NET。
  4. mysql f_MySQL
  5. centos安装 mysql_Linux centos 安装 mysql 5.6
  6. binlog和redo log的区别
  7. 简单的java信息显示_JSP实现简单的用户登录并显示出用户信息的方法
  8. 晚上大龙哥带来了一本vb教程,由于好奇看了下
  9. 【原创】Nginx+PHP-FPM优化技巧总结
  10. 【手游逆向】初探Unity3d+il2cpp.so网游修改新手教程篇[内附所有相关工具下载地址和说明介绍】
  11. 胶水语言概述(以Python为例)
  12. maker win10有movie_手把手解决win10系统出现windows MovieMaker故障的方法
  13. 笔记本如何解除锁定计算机,笔记本键盘锁定解锁方法教程
  14. 三角剖分与Delaunay三角剖分及带约束的Delaunay三角剖分
  15. 如何优雅的在 Word 中插入代码,PlanetB 的完美替代方案
  16. 关于短视频技术轮廓探讨
  17. linux下/proc/sysrq-trigger详解
  18. keep 虚拟路线修改器_Keep 动感单车体验:每天半小时,离瘦更近一步
  19. 使用Java故意消耗Cpu和内存的代码
  20. 目前智能手机 微型计算机,微型计算机基础知识1(新).ppt.ppt

热门文章

  1. 微信小程序时间转换成时间戳、获取当前时间戳、获取当前时间、时间戳加减
  2. python udp编程_在Python下进行UDP网络编程的教程
  3. linux修改文件夹名称_1.3.2 对 Hello Word! 程序代码进行编辑修改
  4. java 年历_逆转监督漫画
  5. 怎么看mysql有没有安装成功_MySQL 安装看这一篇就够了
  6. 在c语言中什么意思,\c在C语言中是什么意思?
  7. java ecj_java - 在Maven构建中使用Eclipse Java Compiler(ecj) - 堆栈内存溢出
  8. android 扫描所有文件大小,Android获取指定文件大小
  9. 【微信小程序】 自定义导航栏(navigationStyle=custom)
  10. java 获取进程_java获取指定进程的stat