Есть ли библиотека квадратичного программирования на С++?

Единственный результат поиска Google, который я нашел, — это QuadProg++, но он не может решить задачу квадратичного программирования, матрица которой неприменима для разложения Холецкого.

Так может ли кто-нибудь дать мне какое-нибудь предложение по другой библиотеке? Спасибо.


person Daniel Gao    schedule 06.11.2011    source источник
comment
Извините за очевидное, но мне пришлось проверить Википедию, чтобы узнать, что такое квадратичное программирование, и я увидел, что там есть ссылки на несколько реализаций, вы их проверяли? Или, может быть, hqp.sourceforge.net/index.html или gnu.org/s/gsl поможет?   -  person rve    schedule 06.11.2011
comment
@rve Я проверяю gsl, в нем нет функции решения квадратичного программирования. Я также проверил вики, большинство из них либо не написаны на C/С++, либо их очень сложно настроить. Я проверю hqp, чтобы увидеть, работает ли он, спасибо   -  person Daniel Gao    schedule 06.11.2011
comment
Как матрица может быть неприменима к разложению Холецкого? Применима любая симметричная положительно-полуопределенная матрица (и разложение занимает ~ n ^ 3/3 FLOP). Выражение $x^TQx$ всегда можно (пере)переписать с симметричным $Q$. Вы имеете в виду, что оно не является положительно-полуопределенным?   -  person fiktor    schedule 28.05.2012
comment
QuadProg++ требует, чтобы матрица была положительно определенной, а не положительно полуопределенной.   -  person Yoav    schedule 19.07.2012
comment
Вы нашли решение для этого? Если да, то не могли бы вы опубликовать это здесь?   -  person Yoav    schedule 19.07.2012
comment
Как насчет CQP в GSL? Я не уверен, что для этого требуется p.d.?   -  person tlamadon    schedule 13.09.2013


Ответы (5)


CGAL отлично подходит для квадратичного программирования. Существует даже руководство.

  // by default, we have a nonnegative QP with Ax <= b
  Program qp (CGAL::SMALLER, true, 0, false, 0); 

  // now set the non-default entries: 
  const int X = 0; 
  const int Y = 1;
  qp.set_a(X, 0,  1); qp.set_a(Y, 0, 1); qp.set_b(0, 7);  //  x + y  <= 7
  qp.set_a(X, 1, -1); qp.set_a(Y, 1, 2); qp.set_b(1, 4);  // -x + 2y <= 4
  qp.set_u(Y, true, 4);                                   //       y <= 4
  qp.set_d(X, X, 2); qp.set_d (Y, Y, 8); // !!specify 2D!!    x^2 + 4 y^2
  qp.set_c(Y, -32);                                       // -32y
  qp.set_c0(64);                                          // +64

  // solve the program, using ET as the exact type
  Solution s = CGAL::solve_quadratic_program(qp, ET());
  assert (s.solves_quadratic_program(qp));

Код из первого примера.

person Wok    schedule 08.11.2012

LAPACK имеет несколько процедур декомпозиции Холецкого (они называют это факторизацией Холецкого). Для LAPACK доступны оболочки C++ (см. этот SO вопрос для списка).

Ответ Anycom в этом сообщении немного загадочен, но он имел в виду, что существуют привязки LAPACK, которые можно использовать вместе с библиотекой линейной алгебры Boost, uBLAS.


Я нашел эту библиотеку: OOQP (объектно-ориентированное программное обеспечение для квадратичного программирования ). Если вы прокрутите эту страницу вниз, вы найдете исследовательскую работу и руководство пользователя. Кажется, для этой библиотеки есть C++ API. Надеюсь это поможет.

person Emile Cormier    schedule 06.11.2011
comment
Но это не решает мою проблему. Симметричная матрица в задаче квадратичного программирования, которую я пытаюсь решить, неприменима для разложения Холецкого. - person Daniel Gao; 06.11.2011
comment
Упс, я невнимательно прочитал ваш вопрос. Извиняюсь. - person Emile Cormier; 06.11.2011
comment
@DanielGao: обновил мой ответ. - person Emile Cormier; 06.11.2011

Есть несколько библиотек, которые включают решатели QP. Существуют как открытые, так и коммерческие варианты. В существующих ответах перечислены некоторые из них. Хочу уточнить вопрос с матрицей.

Я предполагаю, что вы имеете в виду объективную матрицу. Матрица ограничений должна привести только к непустому допустимому множеству. Вы упомянули, что матрица не подходит для разложения Холецкого. Поскольку разложение Холецкого может быть сформировано для любой положительно определенной матрицы, подразумевается, что ваша матрица не является положительно определенной.

Если матрица является положительно полуопределенной (т. е. имеет одно или несколько нулевых собственных значений), то задача является выпуклой КП и может быть решена эффективно. Однако многие решатели требуют положительно определенной цели. Поскольку цель положительно полуопределенного QP имеет нетривиальное нулевое пространство, может быть много решений. На самом деле множество решений может быть даже неограниченным. Численные алгоритмы в любом случае дадут только приближенное решение, поэтому редко важно, чтобы собственные значения матрицы были точно равны нулю. Вы можете сделать матрицу положительно определенной, добавив диагональную матрицу с небольшим положительным значением на диагонали. Это по существу выберет решение с наименьшей 2-нормой. На практике рекомендуется делать это, даже если матрица положительно определена, потому что матрицы с собственными значениями, близкими к нулю, часто могут вызывать проблемы с численными решателями. Сколько диагонали добавить — это компромисс между стабильностью и точностью.

Если матрица неопределенная (т. е. имеет хотя бы одно отрицательное собственное значение), то задача является NP-трудной. Это означает, что любые коды, основанные на доступных в настоящее время алгоритмах, будут иметь необоснованное время работы в худшем случае даже для задач среднего размера. Если ваша проблема имеет какую-то особую структуру или вам не требуется глобально оптимальное решение, то вы можете быть в порядке. Типичный подход состоит в поиске выпуклой релаксации.

person MichaelJ    schedule 30.12.2013
comment
Все интересно, но OP просил указатели на другие библиотеки, а не диссертацию о том, как решать проблемы QP. - person Ted Hopp; 30.12.2013
comment
В этом случае кажется, что диссертация о том, как решать проблемы QP, - это то, что OP на самом деле нужно, независимо от того, осознают они это или нет. - person zwol; 31.12.2013

Тонкость, которая отсутствует во многих приведенных выше ответах, заключается в том, является ли матрица только положительно-полуопределенной (PSD) или на самом деле неопределенной. Я не использовал quadprog, но если он дает сбой на целевой матрице PSD, это признак недостаточной надежности программного обеспечения (выпуклые QP часто являются PSD, где только строго выпуклые QP являются положительно определенными). Согласно книге Голуба «Матричные вычисления», факторизация Холецкого может применяться к матрицам PSD, но числовая стабильность имеет тенденцию страдать.

Для общего программного обеспечения для нелинейного программирования, как выпуклого, так и невыпуклого, проект COIN-OR поддерживает списки бесплатного и несвободного программного обеспечения. Одним из решателей, которые они перечисляют, является IPOPT, который, безусловно, способен решить вашу проблему. IPOPT использует алгоритм внутренней точки, который для небольших задач обычно медленнее, чем методы с активным набором (например, использует quadprog). В качестве альтернативы вы можете сформулировать свою QP как проблему линейной дополнительности (LCP), а затем решить ее с помощью решателя LCP. Я обнаружил, что код Fackler и Miranda Matlab LEMKE легко переносим на C++.

person Evan Drumwright    schedule 25.07.2013

Если вы готовы платить, вы можете использовать Mosek. Однако есть бесплатная 30-дневная пробная версия. Как правило, он считается самым быстрым из доступных решателей (извините, без ссылок). Интерфейс выполнен в стиле C, хотя очевидно, что он идеально подходит для C++. Mosek на самом деле больше похож на решатель конического программирования, но если вам не хочется переформулировать свою проблему как коническую задачу (у Mosek есть много документации о том, как это сделать), вы все равно можете использовать его решатель стохастического градиентного спуска для решения Ваша квадратичная формулировка.

person frankc    schedule 08.11.2012