当前位置: 首页 > news >正文

机器人中的数值优化(十二)——带约束优化问题简介、LP线性规划

   本系列文章主要是我在学习《数值优化》过程中的一些笔记和相关思考,主要的学习资料是深蓝学院的课程《机器人中的数值优化》和高立编著的《数值最优化方法》等,本系列文章篇数较多,不定期更新,上半部分介绍无约束优化,下半部分介绍带约束的优化,中间会穿插一些路径规划方面的应用实例



   十八、带约束优化简介

   1、简单的例子看有无约束的区别

   在如下图所示的表达式f(x)中,无约束优化求得最最优解位于原点处,即图中的①处,若对该问题添加了不等式约束g(x)使解得范围约束在图中的红色椭圆内,此时,求得的最优解,为图中②处

在这里插入图片描述


   2、带约束优化的类别及复杂性

在这里插入图片描述

   (1)、线性规划LP

   目标函数是线性的,等式约束和不等式约束也是线性的,x是决策变量,c、d、A、b、G、h都是常数矩阵或向量

   (2)、二次规划QP

   目标函数含有二次项,一般情况下矩阵Q是半正定的,即Q>=0,等式约束或不等式约束一般是线性的。

   (3)、锥规划SOCP

   目标函数线性的,一般情况下,不等式约束由一个线性表达式的二范数小于等于另一个线性表达式的形式给出。

   (4)、半定锥规划SDP

   目标函数线性的,一般情况下,不等式约束由广义的不等式形式给出,(喇叭形状的大于等于号是半正定的意思)

   (5)、一般形式的带约束的优化问题

在这里插入图片描述


   一般来说,不加说明的话,LP、SOCP、SDP的目标函数都是线性的,等式约束也是线性的,他们的差别在不等式约束上,一般来说LP的线性不等式约束区域是一个凸多面体,SOCP的不等式约束是一个锥的形状,锥的表面和内部都是可行解。

在这里插入图片描述


   最坏时间复杂度如上图右侧所示,其中m是问题的约束个数,n是x的维度,L是求解精度,比如10的负多少次方,即精确到小数点后几位的位数。SOCP中的ki是锥的维度,m个锥的维度可能不同。SDP中的ki表示,m个广义不等式中Ai或Bi的行向量或列向量的个数。从LP→SOCP→SDP复杂度是增长的。

在这里插入图片描述

   另一类分类方式是按照近似优化算法和精确优化算法划分的,精确优化算法可以在有限次迭代后精确的收敛到最优解,而近似优化算法可以不断的逼近最优解。

在这里插入图片描述


   十九、低维度LP线性规划

   线性规划(Linear Programming,简称LP)是数学规划中的一个重要分支,用于解决在给定一组线性约束条件下,优化一个线性目标函数的问题。线性规划在工程、经济、管理等领域有广泛的应用,它能够找到最优的决策方案,使得目标函数的值达到最大或最小。

   一般线性规划问题可以表示为以下标准形式:

   最大化或最小化: f = c 1 x 1 + c 2 x 2 + … + c n x n + d f = c_1x_1 + c_2x_2 + \ldots + c_nx_n+d f=c1x1+c2x2++cnxn+d

   不等式约束为:

   a 11 x 1 + a 12 x 2 + … + a 1 n x n ≤ b 1 a_{11}x_1 + a_{12}x_2 + \ldots + a_{1n}x_n \leq b_1 a11x1+a12x2++a1nxnb1

   a 21 x 1 + a 22 x 2 + … + a 2 n x n ≤ b 2 a_{21}x_1 + a_{22}x_2 + \ldots + a_{2n}x_n \leq b_2 a21x1+a22x2++a2nxnb2

   ⋮ \vdots

   a m 1 x 1 + a m 2 x 2 + … + a m n x n ≤ b m a_{m1}x_1 + a_{m2}x_2 + \ldots + a_{mn}x_n \leq b_m am1x1+am2x2++amnxnbm

   其中, f f f是要优化的目标函数值, c 1 , c 2 , … , c n c_1, c_2, \ldots, c_n c1,c2,,cn是目标函数中各项的系数, x 1 , x 2 , … , x n x_1, x_2, \ldots, x_n x1,x2,,xn是决策变量, a i j a_{ij} aij是约束条件矩阵的元素, b i b_i bi是约束条件的右侧常数项。上面的展开式形式可以写成以下的矩阵形式:

   min ⁡ c T x + d s . t . A x ≤ b G x = h \min\quad c^\mathrm{T}x+d\quad\mathrm{s.t.}\quad Ax\leq b\quad Gx=h mincTx+ds.t.AxbGx=h

在这里插入图片描述

   线性规划的目标是找到一组决策变量 x 1 , x 2 , … , x n x_1, x_2, \ldots, x_n x1,x2,,xn,使得目标函数 f f f的值最小化或最大化。同时,这组决策变量要满足所有的约束条件。

   每个不等式约束在几何上限制了一个半空间区域,半空间即线的某一侧区域,所有的半空间取交集即下图中蓝紫色的可行域

在这里插入图片描述


   由不等式约束确定了可行域后,在可行域内求解使得 f = c T x + d f=c^\mathrm{T}x+d f=cTx+d最大或最小,d为常量,即在可行域内找到一个使得 c T x c^\mathrm{T}x cTx最大或最小的点 v o p t v_{opt} vopt,使这样一个内积运算的值最大,即在可行域内找一个点 v o p t v_{opt} vopt,构成一个向量x,使得其在c方向上的投影最大。

   此时,最大值 c T v o p t > = c T x c^\mathrm{T}v_{opt} >= c^\mathrm{T}x cTvopt>=cTx,其中x是可行域内任意一点,由该表达式可确定如下图红线及箭头所表示的半空间,该半空间包含整个可行域,容易看出,LP问题的最优解 v o p t v_{opt} vopt常位于多边形区域内的某个顶点上。

在这里插入图片描述


   工程中的许多优化问题都是线性规划。其中一个比较精确的实用算法是单纯形算法(Simplex Method)。单纯形算法虽然是精确的,但在最坏的情况下,其复杂度可能是随问题的参数指数增长的。也有一些伪多项式算法,比如内点法(Interior point methods,IPM),只能提供近似解,计算强度也比较大。一般只在规模很大的情况下才用内点法。在路径规划中,常处理维度较低(如1<=d<=10),但约束个数较多的问题(m很大),往往需要高效率的去求解一些精确解。

   (1)一维情况

   对于下面例子中给出的一维的情况,很容易在线性时间内(O(n))得到其精确解,其中c、a1 ~ an,b1 ~ bn 为一维常数,x为一维变量

在这里插入图片描述

   假设存在如下图所示的6个不等式约束,很容易得到如下图中红色区域所示的可行域

在这里插入图片描述

   (2)二维情况

   对于下图中所示的二维的情况,两个不等式约束对应的半空间的交集为可行域,即图中绿色区域,c和x都是二维的,目标函数在红线的上侧取得最大值,可得精确解为图中的v0点。

在这里插入图片描述

   若此时加入一个新的不等式约束h1,此时可行域变为下图所示的绿色区域,加入约束h1之前得到的最优解v0已经不在可行域中,此时目标函数的最优的精确解变为v1点,易知v1点必然位于新加入的约束h1的某个顶点处,再加入新的约束h2后,由于加入约束h2之前的最优解v1依然在当前可行域中,此时的精确解v2=v1,即加入新约束h2后,最优解没有改变,依次类推,再加入新的约束h3后,精确解变为v3,再加入新的约束h4后,精确解为v4=v3。

