Добавление ограничений линейного неравенства в мистике - PullRequest
1 голос
/ 15 мая 2019

Я пытаюсь реализовать нелинейную оптимизацию с 16 ограничениями линейного неравенства и одним ограничением линейного равенства, используя мистику для задачи с 100 переменными.Когда я использую модуль linear_symbolic для создания ограничений, выполнение застревает.Я не нахожу другого очевидного способа добавления ограничений.

Модуль минимизации Сципи создает плохие решения для целевых функций, которые не имеют квадратичного типа (моя цель - относительная энтропия) и когда начальные значения не очень близки коптимальное решение, поэтому мне пришлось отказаться от него.Это действительно то, что Майк МакКернс делает, когда мотивирует мистика, поэтому я был очень счастлив, столкнувшись с ним.

Я пробовал следующие две строки:

cf = mystic.symbolic.linear_symbolic(np.ones(100),[1.],G,h) 
cons = mystic.symbolic.generate_constraint(mystic.symbolic.generate_solvers(mystic.symbolic.simplify(cf)))

, где G - этоматрица коэффициентов 16x100, а h - 16-мерный вектор, содержащий константы в правой части неравенств.

Код выполняется относительно быстро в первой строке выше, но никогда не проходит через вторую (мой компьютер зависает после долгого ожидания).

1 Ответ

0 голосов
/ 15 мая 2019

Аналогичный вопрос / ответ на Проблемы, связанные с установкой ограничения через пакет mystic .

Упрощение с неравенствами занимает много времени, поскольку оно циклически повторяет все возможные перестановки знаков и предполагает наихудший случай для выделения одной переменной в левой части каждого уравнения. Выполнение следующих действий приведет к выделению одного уравнения за один раз, которое затем можно (теоретически) связать с ключевым словом ограничений «соединение», или, как показано ниже:

>>> import mystic      
>>> import numpy as np
>>> G = np.random.random((16,30)) * 100 
>>> h = np.random.random((16,)) * 1000
>>> c = mystic.symbolic.linear_symbolic(np.ones(30),[1.],G,h)
>>> c = c.strip().split('\n')
>>> cs = '\n'.join(mystic.symbolic.simplify(ci, target='x{i}'.format(i=i)) for i,ci in enumerate(c))
>>> cons = mystic.symbolic.generate_constraint(mystic.symbolic.generate_solvers(cs))

Проблема, по-видимому, заключается в том, что, хотя решение для 30 переменных работает в целом, переход к 100 на строку слишком большой нагрузкой на память используемого компьютера. Таким образом, буквально проблема заключается в том, что код для упрощения неравенств не так эффективен, как это может быть для простых случаев, и становится медленным, как только он начинает привязывать память. Мне придется посмотреть на уменьшение объема памяти ... но вы можете обойти его для своего случая, выполнив еще одно ручное упрощение (все, что нужно сделать, - это выделить одну переменную с каждой левой стороны. каждого уравнения).

В приведенном выше случае это быстро для 10 переменных, но занимает около минуты или около того. Для случая, когда явно существует одна переменная, которая используется только один раз, и, следовательно, ее легко изолировать, это не должно занять много времени. , Я уверен, что с небольшой очисткой я могу уменьшить требования к памяти для функции. Я создал заявку на эту проблему: https://github.com/uqfoundation/mystic/issues/113.

...