草庐IT

yalmip实用操作(1)

电力程序小学童 2023-05-11 原文

在平时编程过程中会遇到很多非线性无法利用cplex和gurobi等求解器求解的问题,这时可以通过线性化处理的方式来转换模型,进而采用常规线性化工具进行求解,本文重点对三种非线性的问题进行转化,分别是乘积线性化、绝对值线性化和平方线性化,在每类线性化的理论公式下列出相应的yalmip程序代码,以供大家参考。

目录

1 乘积线性化

2 绝对值线性化

3 平方线性化


1 乘积线性化

虽然两个01变量相乘,但是在yalmip求解时也会被认为是非线性,这就需要按照下式进行简化:

程序代码如下:

x1=binvar(1);

x2=binvar(1);

y=binvar(1);

con=[y<=x1,y<=x2,y>=x1+x2-1];

上述即实现了模型的程序语言化,由于仅做了模型的转化,作为程序应用示例,上面代码并不能单独运行,还需要增加相应目标函数等其他代码才能完全运行,具体可运行程序可参见文后链接)。

不难发现,1.1是1.2情况的一种特例,单拿出来分析的原因在于实际处理比较多,按照1.1来实现1.2的代码并不难,在此不再赘述。

除了上述最简单的程序代码处理之外,考虑实际电力系统情形,在程序编写过程中,会遇到发电机组启停与功率的乘积项,两个参数均为变量,这就需要对其进行线性化处理,具体程序代码如下(程序仅为示例,介绍用法,并不能单独运行,有些变量赋值不全,详情可参见最终全部程序代码):

%onoff*pg线性化出处理

yg = sdpvar(ngen,Horizon);%ngen为发电机组数,Horizon为时序性

cons = [cons, yg <= PG, yg >= PG-repmat(Pgmax,1,Horizon).*(1-OnOff), repmat(Pgmin,1,Horizon).*OnOff <= yg <= repmat(Pgmax,1,Horizon).*OnOff];

2 绝对值线性化

对于模型中常用到的绝对值模型,在yalmip里面可以用implies函数轻松解决,下面先分析一下implies函数的用法。

在官网中,implies定义的是逻辑事件间的关系,换言之,implies(A,B)指的就是如果事件A为真,则B为真,即定义的是A -> B的关系。

在实际应用中,也会用到01状态->01状态的映射关系或者01状态->线性约束的映射关系,用官网的简单例子分析:

d = binvar(1);

F = implies(d,A*x <= b);

上述代码即是01状态->线性约束的映射关系程序,先定义01变量d,然后定义约束F为在d==1时满足约束A*x <= b。

通过上面的分析能够看出来,因为在yalmip编程中是不能用if和if-else语句的,implies用来替代常规程序中的if和if-else语句来实现相应约束,这里注意一点,yalmip编程时对于条件为非变量的情况时仍然可以采用if-else语句,但是当条件为变量时就需要采用implies进行编程。

下面分析采用implies进行线性化,举例在电力系统优化时常会用到负荷波动性的目标,通过程序优化减少负荷波动性可以有效降低发电机组出力(启停)频繁变动和区域电网时段性缺电问题,所以优化目标即是abs(等效负荷-平均负荷),如下图所示。

从图中能看出来,波动性目标为各时段|等效负荷-平均负荷|之和,在等效负荷大于平均负荷时取值为等效负荷-平均负荷,在等效负荷小于平均负荷时取值为平均负荷-等效负荷。具体程序为(程序仅为示例,介绍用法,并不能单独运行,有些变量赋值不全,详情可参见最终全部程序代码):

%负荷波动性目标

Pt=sdpvar(1,Horizon);%实时负荷

Pave=sdpvar(1,1);%负荷均值

Pdt=sdpvar(1,Horizon);%负荷差值绝对值

Pt=pload - x_P_w - x_P_v + x_P_ch + x_P_dis - sum(yitaph.*x_Ph) + sum(x_Pp);%等效负荷变量

Pave=sum(Pt)/Horizon;%平均负荷

lpt=binvar(2,Horizon);%二进制判断变量

for ii=1:Horizon%至整个整个时序时间段

cons = [cons, sum(lpt(:,ii)) == 1,

implies(lpt(1,ii), [Pt(1,ii)>=Pave, Pdt == Pt(1,ii) - Pave]);%大于平均值

implies(lpt(2,ii), [Pt(1,ii)<=Pave, Pdt == -Pt(1,ii) + Pave])];%小于平均值

End

3 平方线性化

平方项的线性化没有办法实现严格线性化,可以通过分段线性化进行近似表达,举一个最简单的例子。

如上图所示,将该模型分成三段,分段线性化即是在定义域内将模型采用分成n段,在每段上采用线性表达的方式,因此,当分段越细化,拟合的精确度就会越高,为了简化分析,按照图中所示分成三段进行分析,可以得到如下的分段函数。

