Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 指定边界数矩阵的生成算法_Python_Algorithm_Numpy_Optimization - Fatal编程技术网

Python 指定边界数矩阵的生成算法

Python 指定边界数矩阵的生成算法,python,algorithm,numpy,optimization,Python,Algorithm,Numpy,Optimization,我试图生成一个7行4列的数字矩阵。每一行的总和必须为100,每一列必须在最小和最大范围(如下规定)之间有一个均匀的排列(如果允许) 目标: C1 C2 C3 C4 sum range 1 low 100 ^ 2 .. | 3 .. | 4 ..

我试图生成一个7行4列的数字矩阵。每一行的总和必须为100,每一列必须在最小和最大范围(如下规定)之间有一个均匀的排列(如果允许)

目标:

       C1      C2    C3    C4   sum   range 
 1     low                      100    ^
 2     ..                              |  
 3     ..                              |
 4     ..                              | 
 5     ..                              |
 6     ..                              |
 7     high                            _

c1_high = 98
c1_low = 75
c2_high = 15
c2_low = 6
c3_high = 8
c3_low = 2
c4_low = 0.05
c4_high =0.5
除此之外,我需要每行的排列尽可能线性,尽管用二阶多项式拟合数据的直线就足够了(r^2值>0.98)

我目前正尝试使用以下sudocode执行此操作:

  • 在c1、c2、c3和c4的范围内生成随机数
  • 重复7次
  • 检查生成的每个c1值与1-7之间的数字范围之间的相关性。例如:
  • 对c2、c3和c4重复步骤3

  • 在步骤3和4成功时中断循环

  • 事实证明,就所需的迭代次数而言,这太麻烦了,因此,解决方案永远无法实现

    是否有更有效的方法实现此解决方案

    到目前为止:

    import pandas as pd
    import numpy as np
    from sklearn.utils import shuffle
    
    c1_high = 98
    c1_low = 75
    c2_high = 15
    c2_low = 6
    c3_high = 8
    c3_low = 2
    c4_low = 0.05
    c4_high =0.5
    
    def matrix_gen(): #generates matrix within min and max values
        container =[]
        d={}
        offset = np.linspace(0.05,1,9)
        c1= np.linspace(c1_low, c1_high, 7)
        c2= np.linspace(c2_low, c2_high, 7)
        c3= np.linspace(c3_low, c3_high, 7)
        c4= np.linspace(c4_low, c4_high, 7)
    
        for i in np.arange(7):
            d["row{0}".format(i)]=[item[i] for item in [c1,c2,c3,c4]]
    
        df =pd.DataFrame(d)
        df.loc[4,:] = df.iloc[0,:][::-1].values
        df1 = df.drop(0)
        df1.loc[5,:] = df1.sum(axis=0)
        new_name = df1.index[-1]
        df1 = df1.rename(index={new_name: 'sum'})
        return df1
    
    m = matrix_gen()
    print(m)
    
    输出:

    下一个功能:

    def shuf():  # attempts at shuffling the values around such that the 'sum' row is as close to 100 as possible. 
        df = matrix_gen()
        df1 = df[1:4]
        count =0
        while True:
            df1 = shuffle(df1)
            df1.loc[5,:] = df1.sum(axis=0)
            for i in df1.loc[5].values:
                if 98<= i <=100:
                    print('solution')
                    return df1
                else:
                    count+=1
                    print(count)
                    continue
    
    opt = shuf()
    print(opt)
    
    def shuf():#尝试对值进行混洗,使“sum”行尽可能接近100。
    df=矩阵_gen()
    df1=df[1:4]
    计数=0
    尽管如此:
    df1=洗牌(df1)
    df1.loc[5,:]=df1.sum(轴=0)
    对于df1.loc[5]中的i,值:
    
    如果98我认为一个有趣的方法是使用优化模型

    有序值 让x(i,j)成为你想要填充的矩阵。然后我们有:

    sum(j, x(i,j)) = 100   ∀i
    L(j) ≤ x(i,j) ≤ U(j)   ∀i,j
    x(i,j) = x(i-1,j) + step(j) + deviation(i,j)
       special cases:
         x(1,j) = L(j) + deviation(1,j)
         and x(m,j) = U(j) + deviation(m,j)
    step(j) ≥ 0
    minimize sum((i,j), deviation(i,j)^2 )
    
    这是一个二次规划问题。可以用绝对偏差代替平方偏差。在这种情况下,您有一个LP

    可以对模型进行优化,使平方相对误差最小化

    这与所谓的矩阵平衡(通常用于经济建模的一种统计技术)有点相关

    无序值 在上面的例子中,我假设必须对值进行排序。现在我明白情况并非如此。我调整了模型以如下方式处理此问题。首先是对结果的概述

    输入数据为:

    ----     17 PARAMETER LO  
    
    c1 80.000,    c2  5.000,    c3  0.500,    c4  0.050
    
    
    ----     17 PARAMETER UP  
    
    c1 94.000,    c2 14.000,    c3  5.000,    c4  0.500
    
    警告:请注意,海报已更改此数据。我的答案是使用更改前的原始LO和UP值

    该模型分为三个步骤:

    (1) 在不遵守行和约束的情况下填充完全组织的矩阵。这可以在模型之外完成。我只生成了:

    ----     53 PARAMETER init  initial matrix
    
                c1          c2          c3          c4      rowsum
    
    r1      80.000       5.000       0.500       0.050      85.550
    r2      82.333       6.500       1.250       0.125      90.208
    r3      84.667       8.000       2.000       0.200      94.867
    r4      87.000       9.500       2.750       0.275      99.525
    r5      89.333      11.000       3.500       0.350     104.183
    r6      91.667      12.500       4.250       0.425     108.842
    r7      94.000      14.000       5.000       0.500     113.500
    
    即从
    lo(j)
    up(j)
    的步骤相等

    (2) 第二步是排列列中的值,以获得与行和非常匹配的解决方案。这使得:

    ----     53 VARIABLE y.L  after permutation
    
                c1          c2          c3          c4      rowsum
    
    r1      94.000       5.000       0.500       0.125      99.625
    r2      82.333      12.500       4.250       0.500      99.583
    r3      89.333       8.000       2.000       0.200      99.533
    r4      87.000       9.500       2.750       0.275      99.525
    r5      84.667      11.000       3.500       0.350      99.517
    r6      91.667       6.500       1.250       0.050      99.467
    r7      80.000      14.000       5.000       0.425      99.425
    
    ----     53 VARIABLE x.L  final values
    
                c1          c2          c3          c4      rowsum
    
    r1      94.374       5.001       0.500       0.125     100.000
    r2      82.747      12.503       4.250       0.500     100.000
    r3      89.796       8.004       2.000       0.200     100.000
    r4      87.469       9.506       2.750       0.275     100.000
    r5      85.142      11.007       3.501       0.350     100.000
    r6      92.189       6.510       1.251       0.050     100.000
    r7      80.561      14.012       5.002       0.425     100.000
    
    
    ----     53 VARIABLE d.L  deviations
    
                c1          c2          c3          c4
    
    r1       0.374       0.001 1.459087E-5 1.459087E-7
    r2       0.414       0.003 9.542419E-5 9.542419E-7
    r3       0.462       0.004 2.579521E-4 2.579521E-6
    r4       0.469       0.006 4.685327E-4 4.685327E-6
    r5       0.475       0.007 7.297223E-4 7.297223E-6
    r6       0.522       0.010       0.001 1.123123E-5
    r7       0.561       0.012       0.002 1.587126E-5
    
    这已经非常接近,并保持“完美”的传播

    (3) 通过添加偏差稍微更改值,使行和正好为100。最小化相对偏差的平方和。这使得:

    ----     53 VARIABLE y.L  after permutation
    
                c1          c2          c3          c4      rowsum
    
    r1      94.000       5.000       0.500       0.125      99.625
    r2      82.333      12.500       4.250       0.500      99.583
    r3      89.333       8.000       2.000       0.200      99.533
    r4      87.000       9.500       2.750       0.275      99.525
    r5      84.667      11.000       3.500       0.350      99.517
    r6      91.667       6.500       1.250       0.050      99.467
    r7      80.000      14.000       5.000       0.425      99.425
    
    ----     53 VARIABLE x.L  final values
    
                c1          c2          c3          c4      rowsum
    
    r1      94.374       5.001       0.500       0.125     100.000
    r2      82.747      12.503       4.250       0.500     100.000
    r3      89.796       8.004       2.000       0.200     100.000
    r4      87.469       9.506       2.750       0.275     100.000
    r5      85.142      11.007       3.501       0.350     100.000
    r6      92.189       6.510       1.251       0.050     100.000
    r7      80.561      14.012       5.002       0.425     100.000
    
    
    ----     53 VARIABLE d.L  deviations
    
                c1          c2          c3          c4
    
    r1       0.374       0.001 1.459087E-5 1.459087E-7
    r2       0.414       0.003 9.542419E-5 9.542419E-7
    r3       0.462       0.004 2.579521E-4 2.579521E-6
    r4       0.469       0.006 4.685327E-4 4.685327E-6
    r5       0.475       0.007 7.297223E-4 7.297223E-6
    r6       0.522       0.010       0.001 1.123123E-5
    r7       0.561       0.012       0.002 1.587126E-5
    
    步骤(2)和(3)必须在优化模型内:它们必须同时执行,以获得经验证的最佳解决方案

    数学模型可以如下所示:

    该模型使用Cplex或Gurobi等解算器,在几秒钟内解出经验证的全局最优解

    我认为这是一个非常可爱的模型(好吧,我知道这真是个书呆子)。置换用置换矩阵P(二进制值)建模。这使得该模型成为MIQP(混合整数二次规划)模型。它可以很容易地线性化:在目标中使用绝对值而不是正方形。经过适当的重新计算,我们得到了一个线性MIP模型。有很多软件可以处理这个问题。这包括可从Python调用的库和包


    注:我可能不应该在目标中除以
    init(I,j)
    ,而是除以
    init
    矩阵中的列平均值。除以y(i,j)
    将是最好的,但这将导致另一个非线性

    您的数字足够小,可以使用智能暴力方法

    我使用两种方法来量化和最小化与“干净”等距值的偏差(
    linspace(低、高、7)
    )<代码>“abserr”表示平方差,而
    “relerr”
    表示平方误差除以平方净值。最后我还检查了corrcoefs,但我从未见过低于99.8%的任何东西

    下面的代码首先查找错误最小的干净值。这只需要几秒钟,因为我们使用以下技巧:

    • 将4列拆分为两对
    • 每对有7个!相对排列,一个可管理的数字,即使平方(每对一个因数)
    • 计算这些(7!)^2次洗牌并对其求和
    • 为了不必迭代对之间的所有相对洗牌,我们观察到,如果两组对和按相反顺序排列,则总误差最小化。对于
      “abserr”
      “relerr”
    最后,对这些值进行校正,使行总和为100。在这里,我们再次使用这样一个事实:当平均分布时,求和误差最小化

    下面的代码包含两个变体,一个是传统的
    solve
    ,它在最小化
    relerr
    时包含一个小的不准确度,另一个是经过修正的版本
    改进的\u solve
    。他们经常会找到不同的解决方案,但在100多个随机问题中,只有一个会导致
    改进的\u solve
    产生非常小的错误

    对几个例子的回答:

    OP的例子:

                    ((75, 98), (6, 15), (2, 8), (0.05, 0.5))
    
    solve relerr                            improved_solve relerr                  
    table:                                  table:                                 
    76.14213 15.22843  8.12183  0.50761     76.14213 15.22843  8.12183  0.50761    
    79.02431 13.53270  7.01696  0.42603     79.02431 13.53270  7.01696  0.42603    
    81.83468 11.87923  5.93961  0.34648     81.83468 11.87923  5.93961  0.34648    
    84.57590 10.26644  4.88878  0.26888     84.57590 10.26644  4.88878  0.26888    
    87.25048  8.69285  3.86349  0.19317     87.25048  8.69285  3.86349  0.19317    
    89.86083  7.15706  2.86282  0.11928     89.86083  7.15706  2.86282  0.11928    
    92.40924  5.65771  1.88590  0.04715     92.40924  5.65771  1.88590  0.04715    
    avgerr:                                 avgerr:                                
     0.03239                                 0.03239                               
    corrcoefs:                              corrcoefs:                             
     0.99977  0.99977  0.99977  0.99977      0.99977  0.99977  0.99977  0.99977 
    
    将某些列升序或降序排序不是最佳的示例:

                    ((11, 41), (4, 34), (37, 49), (0.01, 23.99))
    
    请注意,解算器会找到不同的解,但错误是相同的

    solve relerr                            improved_solve relerr                  
    table:                                  table:                                 
    10.89217 18.81374 46.53926 23.75483     11.00037 24.00080 49.00163 15.99720    
    26.00087  9.00030 49.00163 15.99720     16.00107 19.00127 45.00300 19.99467    
    31.00207  4.00027 45.00300 19.99467     25.74512 13.86276 36.63729 23.75483    
    16.00000 29.00000 43.00000 12.00000     35.99880  8.99970 46.99843  8.00307    
    20.99860 33.99773 40.99727  4.00640     41.00000  4.00000 43.00000 12.00000    
    40.99863 13.99953 36.99877  8.00307     20.99860 33.99773 40.99727  4.00640    
    36.35996 24.23998 39.38996  0.01010     31.30997 29.28997 39.38996  0.01010    
    avgerr:                                 avgerr:                                
     0.00529                                 0.00529                               
    corrcoefs:                              corrcoefs:                             
     0.99993  0.99994  0.99876  0.99997      0.99989  0.99994  0.99877  0.99997 
    
    这就是问题所在,
    改进的\u solve
    实际上胜过了遗留的
    solve

                    ((36.787862883725872, 43.967159949544317),
                     (40.522239654303483, 47.625869880574164),
                     (19.760537036548321, 49.183056694462799),
                     (45.701873101046154, 48.051424087501672))
    
    solve relerr                            improved_solve relerr                  
    table:                                  table:                                 
    21.36407 23.53276 28.56241 26.54076     20.25226 26.21874 27.07599 26.45301    
    22.33545 24.52391 26.03695 27.10370     21.53733 26.33278 25.10656 27.02333    
    23.33149 25.54022 23.44736 27.68093     22.90176 26.45386 23.01550 27.62888    
    24.35314 26.58266 20.79119 28.27301     24.35314 26.58266 20.79119 28.27301    
    25.40141 27.65226 18.06583 28.88050     25.90005 26.71994 18.42047 28.95953    
    26.47734 28.75009 15.26854 29.50403     27.55225 26.86656 15.88840 29.69279    
    27.58205 29.87728 12.39644 30.14424     29.32086 27.02351 13.17793 30.47771    
    avgerr:                                 avgerr:                                
     0.39677                                 0.39630                               
    corrcoefs:                              corrcoefs:                             
     0.99975  0.99975  0.99975  0.99975      0.99847  0.99847  0.99847  0.99847 
    
    代码:


    如果从另一端开始:生成一个se