主要内容

研究线性不可行性

这个例子展示了如何调查引起的线性约束问题是不可行的。有关这些技术的更多细节,看到这个[1][2]

如果线性约束引起的问题是不可行的,你可能想找一个子集的约束是不可行的,但删除子集的任何成员使其他可行的子集。这样的一个子集的名字不可约的不可行的子集的限制,缩写为IIS。相反,您可能希望找到一个最大基数约束的子集是可行的。这个子集被称为最大可行的子集,缩写maxf。这两个概念是相关的,但又不完全相同。一个问题可以有很多不同的IISs,一些不同的基数。

这个例子展示了两种方式找到一个IIS,和两种方式获得一套可行的约束。给出的例子假定所有范围是正确的,这意味着乌兰巴托参数没有错误。

不可行的例子

创建一个随机矩阵一个代表线性不等式的大小150 -,- 15所示。设置相应的向量b与10项向量,和5%的值更改为-10。

N = 15;rng默认的一个= randn ((10 * N, N));b = 10 *的(大小(A, 1), 1);Aeq = [];说真的= [];b(兰德(大小(b)) < = 0.05) = -10;f =的(N - 1);磅= - f;乌兰巴托= f;

检查问题是不可行的。

[x, fval exitflag、输出λ)= linprog (f, A、b Aeq,说真的,磅,乌兰巴托);
没有找到可行的解决方案。Linprog停止,因为没有点满足约束。

删除过滤器

确定一个IIS,执行以下步骤。给定一组线性约束的编号1到N,约束是不可行的,所有问题:

为每一个从1到N:

  • 暂时删除约束从这个问题。

  • 测试结果问题的可行性。

  • 如果问题是可行的,没有约束,还约束问题的办法。

  • 如果问题没有可行的,没有约束,不要返回约束这个问题

继续下一个(价值N)。

这个过程结束时,约束留在问题形成一个IIS。

MATLAB®代码实现这个过程,请参阅deletionfilter辅助函数在这个例子

请注意:如果你使用脚本文件对于本例,生活deletionfilter功能已经包含在文件的末尾。否则,您需要创建这个函数的m文件或将其添加为MATLAB路径上的一个文件。这同样适用于后来在本例中使用的其他辅助功能。

看到的效果deletionfilter在示例数据。

[ineqs,方程式,ncall] = deletionfilter (A, b, Aeq,说真的,磅,乌兰巴托);

这个问题没有等式约束。发现不等式约束的指数和的值b (iis)

iis =找到(ineqs)
iis = 114
b (iis)
ans = -10

只有一个不等式约束导致的问题是不可行的,连同绑定约束。约束条件是

:一个(iis) * x < = b (iis)

为什么这个约束不可行的界限?发现这一行的绝对值的总和一个

disp(总和(abs ((iis,:))))
8.4864

由于界限,x向量1和1之间的值,所以:一个(iis) * x不能少于b (iis)= -10。

有多少linprog调用了deletionfilter执行?

disp (ncall)
150年

150线性约束问题,所以调用的函数linprog150次。

弹性过滤器

作为替代删除过滤器,检查每一个约束,尝试弹性过滤器。这个过滤器工作如下。

首先,允许每个约束被积极的违反e(我),等式约束加法和减法积极的弹性值。

一个 n e x b n e + e 一个 e x = b e + e 1 - - - - - - e 2

接下来,解决问题相关的线性规划(LP)

最小值 x , e e

受约束和上市 e 0

  • 如果相关的资讯解决方案,删除所有的约束有一个严格的正相关 e ,并记录这些约束指数(潜在的IIS成员)的列表。返回到上一步解决新,减少相关的资讯。

  • 如果相关的资讯没有解决方案(是不可行的)或没有严格的正相关 e ,退出过滤器。

弹性过滤器可以在许多迭代少于退出删除过滤器,因为它能带来许多指数立刻到IIS,并且可以停止不经过指标的完整列表。然而,这个问题比原始变量问题,及其结果列表的索引可以比IIS。找到一个IIS运行一个弹性过滤器后,运行删除过滤结果。

MATLAB®代码实现这个过滤器,请参阅elasticfilter辅助函数在这个例子

看到的效果elasticfilter在示例数据。

[ineqselastic, eqselastic ncall] =Aeq elasticfilter (A, b,说真的,磅,乌兰巴托);