在这里插入图片描述

   我们对上述过程进行总结,当我们加入一个新的约束 h i h_i hi时,若已知在约束 h 1 h_1 h1 ~ h i − 1 h_{i-1} hi1下的最优解为 v i − 1 v_{i-1} vi1,基于这些信息,如何获取加入新的约束 h i h_i hi后的最优解 v i v_i vi,可分为两种情况:

   ① 若 v i − 1 v_{i-1} vi1属于新加入的约束 h i h_i hi对应的半空间内,即加入新约束 h i h_i hi后, v i − 1 v_{i-1} vi1依然在可行域中,此时最优解不变, v i v_{i} vi= v i − 1 v_{i-1} vi1

   ② 若 v i − 1 v_{i-1} vi1不属于新加入的约束 h i h_i hi对应的半空间内,即加入新约束 h i h_i hi后, v i − 1 v_{i-1} vi1已经不在可行域中了,此时新的最优解 v i v_{i} vi必然位于新加入的约束 h i h_i hi的边界与之前某个约束的边界相交的顶点上,退一步来说,此时新的最优解 v i v_{i} vi必然位于新约束 h i h_i hi的边界 l i l_i li上,此时,我们可以把之前所有的约束 h 1 h_1 h1 ~ h i − 1 h_{i-1} hi1投影到 l i l_i li上,转化为上面介绍的一维的情况,即在一维线区域 l i l_i li上寻求满足各个约束投影的区间的交集,再配合目标函数,即可得到此时的最优解 v i v_{i} vi

在这里插入图片描述

   如果我们随机化约束条件的输入顺序,采用以上增量式方法进行求解,理论上期望的时间复杂度是线性的。

在这里插入图片描述

   可以使用Fisher-Yates算法对约束条件的顺序进行打乱,Fisher-Yates算法的目标是给定一个n,随机生成一个1 ~ n 的排列,给定n后,有n!,即n的阶乘种可能的排列,Fisher-Yates算法生成任意一种排列的概率是相同的,每种排列的可能性都是1/(n!)

   用C++实现时,可以使用 < random >库来实现生成1~m中任意一个整数的功能,来供Fisher-Yates算法调用。

   Fisher-Yates算法的流程如下:

   ①、首先初始化一个1~n的序列,该序列中第几个位置上的数就是几,如序列第n的位置上存放的数值就是n。

   ②、随机生成一个1~n之间的整数k1,将序列第k1位置上存放的数值,与序列第n个位置上存放的数值进行交换。

   ③、随机生成一个1~(n-1)之间的整数k2,将序列第k2位置上存放的数值,与序列第(n-1)位置上存放的数值进行交换。

  

  

  

   依次类推,直至随机生成1~2之间的一个数(kn-1),将序列第(kn-1)位置上存放的数值,与序列第2个位置上存放的数值进行交换。完成后,Fisher-Yates算法就生成了一个由整数1 ~ n构成 的排列。


   (3)更一般的d维情况(d一般是比较小的个位数)

   d维的LP线性规划的主要思想是,d维的线性规划在遇到新加入的超平面是Exact时,将其转换成d-1维的线性规划,这跟上面2维线性规划时转换成1维线性规划的思想是相同的,这种思想有点像递归的思想。

在这里插入图片描述

   上图中给出的伪代码中,输入参数H即不等式约束 a T x < = b a^\mathrm{T}x<=b aTx<=b,也即一系列半空间,输入参数c即 c T x c^\mathrm{T}x cTx中的系数,如果此时c的维度是一维的,则直接采用上文中介绍的一维情况的解决方法求解,若此时c不是一维的,则初始化一个空集 I I I,可以提前用Fisher-Yates算法对H的序列进行打乱,打乱后进行for循环时,每次依次从H中取一个h,然后判断:

   情况1:若当前最优解属于h,则当前最优解满足约束h,不需要计算新的最优解,直接将h添加到集合 I I I中,继续进行下一轮for循环,处理下一个约束h

   情况2:若当前的最优解不属于h,则需要计算一个新的最优解x,将已经加入到集合 I I I中的约束用高斯消元法投影到约束h的边界上,得到低一个维度的H’,然后将c也用高斯消元法投影到h上,得到低一个维度的c’,然后将低一个维度的H’和c’作为参数递归调用SeidelLP()函数本身进行降维处理,直至降为1维情况。然后就可以得到新的最优解x,此时约束h已经满足,将其添加到集合 I I I中,本轮循环结束,继续进行下一轮for循环,处理下一个约束h。

   for循环结束后,即可得到满足所有约束hi的最优解x


   当d的维数较大时,比如d是20维的,深层次的递归调用可能出现复杂度爆炸,但当d的维数是个位数时,可以高效率的得到精确解。


   接下来借助下图中的例子,来看一下如何使用高斯消元法将d维的半空间,投影成d-1维的半空间:

在这里插入图片描述


   Seidel′s LP线性规划可以高效的处理维度不高,约束很多的情况,可以得到高效率的精确解。下图给出了一些应用实例

在这里插入图片描述

   (1)线性可分问题:假设图中红色凸多边形是障碍物,蓝色凸多边形是机器人或机器人的一部分,现在想要知道机器人是否与障碍物发生了碰撞,可以将障碍物的顶点及其内部的一些冗余点vi与机器人的顶点及其内部的一些冗余点wi,若他们不碰撞,那必然存在一个分离超平面,设该超平面为 a T x < = b a^\mathrm{T}x<=b aTx<=b,则机器人满足 a T w i < = b a^\mathrm{T}w_{i}<=b aTwi<=b,障碍物满足 a T v i > = b a^\mathrm{T}v_{i}>=b aTvi=b,在这两组约束下,求解目标函数 c T x c^\mathrm{T}x cTx,这里的x即为a,b构成的向量,c可设成0向量。可求得任意一个可行超平面,说明两者没有碰撞。Seidel′s LP线性规划可以很好的用于检测机器人是否与障碍物发生了碰撞。

在这里插入图片描述

在这里插入图片描述


   (2)圆形可分问题,在工业流水线的机器视觉中有时需要判断是否存在一个圆来分隔两种点集,如下图中的蓝色点集和红色点集

在这里插入图片描述
   可以进行升维处理,将圆形区域作为增加的维度,下图等式中右侧是一个线性可分问题,若右侧表达式线性可分,则左侧表达式存在圆形来分隔两个点集

在这里插入图片描述


   (3)在安全区域中找一个点,距离安全区域的边界的距离最大化,即在安全区域中找一个圆,使得该圆的半径最大化,即最小的碰撞距离最大化,此时圆心即为所求的最安全的点。

在这里插入图片描述



   参考资料:

   1、数值最优化方法(高立 编著)

   2、机器人中的数值优化



相关文章:

机器人中的数值优化(十二)——带约束优化问题简介、LP线性规划

本系列文章主要是我在学习《数值优化》过程中的一些笔记和相关思考&#xff0c;主要的学习资料是深蓝学院的课程《机器人中的数值优化》和高立编著的《数值最优化方法》等&#xff0c;本系列文章篇数较多&#xff0c;不定期更新&#xff0c;上半部分介绍无约束优化&#xff0c;…...

如何解决使用 ISPC 构建编译项目代码的时候出现_ISPCAlloc、_ISPCLaunch、_ISPCSync的连接器错误

一般在编译 ISPC 代码到时候&#xff0c;构建方法如下&#xff1a; $ ispc add.ispc -o add.o -h add.h $ g main.cpp add.o 但是在一些情况下连接器会报以下错误&#xff1a; $ g main.cpp add.o Undefined symbols for architecture x86_64:"_ISPCAlloc", refer…...

Hadoop 集群一直处于安全模式,强制退出后出现数据丢失警告。解决方法

文章目录 安全模式相关命令分析集群为什么一直处于安全模式解决方法 安全模式相关命令 # 查看安全模式状态 hdfs dfsadmin -safemode get# 进入安全模式 hdfs dfsadmin -safemode enter# 离开安全模式 hdfs dfsadmin -safemode leave# 强制退出安全模式 hdfs dfsadmin -safemo…...

四旋翼飞行器基本模型(MatlabSimulink)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

P1116 车厢重组(冒泡排序)

题目描述 在一个旧式的火车站旁边有一座桥&#xff0c;其桥面可以绕河中心的桥墩水平旋转。一个车站的职工发现桥的长度最多能容纳两节车厢&#xff0c;如果将桥旋转 180 180 180 度&#xff0c;则可以把相邻两节车厢的位置交换&#xff0c;用这种方法可以重新排列车厢的顺序…...

Android逆向学习(番外一)smali2java部分文件无法反编译的bug与修复方法

