算法优化:动态规划加速,货物运输问题,四边形不等式, 从O(n^2)到O(n^3)
货物运输问题
递归方程为:
更为一般形式的递归方程
看起来是不是像可以使用分治的策略实现,但是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)相关推荐
- 【面向对象】记一次错误的Dijkstra算法优化—动态规划与贪心
目录 Floyd(弗洛伊德)算法 Dijkstra(迪杰斯特拉)算法 联想:贪心与动态规划--不恰当的贪心导致出错 没有学过算法,请各位大佬们轻拍 本文将简单比较一下图论中最短路的两大最短路算法:Fl ...
- 四边形不等式优化 --算法竞赛专题解析(10)
本系列文章将于2021年整理出版,书名<算法竞赛专题解析>. 前驱教材:<算法竞赛入门到进阶> 清华大学出版社 2019.8 网购:京东 当当 作者签名书 如有建议, ...
- 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]求费用 ...
- P1912-[NOI2009]诗人小G【四边形不等式,单调队列】
正题 题目链接:https://www.luogu.com.cn/problem/P1912 题目大意 给出nnn个字符串,把这些字符串依次用空格(算一个长度)连接分成若干段,若一段长度为xxx,那么 ...
- 【算法】【动态规划】【四边形不等式】画匠问题(附带问题类型总结)
目录 前言 问题介绍 解决方案 代码编写 java语言版本 c语言版本 c++语言版本 思考感悟 写在最后 前言 当前所有算法都使用测试用例运行过,但是不保证100%的测试用例,如果存在问题务必联系批 ...
- 合并石子 四边形不等式优化
题目描述 有一排石子,共n 堆.现要将石子有次序地合并成一堆.规定每次只能选相邻的2 堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的得分.试设计一个算法,计算出将n堆石子合并成一堆的最小得分. ...
- [转]四边形不等式优化dp(POJ1160)
四边形不等式优化动态规划原理: 1.当决策代价函数w[i][j]满足w[i][j]+w[i'][j']<=w[I;][j]+w[i][j'](i<=i'<=j<=j')时,称w ...
- 线性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, ...
- 四边形不等式算法证明
ps:本人小白,文章可能存在错误,希望大佬谅解或指出错误 先来看一道常规的区间dp,在这里以石子合并为例题 题目描述: 有N堆石子排成一排,每堆石子有一定的数量.现要将N堆石子并成为一堆.合并的过程只 ...
最新文章
- SpringBoot conditional注解和自定义conditional注解使用
- powerdesigner 概念模型_“使用满足”分析框架下社交媒体用户持续使用行为的概念模型研究...
- 。。。。。。想不通的ADO.NET。
- mysql f_MySQL
- centos安装 mysql_Linux centos 安装 mysql 5.6
- binlog和redo log的区别
- 简单的java信息显示_JSP实现简单的用户登录并显示出用户信息的方法
- 晚上大龙哥带来了一本vb教程,由于好奇看了下
- 【原创】Nginx+PHP-FPM优化技巧总结
- 【手游逆向】初探Unity3d+il2cpp.so网游修改新手教程篇[内附所有相关工具下载地址和说明介绍】
- 胶水语言概述(以Python为例)
- maker win10有movie_手把手解决win10系统出现windows MovieMaker故障的方法
- 笔记本如何解除锁定计算机,笔记本键盘锁定解锁方法教程
- 三角剖分与Delaunay三角剖分及带约束的Delaunay三角剖分
- 如何优雅的在 Word 中插入代码,PlanetB 的完美替代方案
- 关于短视频技术轮廓探讨
- linux下/proc/sysrq-trigger详解
- keep 虚拟路线修改器_Keep 动感单车体验:每天半小时,离瘦更近一步
- 使用Java故意消耗Cpu和内存的代码
- 目前智能手机 微型计算机,微型计算机基础知识1(新).ppt.ppt
热门文章
- 微信小程序时间转换成时间戳、获取当前时间戳、获取当前时间、时间戳加减
- python udp编程_在Python下进行UDP网络编程的教程
- linux修改文件夹名称_1.3.2 对 Hello Word! 程序代码进行编辑修改
- java 年历_逆转监督漫画
- 怎么看mysql有没有安装成功_MySQL 安装看这一篇就够了
- 在c语言中什么意思,\c在C语言中是什么意思?
- java ecj_java - 在Maven构建中使用Eclipse Java Compiler(ecj) - 堆栈内存溢出
- android 扫描所有文件大小,Android获取指定文件大小
- 【微信小程序】 自定义导航栏(navigationStyle=custom)
- java 获取进程_java获取指定进程的stat