这个问题没有等式约束。发现不等式约束的指数。

iiselastic =找到(ineqselastic)
iiselastic =5×12 60 82 97 114

弹性IIS列出五个约束,而删除过滤器发现只有一个。返回的集合上运行删除过滤器找到一个真正的IIS。

A_1 = (ineqselastic > 0,:);b_1 = b (ineqselastic > 0);[dineq_iis, deq_iis ncall2] = deletionfilter (A_1、b_1、Aeq,说真的,磅,乌兰巴托);iiselasticdeletion =找到(dineq_iis)
iiselasticdeletion = 5

第五个约束的弹性过滤结果,114年不平等,IIS。这个结果同意删除过滤器的答案。方法之间的差异,结合弹性和删除过滤方法使用少很多linprog调用。显示的总数linprog电话使用的弹性过滤器之后删除过滤器。

disp (ncall + ncall2)
7

删除一个循环中的IIS

一般来说,获得一个IIS的原因不让你找到所有你的优化问题失败。纠正一个不可行的问题,可以不断发现一个IIS和删除它从问题到问题就变得可行。

下面的代码显示了如何删除一个IIS的问题,直到问题变得可行。代码使用一个索引技术跟踪约束的位置在最初的问题,算法之前删除任何约束。

原变量的代码跟踪问题通过使用布尔向量activeA代表当前约束(行)一个矩阵和布尔向量activeAeq表示当前的约束Aeq矩阵。当添加或删除约束,索引到的代码一个Aeq这行数据不会改变,尽管约束的数量变化。

运行此代码返回idx2,一个向量中的非零元素的索引activeA:

idx2 =找到(activeA)

假设var同样是一个布尔向量的长度吗idx2。然后

idx2(找到(var))

表达var作为指标变量到原始的问题。通过这种方式,索引可以约束的一个子集的一个子集,工作只有较小的子集,还明确地把原问题变量。

选择= optimoptions (“linprog”,“显示”,“没有”);activeA = true(大小(b));activeAeq = true(大小(说真的));[~,~,exitflag] = linprog (f, A、b Aeq,说真的,磅,乌兰巴托,选择);ncl = 1;(ineqselastic exitflag < 0, eqselastic ncall] =elasticfilter ((activeA:), b (activeA) Aeq (activeAeq:),说真的(activeAeq)磅,乌兰巴托);ncl = ncl + ncall;idxaa =找到(activeA);idxae =找到(activeAeq);tmpa = idxaa(找到(ineqselastic));tmpae = idxae(找到(eqselastic));AA = (tmpa:);bb = b (tmpa);AE = Aeq (tmpae:);是= beq (tmpae); [ineqs,eqs,ncall] =deletionfilter (AA、bb AE,磅,乌兰巴托);ncl = ncl + ncall;activeA (tmpa (ineqs)) = false;activeAeq (tmpae(方程式))= false;disp ([消除不平等的,int2str ((tmpa (ineqs))”),和等式,int2str ((tmpae(方程式)))))~,~,exitflag =linprog (f (activeA:)、b (activeA) Aeq (activeAeq:),说真的(activeAeq)磅,乌兰巴托,选择);ncl = ncl + 1;结束
消除不平等114年和97年平等移除不平等,平等删除不平等60 64 82和等式不等式和等式
流(“linprog电话数量:% d \ n 'ncl)
linprog电话数量:28

注意循环消除不平等同时64年和82年,这表明这两个约束形成一个IIS。

找到maxf

另一种方法获得一套可行的约束是找到maxf直接。作为这个[1]解释说,找到一个maxf是一个np完全问题,意义问题并不一定有效的算法寻找maxf。然而,这个提出了一些算法,能有效地工作。

找到一个使用这个算法7.3覆盖集的约束,当删除,提供一套可行的。该算法的实现generatecover辅助函数在这个例子

(coversetineq coverseteq, nlp) = generatecover (A, b, Aeq,说真的,磅,乌兰巴托)
coversetineq =5×1114 97 82 2
coverseteq = []
nlp = 40

移除这些约束和解决LP。

usemeineq = true(大小(b));usemeineq (coversetineq) = false;%将不等式约束usemeeq = true(大小(说真的));usemeeq (coverseteq) = false;%将等式约束[x, fvals exitflags] =linprog (f (usemeineq:)、b (usemeineq) Aeq (usemeeq),说真的(usemeeq)磅,乌兰巴托);
找到最优解。

注意,封面是一模一样iiselastic设置从弹性过滤器。一般来说,弹性过滤器这个发现太大一个覆盖集。与弹性过滤结果的算法7.3开始,然后只保留的约束条件是必要的。

这个算法7.3花40调用linprogmaxf完成计算。这个数字有点超过28个电话使用过程中删除IIS早些时候在一个循环。

同时,注意循环中的不平等移除并不完全一样的不平等被算法7.3。循环消除不平等114、97、82年,60岁,64年,算法7.3删除不平等114、97、82年,60岁,2。检查82和64不平等形成一个IIS(如示删除一个循环中的IIS),82和2也形成一个IIS的不平等现象。

usemeineq = false(大小(b));usemeineq ((82、64)) = true;ineqs = deletionfilter (A (usemeineq:)、b (usemeineq) Aeq,说真的,磅,乌兰巴托);disp (ineqs)
1
usemeineq = false(大小(b));usemeineq([2] 82年)= true;ineqs = deletionfilter (A (usemeineq:)、b (usemeineq) Aeq,说真的,磅,乌兰巴托);disp (ineqs)
1

引用

这个[1],j·W。优化的可行性和不可行性:算法和计算方法。施普林格,2008年。

这个[2],j·W。“在优化可行性和不可行性。”Tutorial for CP-AI-OR-07, Brussels, Belgium. Available athttps://www.sce.carleton.ca/faculty/chinneck/docs/CPAIOR07InfeasibilityTutorial.pdf

辅助函数

这段代码创建了deletionfilterhelper函数。

函数[ineq_iis, eq_iis ncalls] = deletionfilter (Aineq、bineq Aeq,说真的,磅,乌兰巴托)ncalls = 0;[mi, n] =大小(Aineq);%多的变量和线性不等式约束f = 0 (1, n);我=大小(Aeq, 1);%的数量线性等式约束选择= optimoptions (“linprog”,“算法”,“对偶单纯形”,“显示”,“没有”);ineq_iis = true (mi, 1);%开始所有的不平等问题eq_iis = true(我,1);%开头都平等的问题i = 1: mi ineq_iis (i) = 0;%消除不平等我[~,~,exitflag] = linprog (f, Aineq (ineq_iis:), bineq (ineq_iis),Aeq、说真的、磅、乌兰巴托、选择);ncalls = ncalls + 1;如果exitflag = = 1%如果现在可行ineq_iis (i) = 1;%我回到这个问题结束结束我= 1:eq_iis (i) = 0;%去除平等我[~,~,exitflag] = linprog (f Aineq bineq,Aeq (eq_iis:),说真的(eq_iis)磅,乌兰巴托,选择);ncalls = ncalls + 1;如果exitflag = = 1%如果现在可行eq_iis (i) = 1;%我回到这个问题结束结束结束

这段代码创建了elasticfilterhelper函数。

函数[ineq_iis, eq_iis ncalls fval0] = elasticfilter (Aineq、bineq Aeq,说真的,磅,乌兰巴托)ncalls = 0;[mi, n] =大小(Aineq);%多的变量和线性不等式约束我=大小(Aeq, 1);Aineq_r = [Aineq -1.0 *眼(mi) 0 (mi, 2 *我)];Aeq_r = [Aeq 0(我,mi)眼(我)-1.0 *眼(我)];%为每个等式约束两个休闲裤lb_r =[磅(:);0 (mi + 2 *我,1)];ub_r =[乌兰巴托(:);正(mi + 2 *我,1)];ineq_slack_offset = n;eq_pos_slack_offset = n + mi;eq_neg_slack_offset = n + mi +我;f = [0 (1, n) 1(1 + 2 *小姐我)];选择= optimoptions (“linprog”,“算法”,“对偶单纯形”,“显示”,“没有”);托尔= 1平台以及;ineq_iis = false (mi, 1);eq_iis = false(我,1);[x, fval exitflag] = linprog (f Aineq_r bineq Aeq_r,说真的,lb_r, ub_r,选择);fval0 = fval;ncalls = ncalls + 1;exitflag = = 1 & & fval >托尔%的可行性和一些休闲裤都是非零的c = 0;i = 1: mi j = ineq_slack_offset + i;如果x (j) > tol ub_r (j) = 0.0;ineq_iis (i) = true;c = c + 1;结束结束i = 1: j = eq_pos_slack_offset +我;如果x (j) > tol ub_r (j) = 0.0;eq_iis (i) = true;c = c + 1;结束结束i = 1: j = eq_neg_slack_offset +我;如果x (j) > tol ub_r (j) = 0.0;eq_iis (i) = true;c = c + 1;结束结束[x, fval exitflag] = linprog (f Aineq_r bineq Aeq_r,说真的,lb_r, ub_r,选择);如果fval > 0 fval0 = fval;结束ncalls = ncalls + 1;结束结束

这段代码创建了generatecoverhelper函数。跟踪代码使用相同的索引技术的约束删除一个循环中的IIS代码。

函数(coversetineq coverseteq, nlp) = generatecover (Aineq、bineq Aeq,说真的,磅,乌兰巴托)%返回封面组线性不等式,封面的一组线性的%等式,并呼吁linprog的总数。%这个改编自[1]算法7.3。步骤号来自这本书。coversetineq = [];coverseteq = [];activeA = true(大小(bineq));activeAeq = true(大小(说真的));% 7.3算法的步骤1[ineq_iis, eq_iis ncalls] = elasticfilter (Aineq、bineq Aeq,说真的,磅,乌兰巴托);nlp = ncalls;ninf =总和(ineq_iis(:)) +总和(eq_iis (:));如果ninf = = 1 coversetineq = ineq_iis;coverseteq = eq_iis;返回结束holdsetineq =找到(ineq_iis);holdseteq =找到(eq_iis);candidateineq = holdsetineq;candidateeq = holdseteq;%的第2步算法7.3sum (candidateineq(:)) +总和(candidateeq (:)) > 0 minsinf =正;ineqflag = 0;i = 1:长度(candidateineq (:)) activeA (candidateineq(我))= false;idx2 =找到(activeA);idx2eq =找到(activeAeq);[ineq_iis, eq_iis ncalls fval] = elasticfilter (Aineq (activeA:), bineq (activeA) Aeq (activeAeq:),说真的(activeAeq)磅,乌兰巴托);nlp = nlp + ncalls;ineq_iis = idx2(找到(ineq_iis));eq_iis = idx2eq(找到(eq_iis));如果fval = = 0 coversetineq = [coversetineq; candidateineq (i)];返回结束如果fval < minsinf ineqflag = 1;赢家= candidateineq(我);minsinf = fval;holdsetineq = ineq_iis;如果元素个数(ineq_iis(:)) +元素个数(eq_iis (:)) = = 1 nextwinner = ineq_iis;nextwinner2 = eq_iis;nextwinner = [nextwinnner, nextwinner2];其他的nextwinner = [];结束结束activeA (candidateineq (i)) = true;结束i = 1:长度(candidateeq (:)) activeAeq (candidateeq(我))= false;idx2 =找到(activeA);idx2eq =找到(activeAeq);[ineq_iis, eq_iis ncalls fval] = elasticfilter (Aineq (activeA:), bineq (activeA) Aeq (activeAeq:),说真的(activeAeq)磅,乌兰巴托);nlp = nlp + ncalls;ineq_iis = idx2(找到(ineq_iis));eq_iis = idx2eq(找到(eq_iis));如果fval = = 0 coverseteq = [coverseteq; candidateeq (i)];返回结束如果fval < minsinf ineqflag = 1;赢家= candidateeq(我);minsinf = fval;holdseteq = eq_iis;如果元素个数(ineq_iis(:)) +元素个数(eq_iis (:)) = = 1 nextwinner = ineq_iis;nextwinner2 = eq_iis;nextwinner = [nextwinnner, nextwinner2];其他的nextwinner = [];结束结束activeAeq (candidateeq (i)) = true;结束% 7.3算法的第三步如果ineqflag = = 1 coversetineq = (coversetineq;赢家);activeA(冠军)= false;如果nextwinner coversetineq = [coversetineq; nextwinner];返回结束结束如果ineqflag = = 1 coverseteq = (coverseteq;赢家);activeAeq(冠军)= false;如果nextwinner coverseteq = [coverseteq; nextwinner];返回结束结束candidateineq = holdsetineq;candidateeq = holdseteq;结束结束

另请参阅

相关的话题