在该分段非线性模型中,可以通过4个连续型变量w和3个01变量z进一步转换,设b为自变量分点,在该模型中分别为0、1、2、3,得到如下转换模型(参考https://www.cnblogs.com/liuxiang2020/p/11254947.html):

通过上述转化就得到了平方项的线性化转换,同样也能得到转换过程的一般形式如下:

设f(x)函数的分点分别是,引入n+1个连续变量w和n个0-1变量z,得到下述一般形式模型:

具体程序表达即是将上述模型进行程序语言化,举个例子,在电力系统中,火电机组的成本一般表达为出力的二次函数,表述为y=ax2+bx+c的形式,假定系统含有5个火电机组,可以得到程序表达如下所示(程序仅为示例,介绍用法,并不能单独运行,有些变量赋值不全,详情可参见最终全部程序代码):

%分段线性化

gn=5;%分段数

gl1=(Pgmax-Pgmin)./gn;%每个机组分段长度

gl2=zeros(3,gn+1);

for i=1:3

gl2(i,:)=Pgmin(i):gl1(i):Pgmax(i);%分点

end

cons = [cons, x_pf(1,:)==gl2(1,:).^2*gw1];

cons = [cons, x_pf(2,:)==gl2(2,:).^2*gw2];

cons = [cons, x_pf(3,:)==gl2(3,:).^2*gw3];

cons = [cons, gw1(1,:)<=gz1(1,:)];

for i=2:gn

    cons = [cons, gw1(i,:)<=gz1(i-1,:)+gz1(i,:)];

end

cons = [cons, gw1(gn+1,:)<=gz1(gn,:)];

cons = [cons, sum(gz1)==ones(1,Horizon)];

cons = [cons, gw2(1,:)<=gz2(1,:)];

for i=2:gn

    cons = [cons, gw2(i,:)<=gz2(i-1,:)+gz2(i,:)];

end

cons = [cons, gw2(gn+1,:)<=gz2(gn,:)];

cons = [cons, sum(gz2)==ones(1,Horizon)];

cons = [cons, gw3(1,:)<=gz3(1,:)];

for i=2:gn

    cons = [cons, gw3(i,:)<=gz3(i-1,:)+gz3(i,:)];

end

cons = [cons, gw3(gn+1,:)<=gz3(gn,:)];

cons = [cons, sum(gz3)==ones(1,Horizon)];

cons = [cons, PG(1,:)==gl2(1,:)*gw1];

cons = [cons, PG(2,:)==gl2(2,:)*gw2];

cons = [cons, PG(3,:)==gl2(3,:)*gw3];

结语:在编程过程中,需要我们对于模型所遇到的问题进行灵活处理,比较常见的三种线性化方法如本文所述,仍然有些高端线性化的方法通过更加复杂的数学推导可以得到,如两阶段鲁棒优化、二阶锥约束等,以后会陆续更新。

完整电力程序代码:含风电电力系统低碳调度matlab代码-专业指导文档类资源-CSDN下载本文参考考虑源荷两侧不确定性的含风电电力系统低碳调度,编写计及源荷两侧不确定性对含风电电力系统低碳调更多下载资源、学习资料请访问CSDN下载频道.https://download.csdn.net/download/zhangxd212489/79381892

电力程序定做可私信。

有关yalmip实用操作(1)的更多相关文章

  1. ruby - 在 Ruby 中编写命令行实用程序 - 2

    我想用ruby​​编写一个小的命令行实用程序并将其作为gem分发。我知道安装后,Guard、Sass和Thor等某些gem可以从命令行自行运行。为了让gem像二进制文件一样可用,我需要在我的gemspec中指定什么。 最佳答案 Gem::Specification.newdo|s|...s.executable='name_of_executable'...endhttp://docs.rubygems.org/read/chapter/20 关于ruby-在Ruby中编写命令行实用程序

  2. ruby - 如何使用 Selenium Webdriver 根据 div 的内容执行操作? - 2

    我有一个使用SeleniumWebdriver和Nokogiri的Ruby应用程序。我想选择一个类,然后对于那个类对应的每个div,我想根据div的内容执行一个Action。例如,我正在解析以下页面:https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=puppies这是一个搜索结果页面,我正在寻找描述中包含“Adoption”一词的第一个结果。因此机器人应该寻找带有className:"result"的div,对于每个检查它的.descriptiondiv是否包含单词“adoption

  3. ruby-on-rails - 如何处理 Grape 中特定操作的过滤器之前? - 2

    我正在我的Rails项目中安装Grape以构建RESTfulAPI。现在一些端点的操作需要身份验证,而另一些则不需要身份验证。例如,我有users端点,看起来像这样:moduleBackendmoduleV1classUsers现在如您所见,除了password/forget之外的所有操作都需要用户登录/验证。创建一个新的端点也没有意义,比如passwords并且只是删除password/forget从逻辑上讲,这个端点应该与用户资源。问题是Grapebefore过滤器没有像except,only这样的选项,我可以在其中说对某些操作应用过滤器。您通常如何干净利落地处理这种情况?

  4. ruby-on-rails - 在 Ruby on Rails 中发送响应之前如何等待多个异步操作完成? - 2

    在我做的一些网络开发中,我有多个操作开始,比如对外部API的GET请求,我希望它们同时开始,因为一个不依赖另一个的结果。我希望事情能够在后台运行。我找到了concurrent-rubylibrary这似乎运作良好。通过将其混合到您创建的类中,该类的方法具有在后台线程上运行的异步版本。这导致我编写如下代码,其中FirstAsyncWorker和SecondAsyncWorker是我编写的类,我在其中混合了Concurrent::Async模块,并编写了一个名为“work”的方法来发送HTTP请求:defindexop1_result=FirstAsyncWorker.new.async.

  5. ruby - 在 Ruby 中是否有一种惯用的方法来操作 2 个数组? - 2

    a=[3,4,7,8,3]b=[5,3,6,8,3]假设数组长度相同,是否有办法使用each或其他一些惯用方法从两个数组的每个元素中获取结果?不使用计数器?例如获取每个元素的乘积:[15,12,42,64,9](0..a.count-1).eachdo|i|太丑了...ruby1.9.3 最佳答案 使用Array.zip怎么样?:>>a=[3,4,7,8,3]=>[3,4,7,8,3]>>b=[5,3,6,8,3]=>[5,3,6,8,3]>>c=[]=>[]>>a.zip(b)do|i,j|c[[3,5],[4,3],[7,6],

  6. ruby-on-rails - 如何让 Rails View 返回其关联的操作名称? - 2

    我有一个非常简单的Controller来管理我的Rails应用程序中的静态页面:classPagesController我怎样才能让View模板返回它自己的名字,这样我就可以做这样的事情:#pricing.html.erb#-->"Pricing"感谢您的帮助。 最佳答案 4.3RoutingParametersTheparamshashwillalwayscontainthe:controllerand:actionkeys,butyoushouldusethemethodscontroller_nameandaction_nam

  7. Postman测试简单操作 - 2

    1、接口请求基本操作1.1例子tips在view的选项可以zoomin调整窗口字帖大小。1、创建一个测试的workspace,并命名为test2、test后面新增一个addrequest3、选择发送GET,URL为一个开源的https://api.apiopen.top/api/sentences获取每日一句4、点击send查看内容Tips:如果提示出现Error:tunnelingsocketcouldnotbeestablished,statusCode=407错误,参照以下解决办法)关于tunnelingsocketcouldnotbeestablished,cause=getaddri

  8. 【Linux操作系统】——网络配置与SSH远程 - 2

    Linux操作系统——网络配置与SSH远程安装完VMware与系统后,需要进行网络配置。第一个目标为进行SSH连接,可以从本机到VMware进行文件传送,首先需要进行网络配置。1.下载远程软件首先需要先下载安装一款远程软件:FinalShell或者xhell7FinalShellxhell7FinalShell下载:Windows下载http://www.hostbuf.com/downloads/finalshell_install.exemacOS下载http://www.hostbuf.com/downloads/finalshell_install.pkg2.配置CentOS网络安装好

  9. ruby - Ruby 语言可以用来构建操作系统吗? - 2

    Ruby语言是否可以用于创建全新的移动操作系统或桌面操作系统,即是否可以用于系统编程? 最佳答案 嗯,现在有一些操作系统使用比C更高级的语言。基本上,ruby解释器本身需要用一些低级的东西来编写,并且需要一些引导加载代码将功能齐全的ruby​​解释器作为独立内核加载到内存中。一旦ruby​​解释器被引导并以内核模式(或innerrings之一)运行,就没有什么可以阻止您在其上构建整个操作系统。不幸的是,它可能会很慢。每个操作系统功能的垃圾收集可能会相当引人注目。ruby解释器将负责任务调度和网络堆栈等基本事情,使用垃圾收集框架会大大

  10. ruby-on-rails - JSON 对象操作 - 2

    假设我们有以下描述一个人的JSON对象:{"firstName":"John","lastName":"Smith","age":25,"address":{"streetAddress":"212ndStreet","city":"NewYork","state":"NY","postalCode":"10021"},"phoneNumber":[{"type":"home","number":"212555-1234"},{"type":"fax","number":"646555-4567"}]有人可以建议在Rails3中操作前一个对象的最优雅和最有效的方法吗?我希望能够:添加另

随机推荐