Android逆向学习&#xff08;番外一&#xff09;smali2java部分文件无法反编译的bug与修复方法 一、前言 昨天我和往常一样准备着android逆向&#xff08;四&#xff09;的博客&#xff0c;结果发现smali2java对某些文件无法进行逆向&#xff0c;我不知道windows会不会产生这…...

go语言基本操作---三

变量的内存和变量的地址 指针是一个代表着某个内存地址的值。这个内存地址往往是在内存中存储的另一个变量的值的起始位置。Go语言对指针的支持介于java语言和C/C语言之间&#xff0c;它即没有想Java语言那样取消了代码对指针的直接操作的能力&#xff0c;也避免了C/C语言中由…...

ArcGIS Enterprise + ArcGIS Pro 常用服务类型发布

发布前设置 门户连接 首先Pro需要先连接portal 添加portal门户地址&#xff0c;注意只到WA一级地址&#xff0c;并登录&#xff1a; 登录完成后&#xff0c;右键&#xff0c;设置为活动门户&#xff1a; 1. 发布动态地图服务 关联数据文件夹&#xff1a; 拖拽数据到地图…...

优思学院|亲和图案例:寻找六西格玛的项目

什么是亲和图&#xff1f; 亲和图&#xff08;Affinity Diagram&#xff09;主要功能在於分类归纳&#xff0c;协助在一堆杂乱无章的资料之中&#xff0c;有系统的归纳出几个大类&#xff0c;以利后续作业。通常先利用头脑风暴&#xff08;Brainstorming&#xff09;方式得到大…...

tomcat 的缓存机制

HTTP缓存&#xff1a;Tomcat支持HTTP缓存机制&#xff0c;可以通过设置响应头中的Cache-Control、Expires和ETag等字段来控制缓存策略。这些字段告诉浏览器是否可以缓存响应以及缓存的有效期等信息。 Servlet缓存&#xff1a;Tomcat还提供了Servlet缓存机制&#xff0c;它可以…...

laravel 压缩文件与解压文件

一、引入第三方类 composer require chumper/zipper二、第三方类配置 providers>[Chumper\Zipper\ZipperServiceProvider::class ]aliases > [Zipper > Chumper\Zipper\Zipper::class ]三、压缩解压缩实例 <?php namespace App\Http\Controllers\Upload; use A…...

kind搭建k8s集群用于测试

安装kind 需要先安装go kind基于go开发 #第一种安装方式#修改go源加快下载速度 go env -w GOPROXYhttps://goproxy.cn,direct #直接下载安装kind最新版本 go install sigs.k8s.io/kindlatest #进入GOPATH目录找到bin目录下kind执行程序 移动到环境变量里 mv ./kind /usr/local…...

软件测试人需要掌握的测试知识架构体系(上)

软件计划与可行性研究&#xff08;问题定义、可行性研究&#xff09;&#xff1b;需求分析&#xff1b;软件设计&#xff08;概要设计、详细设计&#xff09;&#xff1b;编码&#xff1b;软件测试&#xff1b;运行与维护。 一、软件的生命周期(SDLC) 1、生存周期划分 各阶段…...

QT数据库,实现数据库增删改查

QT关于数据库的相关概念 QT将数据库分为三个层次&#xff1a; 数据库驱动层&#xff1a;QSqlDriver、QSqlDriverCreator、QSqlDriverCreatorBase、QSqlDriverPlugin sql接口层&#xff1a;QSqlDatabase、QSqlQuery、QSqlRecord、QSqlError 用户接口层&#xff1a;提供一些模…...

SQL-子查询

SQL 子查询 是指将一个SELECT查询&#xff08;子查询&#xff09;的结果用括号括起来作为另一个SQL语句的数据来源或者判断条件...

【8章】Spark编程基础(Python版)

课程资源&#xff1a;&#xff08;林子雨&#xff09;Spark编程基础(Python版)_哔哩哔哩_bilibili 第8章 Spark MLlib&#xff08;6节&#xff09; 机器学习算法库 &#xff08;一&#xff09;MLlib简介 1、机器学习 机器学习可以看做是一门人工智能的科学&#xff0c;该领…...

