Python优化 - 无法满足多个约束

时间:2017-11-30 05:11:55

标签: python math optimization mathematical-optimization

我试图将重量最小化到尽可能接近平均值并且满足w> 0和Aw = b的约束。然而,在帮助下,我能够满足第二个约束(Aw = b)几乎100%,但我仍然返回负值,同时没有接近平均值。正如您所看到的,下面的结果会返回两个较大的负数(-39.99771255,-2.9709434)和一个超出界限的大位置编号(43.82670431),这会使练习的目的失效,从而最大限度地减轻重量。我甚至试图将我的数据集划分为随机不同的组,但没有优化的解决方案。

如果有任何数学或更好的python建议以及任何有助于实现最优化解决方案的方法,请告诉我。我期待这个数字接近0.2。任何数字建议和建议都是非常受欢迎的。

  

问题:找到接近平均值和最小值的最小重量   同时尽可能接近目标,重量必须更大   比0

我现在的数学是

           **min⁡(w-mean(w))**

           **s.t.** Aw-b=0, w>=0


           **bound** 0.2'<'w<0.5

数据:

    variable1   variable2   variable3   weight
    1.49E+03    9.65E+07    2.27E+08    w1
    1.52E+03    1.02E+08    2.20E+08    w2
    1.54E+03    1.11E+08    2.23E+08    w3
    1.49E+03    9.73E+07    2.18E+08    w4
    1.60E+03    1.05E+08    2.38E+08    w5
    1.57E+03    1.01E+08    2.25E+08    w6
    1.59E+03    1.06E+08    2.30E+08    w7
    1.49E+03    9.15E+07    2.20E+08    w8
    1.54E+03    1.02E+08    2.20E+08    w9
    1.54E+03    1.01E+08    2.28E+08    w10
    1.57E+03    1.08E+08    2.25E+08    w11
    1.54E+03    1.00E+08    2.25E+08    w12
    1.57E+03    9.97E+07    2.26E+08    w13
    1.49E+03    9.64E+07    2.13E+08    w14
    1.53E+03    1.05E+08    2.36E+08    w15
    1.53E+03    1.09E+08    2.23E+08    w16
    1.55E+03    1.00E+08    2.45E+08    w17
    1.52E+03    1.07E+08    2.17E+08    w18
    1.50E+03    9.62E+07    2.07E+08    w19
    1.57E+03    9.91E+07    2.32E+08    w20


  Target            
    8531        429386951   1079115532

当前结果:

('x: ', array([  0.28601612,   0.28601614,  43.82670431,   0.28601614,   0.28601613,   0.28601614,   0.28601614,  -2.9709434 ,
     0.28601614,   0.28601613,   0.28601615,   0.28601613,   0.28601613,   0.28601614,   0.28601614,   0.28601618,
   -39.99771255,   0.28601618,   0.28601614,   0.28601612]))

Python代码:

    # -*- coding: utf-8 -*-
"""
Created on Wed Nov 9 13:15:49 2017

@author: zkmkq7a
"""

import numpy as np
import scipy.optimize as spo
#from __future__ import print_function
import csv
import os
import sys
import operator
import itertools
import random
import numpy as np
from array import array
import matplotlib.pyplot as plt
from scipy.optimize import nnls, minimize
from scipy.sparse import coo_matrix
import pandas as pd
from sklearn.utils import shuffle
import networkx as nx
np.set_printoptions(linewidth=120)
np.random.seed(1)

""" Test Solver with random data """
#M, N = 2, 3
#A = np.random.random(size=(M,N))
#x_hidden = np.random.random(size=N)
#b = A.dot(x_hidden)  # target
#n = N
#
#print('Original A')
#print(A)
#print('hidden x: ', x_hidden)
#print('target: ', b)

A = np.array(
[
[1486,1522,1536,1485,1598,1570,1593,1491,1540,1544,1566,1544,1573,1490,1530,1526,1546,1518,1498,1567],
[96454395,101615856,110933285,97323661,104973593,101499747,106069432,91496414,101843454,101040852,107795438,100260356,99722283,96419402,104875509,108908675,100158114,107298576,96209051,99065264],
[226553304,219597259,223410668,217613414,237752337,225150384,230103384,219982453,219726185,227791091,225452565,225279979,225682678,213304290,236148563,223027694,244961198,216856884,207345788,231758040]
]
)

b = np.array([8531., 1079115532., 429386951.])
n = 20

""" Optimize as LP """
def solve(A, b, n):
    print('Reformulation')
    am, an = A.shape

    # Introduce aux-vars
    # 1: y = mean
    # n: z = x - mean
    # n: abs(z)
    n_plus_aux_vars = 3*n + 1

    # Equality constraint: y = mean
    eq_mean_A = np.zeros(n_plus_aux_vars)
    eq_mean_A[:n] = 1. / n
    eq_mean_A[n] = -1.
    eq_mean_b = np.array([0])

    print('y = mean A:')
    print(eq_mean_A)
    print('y = mean b:')
    print(eq_mean_b)

    # Equality constraints: Ax = b
    eq_A = np.zeros((am, n_plus_aux_vars))
    eq_A[:, :n] = A[:, :n]
    eq_b = np.copy(b)

    print('Ax=b A:')
    print(eq_A)
    print('Ax=b b:')
    print(eq_b)

    # Equality constraints: z = x - mean
    eq_mean_A_z = np.hstack([-np.eye(n), np.ones((n, 1)), + np.eye(n), np.zeros((n, n))])
    eq_mean_b_z = np.zeros(n)

    print('z = x - mean A:')
    print(eq_mean_A_z)
    print('z = x - mean b:')
    print(eq_mean_b_z)

    # Inequality constraints: absolute values -> x <= x' ; -x <= x'

    ineq_abs_0_A = np.hstack([np.zeros((n, n)), np.zeros((n, 1)), np.eye(n), -np.eye(n)])
    ineq_abs_0_b = np.zeros(n)

    ineq_abs_1_A = np.hstack([np.zeros((n, n)), np.zeros((n, 1)), -np.eye(n), -np.eye(n)])
    ineq_abs_1_b = np.zeros(n)

    # Bounds
    # REMARK: Do not touch anything besides the first bounds-row!
    bounds = [(-50., 50.) for i in range(n)] +     \
             [(None, None)] +                   \
             [(None, None) for i in range(n)] + \
             [(0, None) for i in range(n)]

    # Objective
    c = np.zeros(n_plus_aux_vars)
    c[-n:] = 1

    A_eq = np.vstack((eq_mean_A, eq_A, eq_mean_A_z))
    b_eq = np.hstack([eq_mean_b, eq_b, eq_mean_b_z])

    A_ineq = np.vstack((ineq_abs_0_A, ineq_abs_1_A))
    b_ineq = np.hstack([ineq_abs_0_b, ineq_abs_1_b])

    print('solve...')
    result = spo.linprog(c, A_ineq, b_ineq, A_eq, b_eq, bounds=bounds, method='interior-point')
    print(result)
    x = result.x[:n]
    print('x: ', x)
    print('residual Ax-b: ', A.dot(x) - b)
    print('residual Ax-b %: ', np.divide(A.dot(x)-b,b))   
    print('mean: ', result.x[n])
    print('x - mean: ', x - result.x[n])
    print('l1-norm(x - mean) / objective: ', np.linalg.norm(x - result.x[n], 1))


solve(A, b, n)

0 个答案:

没有答案