Ошибка AMPL Cplex: QP Hessian не является положительным полуопределенным

В настоящее время я пытаюсь решить модель AMPL, которая работает для меня с использованием minos, с cplex и интегральными переменными.

Большинство проблем я решил (думаю). Я помог себе "уловкой соотношения" отсюда: http://lpsolve.sourceforge.net/5.5/ratio.htm, но прямо сейчас я получаю «QP Hessian не является положительным полуопределенным». ошибка из-за одного из моих ограничений.

Я вроде знаю, что означает ошибка, но не уверен, почему она отображается для этого ограничения: /

#S
set SOURCE;
#D
set HALFPROD;
#K
set HALFPRODU;
#P
set PROD;

param surmax {SOURCE} >= 0;
param prodmin {PROD} >= 0;
param prodprofit {PROD} >= 0;
param convSDmax >= 0;
param convDKmax >= 0;
param convSD {SOURCE, HALFPROD} >= 0;
param convDK {HALFPROD, HALFPRODU} >= 0;
param convDP {HALFPROD, PROD} >= 0;
param convKP {HALFPRODU, PROD} >= 0;

var xs {SOURCE} >= 0, integer;
var xu {HALFPROD} >= 0, integer;
var xpd {PROD, HALFPROD} >= 0, integer;
var xpk {PROD, HALFPRODU} >= 0, integer;
var isKUsed binary;

var quantityD {j in HALFPROD} = sum {i in SOURCE} convSD[i,j] * xs[i];
var costSur = sum {i in SOURCE} xs[i]*12;

var quantityK {k in HALFPRODU} = (sum {j in HALFPROD} xu[j] * convDK[j,k]) * isKUsed;
var costK = isKUsed * 13000;

var quantityProdD {l in PROD} = sum {j in HALFPROD} xpd[l,j] * convDP[j,l];
var quantityProdK {l in PROD} = sum {k in HALFPRODU} xpk[l,k] * convKP[k,l];
var quantityProd {l in PROD} = quantityProdD[l] + quantityProdK[l];

var profitProd = sum {l in PROD} prodprofit[l] * quantityProd[l];
var balance = profitProd - costSur - costUwod;

subject to OgrSurMax {i in SOURCE}: xs[i] <= surmax[i];
subject to OgrconvSDMax: (sum {i in SOURCE} xs[i]) <= convSDmax;
subject to OgrconvDKMax: (sum {j in HALFPROD} xu[j]) <= convDKmax;
subject to OgrProdMin {l in PROD}: quantityProd[l] >= prodmin[l];
subject to OgrHALFPRODXPD {j in HALFPROD}: (sum {l in PROD} xpd[l,j]) + xu[j] - quantityD[j] <= 0;
#------------------TRAITOR!
subject to OgrHALFPRODXPK {k in HALFPRODU}: (sum {l in PROD} xpk[l,k]) - quantityK[k] <= 0;
#--------------------------

maximize balanceMax: balance;

Это моя модель.

"conv" означает конверсию:

  • S-> D и D-> K - это отношения «сколько D я получаю от преобразования S?»
  • D-> P и K-> P - двоичные матрицы, которые говорят, можно ли преобразовать D или K в P

Основными участниками этой модели являются xpd и xpk - они говорят, сколько PROD было получено от конвертации HALFPROD или HALFPRODU. Из-за множественных преобразований я должен отслеживать количество D - количество D, используемых для D-> K и D-> P, должно быть меньше или равно D из S-> D. Это работает, но по какой-то причине такое же (даже более простое) ограничение не работает: /

Есть какие-нибудь подсказки относительно того, в чем может быть проблема или как ее исправить?


ОБНОВЛЕНИЕ:

Основываясь на ответе Эрвина Калвелагенса, я попытался его линеаризовать. Не удалось найти простой способ его линеаризации, кроме метода bigM. Я изменил свою часть количестваD на это:

param quantityKMAX = 490860;
var quantityK {k in HALFPRODU} >= 0;
s.t. ogrK1 {k in HALFPRODU}: quantityK[k] <= quantityKMAX * isKUsed;
s.t. ogrK2 {k in HALFPRODU}: quantityK[k] <= (sum {j in HALFPROD} xu[j] * convDK[j,k]);
s.t. ogrK3 {k in HALFPRODU}: quantityK[k] <= (sum {j in HALFPROD} xu[j] * convDK[j,k]) - quantityKMAX * (1 - isKUsed);

amountKMAX - это максимальное количество, полученное при преобразовании (при преобразовании максимально возможного количества D в "наиболее полезный" K), но я на самом деле пробовал с произвольно большим числом, которое наверняка больше любого возможное значение для amountK.

Работает!


person MKK    schedule 04.11.2017    source источник


Ответы (1)


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

Один простой подход - решить проблему дважды: один раз с isKUsed=0 и один раз с isKUsed=1. Тогда просто выберите лучшее решение.

В противном случае вы можете сделать что-то линеаризованным. Умножение двоичной переменной на непрерывную (или целую) неотрицательную переменную не очень сложно линеаризовать.

person Erwin Kalvelagen    schedule 04.11.2017
comment
Большое спасибо! Ни для кого не секрет, что мой вопрос выглядит как задание - оно одно. Я должен сказать, что Ваш ответ - лучший ответ на переполнение стека, на который можно надеяться - не слишком много, но достаточно. Решить проблему дважды - это действительно просто, но я думаю, что мне нужно попытаться линеаризовать ее. Я попробую это и вернусь к Вам с результатами;) - person MKK; 06.11.2017