繁体   English   中英

Python:GEKKO 求解代数微分方程的快速替代方案

[英]Python: Fast alternatives to GEKKO for solving Algebraic differential equations

为了模拟电网中的潮流,我使用 GEKKO 来求解我的代数微分方程系统。

对于较小的模拟,它工作得很好,但是连续运行几次,例如在训练强化学习代理时,需要相当长的时间。

谁能建议一个开销较小的求解器来加快模拟速度?

系统外观的一个小例子在我们的 GitHub 回购链接中:

https://github.com/upb-lea/openmodelica-microgrid-gym/blob/feature_50_SinglePhaseModel/experiments/swing_equation/gekko_freq_volt.py

还有其他替代品,例如 assimulo 和 CasADi。 但我还没有找到接近 GEKKO 的东西。 我的建议是,用参数而不是变量来定义 model。 这肯定会减少重新初始化 model 所需的时间。

在一些基准测试中,Gekko 比 pyomo 快大约 5 倍。 我们还与目前正在使用 CasADi 的团队合作,以加快对 Gekko 的优化。 如果它是一种代数建模语言,那么 Gekko 是最快的选择之一。 以下是对 Gekko 的一些建议。 使用m.options.TIME_SHIFT=0切换到 IMODE IMODE=4以从先前的解决方案作为热启动解决。 这可以显着提高求解速度。 另一种选择是并行化 function 调用,以使用multi-threading进行强化学习代理。

import numpy as np
import threading
import time, random
from gekko import GEKKO

class ThreadClass(threading.Thread):
    def __init__(self, id, server, ai, bi):
        s = self
        s.id = id
        s.server = server
        s.m = GEKKO(remote=False)
        s.a = ai
        s.b = bi
        s.objective = float('NaN')

        # initialize variables
        s.m.x1 = s.m.Var(1,lb=1,ub=5)
        s.m.x2 = s.m.Var(5,lb=1,ub=5)
        s.m.x3 = s.m.Var(5,lb=1,ub=5)
        s.m.x4 = s.m.Var(1,lb=1,ub=5)

        # Equations
        s.m.Equation(s.m.x1*s.m.x2*s.m.x3*s.m.x4>=s.a)
        s.m.Equation(s.m.x1**2+s.m.x2**2+s.m.x3**2+s.m.x4**2==s.b)

        # Objective
        s.m.Minimize(s.m.x1*s.m.x4*(s.m.x1+s.m.x2+s.m.x3)+s.m.x3)

        # Set global options
        s.m.options.IMODE = 3 # steady state optimization
        s.m.options.SOLVER = 1 # APOPT solver

        threading.Thread.__init__(s)

    def run(self):

        # Don't overload server by executing all scripts at once
        sleep_time = random.random()
        time.sleep(sleep_time)

        print('Running application ' + str(self.id) + '\n')

        # Solve
        self.m.solve(disp=False)

        # Retrieve objective if successful
        if (self.m.options.APPSTATUS==1):
            self.objective = self.m.options.objfcnval
        else:
            self.objective = float('NaN')
        self.m.cleanup()

# Select server
server = 'https://byu.apmonitor.com'

# Optimize at mesh points
x = np.arange(20.0, 30.0, 2.0)
y = np.arange(30.0, 50.0, 2.0)
a, b = np.meshgrid(x, y)

# Array of threads
threads = []

# Calculate objective at all meshgrid points

# Load applications
id = 0
for i in range(a.shape[0]):
    for j in range(b.shape[1]):
        # Create new thread
        threads.append(ThreadClass(id, server, a[i,j], b[i,j]))
        # Increment ID
        id += 1

# Run applications simultaneously as multiple threads
# Max number of threads to run at once
max_threads = 8
for t in threads:
    while (threading.activeCount()>max_threads):
        # check for additional threads every 0.01 sec
        time.sleep(0.01)
    # start the thread
    t.start()

# Check for completion
mt = 3.0 # max time
it = 0.0 # incrementing time
st = 1.0 # sleep time
while (threading.activeCount()>=1):
    time.sleep(st)
    it = it + st
    print('Active Threads: ' + str(threading.activeCount()))
    # Terminate after max time
    if (it>=mt):
        break

# Wait for all threads to complete
#for t in threads:
#    t.join()
#print('Threads complete')

# Initialize array for objective
obj = np.empty_like(a)

# Retrieve objective results
id = 0
for i in range(a.shape[0]):
    for j in range(b.shape[1]):
        obj[i,j] = threads[id].objective
        id += 1

# plot 3D figure of results
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
from matplotlib import cm
import numpy as np

fig = plt.figure()
ax = fig.gca(projection='3d')
surf = ax.plot_surface(a, b, obj, \
                       rstride=1, cstride=1, cmap=cm.coolwarm, \
                       vmin = 12, vmax = 22, linewidth=0, antialiased=False)
ax.set_xlabel('a')
ax.set_ylabel('b')
ax.set_zlabel('obj')
ax.set_title('Multi-Threaded GEKKO')
plt.show()

如果在 Sundials 中有一个 DAE 集成器,例如 IDA ,那么这也可能是模拟的替代方案。 Gekko 解决了更高的 DAE 索引问题,而大多数集成器(如 DASSL、DASPK 和 IDA)仅限于索引 1 DAE 和可选的索引 2 Hessenberg 形式。 如果可能的话,这通常会造成将方程重新排列成那种形式的巨大负担。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM