gpt4 book ai didi

python - 比暴力破解更快地解决约束满足问题的方法?

转载 作者:太空宇宙 更新时间:2023-11-03 16:22:03 25 4
gpt4 key购买 nike

我有一个 CSV,它为每行提供三个不同 x 值的 y 值。当读入 pandas DataFrame 时,它​​看起来像这样:

     5     10    20
0 -13.6 -10.7 -10.3
1 -14.1 -11.2 -10.8
2 -12.3 -9.4 -9.0

也就是说,对于第 0 行,第 5 行的值为 -13.6,第 10 行的值为 -10.7,第 20 行的值为 -10.3。这些值是以下形式的算法的结果:

def calc(x, r, b, c, d):
if x < 10:
y = (x * r + b) / x
elif x >= 10 and x < 20:
y = ((x * r) + (b - c)) / x
else:
y = ((x * r) + (b - d)) / x
return y

我想找到每一行的 r、b、c 和 d 的值。我对每个值都有一定的了解。例如,对于每一行: r 位于 np.arange(-.05, -.11, -.01) 中,b 位于 np.arange(0, -20.05, -.05) 中,c 和 d 位于np.arange(0, 85, 5)。我还知道 d 是 <= c。

目前,我正在用暴力解决这个问题。对于每一行,我迭代 r、b、c 和 d 的每个组合,并测试三个 x 值处的值是否等于 DataFrame 中的已知值。这是有效的,为我提供了每行的一些组合,除了舍入差异之外,这些组合基本上相同。

问题是,当我需要对 2,000 多行运行时,这种方法需要很长时间。我的问题是:有没有比迭代和测试每个组合更快的方法?我的理解是,这是一个约束满足问题,但之后,我不知道要缩小范围;有很多类型的约束满足问题(看起来),我仍然迷失了(我什至不确定这是一个这样的问题!)。任何帮助我指明正确方向的帮助将不胜感激。

最佳答案

我希望我正确理解了任务。

如果您知道参数的分辨率/离散化,它看起来像是一个离散优化问题(通常:困难),可以通过 CP 方法解决。

但是如果您允许这些值连续(并重新制定公式),则:

  • (1) 线性规划:如果检查可行值(需要有有效的解决方案)
  • (2) 线性程序:如果优化参数以最小化绝对差值之和(=误差)
  • (3) 二次规划:如果优化参数以最小化平方差之和(=误差)/相当于最小化欧几里得范数

所有三个版本都可以有效解决!

这是使用 cvxpy 的 (3) 的非通用(可以很容易地通用)实现制定问题并 ecos来解决QP。这两个工具都是开源的。

代码

import numpy as np
import time
from cvxpy import *
from random import uniform

""" GENERATE TEST DATA """
def sample_params():
while True:
r = uniform(-0.11, -0.05)
b = uniform(-20.05, 0)
c = uniform(0, 85)
d = uniform(0, 85)
if d <= c:
return r, b, c, d

def calc(x, r, b, c, d):
if x < 10:
y = (x * r + b) / x
elif x >= 10 and x < 20:
y = ((x * r) + (b - c)) / x
else:
y = ((x * r) + (b - d)) / x
return y

N = 2000
sampled_params = [sample_params() for i in range(N)]
data_5 = np.array([calc(5, *sampled_params[i]) for i in range(N)])
data_10 = np.array([calc(10, *sampled_params[i]) for i in range(N)])
data_20 = np.array([calc(20, *sampled_params[i]) for i in range(N)])
data = np.empty((N, 3))
for i in range(N):
data[i, :] = [data_5[i], data_10[i], data_20[i]]

""" SOLVER """
def solve(row):
""" vars """
R = Variable(1)
B = Variable(1)
C = Variable(1)
D = Variable(1)
E = Variable(3)

""" constraints """
constraints = []
# bounds
constraints.append(R >= -.11)
constraints.append(R <= -.05)
constraints.append(B >= -20.05)
constraints.append(B <= 0.0)
constraints.append(C >= 0.0)
constraints.append(C <= 85.0)
constraints.append(D >= 0.0)
constraints.append(D <= 85.0)
constraints.append(D <= C)
# formula of model
constraints.append((1.0 / 5.0) * B + R == row[0] + E[0]) # alternate function form: b/x+r
constraints.append((1.0 / 10.0) * B - (1.0 / 10.0) * C == row[1] + E[1]) # alternate function form: b/x-c/x+r
constraints.append((1.0 / 20.0) * B - (1.0 / 20.0) * D == row[2] + E[2]) # alternate function form: b/x-d/x+r

""" Objective """
objective = Minimize(norm(E, 2))

""" Solve """
problem = Problem(objective, constraints)
problem.solve(solver=ECOS, verbose=False)
return R.value, B.value, C.value, D.value, E.value

start = time.time()
for i in range(N):
r, b, c, d, e = solve(data[i])
end = time.time()

print('seconds taken: ', end-start)
print('seconds per row: ', (end-start) / N)

输出

('seconds taken: ', 20.620506048202515)
('seconds per row: ', 0.010310253024101258)

关于python - 比暴力破解更快地解决约束满足问题的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38354320/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com