Как сделать параллельный Python Gekko?

Иногда мое приложение Python Gekko решается лучше с одним решателем по сравнению с другим. Трудно предсказать, какой решатель будет работать лучше всего. Поскольку Python Gekko поддерживает локальные или удаленные решения на разных серверах с m.GEKKO(server='http://{address}'), возможно ли создать параллельное приложение Gekko, которое будет проверять все решатели одновременно на любом количестве компьютеров (включая локальные), а затем завершать другие процессы, когда возвращается первый. успешно? Я искал многопоточные и параллельные пакеты для Python. Есть ли что-то, что хорошо работает с Gekko для параллельных решений? Вот последовательный прототип:

from gekko import GEKKO
m = GEKKO()
x = m.Var(); y = m.Var()
m.Equation(x**2+y**2==1)
m.Maximize(x+y)
# try all solvers
for i in range(1,4):
    m.options.SOLVER = i
    m.solve()
    if m.options.APPSTATUS==1:
        print('Success: ' + str(i))

person TexasEngineer    schedule 16.11.2019    source источник
comment
Это помогает? apmonitor.com/me575/index.php/Main/ParallelComputing Я не уверен, лучше ли будет параллельная обработка с multiprocessing или многопоточное приложение с threading. Кажется, что многопоточность была бы лучше, если бы вы решали в сетевом кластере компьютеров, потому что ваш основной скрипт может порождать их последовательно, а затем ждать возврата первого.   -  person John Hedengren    schedule 16.11.2019
comment
Вот некоторая информация о том, как завершить другие потоки после завершения одного: stackoverflow.com/questions/17564804/   -  person John Hedengren    schedule 17.11.2019


Ответы (1)


Вы можете решать на любом количестве серверов одновременно с многопоточным приложением. Вот параллельная версия вашего последовательного приложения, использующая queue, хотя она не останавливает другие потоки по завершении первого. Даже если другие потоки не остановлены, вы можете включить MAX_TIME значение < / a>, чтобы потоки были принудительно завершены в течение указанного количества секунд. Этот подход позволяет вам продолжить основную программу, позволяя другим потокам умереть, когда они завершатся или достигнут максимального временного лимита.

from gekko import GEKKO
import queue, threading

def solve(rq, solver, server):
    #print('Solver ' + str(solver) + ' Server: ' + str(server) + '\n')
    if server=='localhost':
        m = GEKKO(remote=False)
    else:
        m = GEKKO(server=server)
    x = m.Var(); y = m.Var()
    m.Equation(x**2+y**2==1)
    m.Maximize(x+y)
    m.options.SOLVER = solver
    m.options.MAX_TIME = 2
    m.solve(disp=False)
    m.cleanup()
    rq.put(('solver',solver,'server',server))

# Select servers and solvers (1=APOPT, 2=BPOPT, 3=IPOPT, etc)
APOPT = 1; BPOPT = 2; IPOPT = 3
jobs = {'https://byu.apmonitor.com':APOPT,\
        'localhost':APOPT,\
        'https://byu.apmonitor.com':IPOPT,\
        'https://apmonitor.com':IPOPT}

# Run jobs, get only first result
q = queue.Queue()
threads = [threading.Thread(target=solve, args=(q, solver, server)) \
           for server, solver in jobs.items()]
for th in threads:
    th.daemon = True
    th.start()
first = q.get(); print(first)

Если вы также хотите получить второй или несколько результатов, вы можете добавить еще одну строку с дополнительными q.get() вызовами.

second = q.get(); print(second)
person John Hedengren    schedule 17.11.2019