2013-08-19 5 views
2

Я решал некоторые пластинки с gurobi, и я заметил, что для большинства случаев, с которыми я сталкиваюсь, построение модели занимает больше времени, чем фактически ее решение. Возможно, это стандартно, но для меня это кажется странным.Gurobi долгое время строил модель для LP

Один конкретный экземпляр занял 1,75 секунд, чтобы решить, но следующий участок кода для построения модели взяли 13,6 секунды:

for (int i = 0; i < numSeq2; ++i) { 
    expr = new GRBLinExpr(); 
    //expr.clear(); 
    for (int j = 0; j < numSeq1; ++j) 
     expr.addTerm(-1 * A[j][i], x[j]); 
    for (int j = 0; j < numIS2; ++j) 
     expr.addTerm(-1 * F[j][i], q[j]); 
    duals[i] = model.addConstr(expr, GRB.LESS_EQUAL, 0, ""); 
} 

В примере, описанном выше, numSeq1 = 7475, numSeq2 = 7475, numIS2 = 2517, а окончательный LP имел 9992 строки и 9992 столбца. Я знаю, что это довольно большой, но, похоже, странно, что для создания модели требуется почти 10 раз больше времени, чем для ее решения.

Я попробовал expr.clear() вместо создания нового GRBLinExpr для каждого ограничения (закомментировал), и это не помогло.

Есть ли какой-нибудь способ сделать модельную конструкцию гуроби быстрее? Будет ли cplex лучше, чем gurobi в этом отношении, если узкое место строит модель?

Спасибо!

ответ

-2

Поскольку вы спрашиваете об альтернативах, я считаю, что вам лучше использовать язык алгебраического моделирования, такой как AMPL, AIMMS или альтернативы с открытым исходным кодом, такие как GLPK и AML. Эти декларативные языки позволяют кратко и изящно сформулировать вашу проблему. Эти языки генерируют MPS или NL, которые затем могут обрабатываться CPLEX или альтернативными свободными решателями. Как вы можете видеть, язык моделирования - это одно, а решатель - другой.

+0

Tarik: Предположим, что я сейчас только забочусь о скорости (а не изящество или лаконичность), как вы думаете, эти другие языки помогут? – beserious

+1

Нет: правильно написанный код с интерпретированным языком моделирования не будет быстрее, чем правильно написанный код, используя API-интерфейс решателя. Незначительная причина этого заключается в том, что сами системы моделирования называют решающие API. –

+0

Я честно не знаю. Если кто-то не испытывает опыта с Gurobi, я не думаю, что вам следует ожидать большой части ответа на этом сайте. Тем не менее, хотя и большой, ваша проблема кажется довольно простой, и было бы не так много времени для изучения альтернатив, таких как создание входных файлов MPS, которые бывают в текстовой форме и не потребуют значительной части кривой обучения. – Tarik

1

Во-первых, в блоках вашего образца кода (теперь исправлено) была большая опечатка. Это заставляет меня задаться вопросом, должна ли ваша модель иметь numSeq2 строк (7495).

Если каждый элемент в ваших матрицах A и F отличен от нуля, структура вашего кода в порядке. Однако это очень редко. в большинстве случаев подавляющее большинство матричных коэффициентов равно нулю. Если это так, вы должны вызвать GRBLinExpr.addTerm() только для ненулевых элементов в строках. Это верно независимо от того, используете ли вы Gurobi или любой другой решатель.

(. Обратите внимание, что вы можете получить быстрый ответ на Gurobi специфических вопросов на собственном дискуссионном форуме Gurobi в)

Отказ от ответственности: я работаю для Gurobi оптимизации и ранее работал ILOG, который обеспечил CPLEX.

+0

Привет, Грегг, что такое опечатка? Когда я копировал/вставлял его, возникла проблема с отступом в примере кода, который я только что исправил. Кроме того, numSeq2 должен быть 7475 в примере (то же, что и numSeq1), который я только что исправил (эта часть была опечаткой). Предполагается, что у модели есть строки numSeq2, это правильно. Как я уже говорил ниже, использование addTerms() вместо addTerm() немного помогло. Я также попробую ваше предложение с нулевыми коэффициентами и проведу форум Gurobi. Благодаря! – beserious

+1

Игнорирование нулевых коэффициентов позволило решить проблему, спасибо! Теперь он занимает 1-2 секунды на LP вместо 12-15! – beserious

+0

Число брекетов/блоков было неправильным; теперь это исправлено. –