桌面应用小程序,一种创新的跨端开发方案

Qt Group在提及2023年有桌面端应用程序开发热门趋势时&#xff0c;曾经提及三点&#xff1a; 关注用户体验&#xff1a;无论您是为桌面端、移动端&#xff0c;还是为两者一起开发应用程序&#xff0c;有一点是可以确定的&#xff1a;随着市场竞争日益激烈&#xff0c;对产品的期…...

将本地jar打包到本地maven仓库或maven私服仓库中

将本地jar包打包到本地的maven仓库中的命令&#xff1a; mvn install:install-file -DgroupIdtebie.applib.api -DartifactIdapiclient -Dversion1.0-SNAPSHOT -Dfile本地jar路径 -Dpackagingjar说明&#xff1a; DgroupId pom中的<groupId></groupId> Dartifact…...

java 实现建造者模式

建造者模式&#xff08;Builder Pattern&#xff09;是一种创建型设计模式&#xff0c;用于创建一个复杂对象&#xff0c;将对象的构建过程与其表示分离&#xff0c;以便可以使用相同的构建过程来创建不同的表示。在Java中&#xff0c;可以使用建造者模式来构建具有多个属性的对…...

串行FIR滤波器

串行 FIR 滤波器设计 串行设计&#xff0c;就是在 16 个时钟周期内对 16 个延时数据分时依次进行乘法、加法运算&#xff0c;然后在时钟驱动下输出滤波值。考虑到 FIR 滤波器系数的对称性&#xff0c;计算一个滤波输出值的周期可以减少到 8 个。串行设计时每个周期只进行一次乘…...

电脑插入多块移动硬盘后经常出现卡顿和蓝屏

当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时&#xff0c;可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案&#xff1a; 1. 检查电源供电问题 问题原因&#xff1a;多块移动硬盘同时运行可能导致USB接口供电不足&#x…...

2.Vue编写一个app

1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

Python如何给视频添加音频和字幕

在Python中&#xff0c;给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加&#xff0c;包括必要的代码示例和详细解释。 环境准备 在开始之前&#xff0c;需要安装以下Python库&#xff1a;…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

深度学习习题2

1.如果增加神经网络的宽度&#xff0c;精确度会增加到一个特定阈值后&#xff0c;便开始降低。造成这一现象的可能原因是什么&#xff1f; A、即使增加卷积核的数量&#xff0c;只有少部分的核会被用作预测 B、当卷积核数量增加时&#xff0c;神经网络的预测能力会降低 C、当卷…...

搭建DNS域名解析服务器(正向解析资源文件)

正向解析资源文件 1&#xff09;准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2&#xff09;服务端安装软件&#xff1a;bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...

【JavaSE】多线程基础学习笔记

多线程基础 -线程相关概念 程序&#xff08;Program&#xff09; 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序&#xff0c;比如我们使用QQ&#xff0c;就启动了一个进程&#xff0c;操作系统就会为该进程分配内存…...

Golang——9、反射和文件操作

反射和文件操作 1、反射1.1、reflect.TypeOf()获取任意值的类型对象1.2、reflect.ValueOf()1.3、结构体反射 2、文件操作2.1、os.Open()打开文件2.2、方式一&#xff1a;使用Read()读取文件2.3、方式二&#xff1a;bufio读取文件2.4、方式三&#xff1a;os.ReadFile读取2.5、写…...

关于uniapp展示PDF的解决方案

在 UniApp 的 H5 环境中使用 pdf-vue3 组件可以实现完整的 PDF 预览功能。以下是详细实现步骤和注意事项&#xff1a; 一、安装依赖 安装 pdf-vue3 和 PDF.js 核心库&#xff1a; npm install pdf-vue3 pdfjs-dist二、基本使用示例 <template><view class"con…...

wpf在image控件上快速显示内存图像

wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像&#xff08;比如分辨率3000*3000的图像&#xff09;的办法&#xff0c;尤其是想把内存中的裸数据&#xff08;只有图像的数据&#xff0c;不包…...