簡體   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