Python:解决寻找满足特定条件的组合的问题

Posted

技术标签:

【中文标题】Python:解决寻找满足特定条件的组合的问题【英文标题】:Python : Solving a problem of finding a combination which satisfies a particular condition 【发布时间】:2019-06-29 07:15:25 【问题描述】:

我遇到了一个我无法使用正常蛮力方法解决的问题。问题-我试图找到一个 50 年的组合,一次取 30 年而不重复,这样它们的平均值和变异系数就在特定的范围内。 我正在使用itertools combinations。 但问题是,总组合中没有 -47129212243960 计算时间过长。 有什么方法可以提高效率吗? 数据集的格式如下-

Yrs       Prs_90      Prs_80      Prs_70

2012  499.934588  521.512345  425.189729
2013  579.063531  477.782099  256.382494
2014  458.415624  456.480642  363.309507

我正在计算Prs_90 , Prs_80, Prs_70 的均值和变异系数,然后根据取决于均值和变异系数的阈值找到组合。 编辑-变异系数(CV)=标准偏差(x)/平均值(x) 选择所需组合的条件是-

if (mean >= 501 and <= 570) and ((0.13<=CV<=0.17) or(0.23<=CV<=0.27) or(0.23 <=CV <=27)

if (mean >= 451 and <= 460) and ((0.13<=CV<=0.17) or(0.23<=CV<=0.27) 
or(0.33 <=CV <=37):

if (mean >= 391 and <= 400) and ((0.13<=CV<=0.17) or(0.23<=CV<=0.27) 
or(0.33 <=CV <=37)):

我需要上面每个条件对应的组合。

编辑- 我首先以以下格式重新排序上面提供的数据框-

             Yrs      Prs_80      Prs_70
Prs_90                                  
579.063531  2013  477.782099  256.382494
477.758138  2044  475.458614  259.228592
492.957830  2036  408.590138  281.921215
541.632294  2042  430.990568  290.163454
565.369062  2024  420.107058  296.545395
409.979527  2027  379.740246  301.086631
347.702470  2052  610.775045  307.756455
460.657276  2016  301.774467  309.311562

然后我使用以下方法-

r =30
check1 = 1
check10 = 1
for p in combinations(test4.index,r):
  den = np.mean(p)
  num = np.std(p)
  cv = num/den
  if (den >= 561 and den <= 570 ) :
     if(cv>=0.13 or cv <= 0.17 and check1):
     check1=0
     print("Combination 1 done")

  elif(den>=391 and den <= 400):
     if(cv>=0.13 or cv < 0.17 and check10):
     check10 = 0
     print("Combination 10 done")
if(check1+check10==0)
break

即使这样,我在这里也只考虑了 2 个条件。它正在运行数百万次迭代,因此完整处理组合将需要更多时间。 我使用 check1 和 check10 作为信号,因为当我收到以下组合时,我会中断循环。

其他信息-

           Prs_90      Prs_80      Prs_70
count   50.000000   50.000000   50.000000
mean   510.732700  445.366865  386.037076
std    113.773333   84.078209   80.987841
min    347.702470  233.335085  256.382494
25%    427.241363  390.745725  320.812298
50%    469.263029  439.407141  383.430153
75%    573.406731  512.019602  433.199140
max    854.819691  610.775045  644.588971

数据的CV为25%。

【问题讨论】:

你能说得更具体点吗? “变异系数”是什么意思?你能给出一个公式吗?你如何使用你的阈值(也请给出一个公式)? 对不起,我添加了细节。 您可以将您的 CV 不等式转换为 StdDev 不等式,然后测试它们的 StdDev 组合.....在所有 CV 和 Mean 都通过等式链接之后 问题不是我不能改造,问题是时间太长不知道怎么优化 你能再具体一点吗?例如:您的原始数据集看起来像熊猫数据框,对吗?你能提供一个minimal reproducible example 告诉我们你的问题应该如何解决吗?即使它不是大数据,我们也会考虑在内。 【参考方案1】:

我说过这样的事情可以用 MINLP(混合整数非线性规划)模型来解决。让我试试看。

我生成了一些随机数据:

----     30 PARAMETER p  random data

year1  18.003,    year2  84.483,    year3  55.487,    year4  30.813,    year5  29.929,    year6  23.181
year7  35.633,    year8  85.771,    year9   7.644,    year10 50.521,    year11 99.814,    year12 58.295
year13 99.122,    year14 76.463,    year15 13.939,    year16 64.332,    year17 16.792,    year18 25.758
year19 67.224,    year20 44.100,    year21 36.610,    year22 35.793,    year23 14.018,    year24 15.860
year25 59.322,    year26 83.258,    year27 23.851,    year28 66.908,    year29 77.810,    year30 31.062
year31 11.939,    year32 50.736,    year33 16.857,    year34 87.374,    year35 27.246,    year36 29.296
year37 59.802,    year38 72.549,    year39 63.197,    year40 46.916,    year41 41.917,    year42 12.652
year43 32.107,    year44  5.609,    year45 34.516,    year46 19.028,    year47 64.927,    year48 56.514
year49 77.226,    year50 30.483


----     30 PARAMETER meanbounds  

               lo          up

mean1      10.000      20.000
mean2      30.000      40.000
mean3      50.000      60.000


----     30 PARAMETER cvbounds  

             lo          up

cv1       0.500       0.700
cv2       0.900       0.950


----     30 PARAMETER K                    =       30.000  number to select

MINLP 模型:

模型基本上做了三件事:

    选择 30 个点(通过 x(i) 变量) 为平均值选择一个区间(通过xm(k1)) 为 CV 选择一个区间(通过xcv(k2)

一些结果:

----     74 VARIABLE x.L  select points

year1  1,    year2  1,    year3  1,    year4  1,    year5  1,    year6  1,    year7  1,    year9  1,    year10 1
year12 1,    year16 1,    year17 1,    year18 1,    year20 1,    year21 1,    year22 1,    year23 1,    year24 1
year27 1,    year30 1,    year32 1,    year33 1,    year35 1,    year37 1,    year40 1,    year42 1,    year43 1
year44 1,    year46 1,    year48 1


----     74 VARIABLE mu.L                  =       34.321  mean
            VARIABLE sigma.L               =       18.843  stdev
            VARIABLE cv.L                  =        0.549  coeff of variation

----     74 VARIABLE xm.L  select mean interval

mean2 1


----     74 VARIABLE xcv.L  select CV interval

cv1 1

我用Baron 解决了这个问题。至少对于这个数据集,这种方法似乎有效。由于没有目标,这基本上是一个可行性问题。约束编程求解器也可以工作(尽管大多数对浮点变量的支持有限)。

【讨论】:

我想有没有其他方法,我需要为此购买软件。 有一些开源的 MINLP 求解器,例如 Couenne(它会找到一个不同的解决方案,并且在我的数据上需要更长的时间)。或者,可以通过 NEOS 在线访问 Baron。

以上是关于Python:解决寻找满足特定条件的组合的问题的主要内容,如果未能解决你的问题,请参考以下文章

在python中寻找具有特定条件的数字

编程之美2.12 高速寻找满足条件的两个数

如何在 Kivy 应用程序启动时满足特定条件时自动弹出警报

二分法02:寻找第一个和最后一个的满足条件的位置

编程之美快速寻找满足条件的两个数

Matlab中find()寻找函数的常见用法