Cplex найти недопустимое решение - PullRequest
0 голосов
/ 26 мая 2020

Я делаю MIP-код в Cplex. Проблема имеет допустимое решение, но решение CPLEX невозможно. И это не показывает никакого ослабления, но ослабляет ограничения емкости 1 и 2. Я думаю, что это связано с конфигурацией запуска, но я не знаю, в чем именно проблема.

модель следующая:

//Parameters

//DKPCs
int I=...;
range DKPCs=1..I;

//Small DKPCs 
int S=...;
range SDKPCS=1..S;

//Big and Medium DKPCs

range BDKPCs=S+1..I;

//Depots
range Depots=1..2;

//Free capacity of depots
float Cj[Depots]=...;

//The unit storage cost of product i
float Hi[DKPCs]=...;

//Volume
float Vi[DKPCs]=...;

//The unit lost sale cost of product i
float Si[DKPCs]=...;

//The probability of selling product i if it were available in the DK depots

float Pi[DKPCs]=...;


//The initial inventory of consignment depot for product i
int Ki[DKPCs]=...;

// Total demand for product i in time period

int Di[DKPCs]=...;

int M=...;

//Decision Varaibles

//The assigned consignment capacity for product i
dvar int+ Yi[DKPCs];

//if product i is selected for consignment capacity
dvar boolean  Xi[DKPCs];

//if product i is available in the DK deopts in the problem time period
dvar boolean  Zi[DKPCs];

//Formulation
//Total Cost
dexpr float TotalStorageCost=sum (i in DKPCs)(Yi[i]+Ki[i]*Xi[i]-1/2*Di[i]*Xi[i])*Hi[i];
dexpr float TotalLostSaleCost=sum (i in DKPCs)(1-Zi[i])*(Di[i]-Ki[i])*Si[i]*Pi[i];
dexpr float TotalSmallProductsVolume= sum (i in SDKPCS)Vi[i]*Yi[i];
dexpr float TotalBigProductsVolume= sum (i in BDKPCs)Vi[i]*Yi[i];



minimize TotalStorageCost+TotalLostSaleCost;


subject to {

const1: forall (i in SDKPCS, j in 1..1){
                                                Vi[i]*Yi[i]<=Cj[1];}

const2: forall (i in BDKPCs, j in 2..2){
                                                Vi[i]*Yi[i]<=Cj[2];}

const3: forall (i in DKPCs){
                                                Yi[i]<=M*Xi[i];}

//const4: forall (i in DKPCs){                          
//                                              Ki[i]-Di[i]<=M*(1-Xi[i])-1;}

const5: forall (i in DKPCs){
                                                Ki[i]-Di[i]<=M*Zi[i]-1;}

const6: forall (i in DKPCs){                    
                                                Xi[i]*(Di[i]-Ki[i])<=Yi[i];}

const7: forall (i in DKPCs){                    
                                                Yi[i]<=M*Zi[i];}

const8: forall (i in DKPCs){
                                                (Di[i]-Ki[i])*Zi[i]<=M*Xi[i];}                                              

const9: forall (i in DKPCs){    
                                                Yi[i]>=0;}}

execute DISPLAY {
      writeln("TotalStorageCost=", TotalStorageCost);
      writeln("TotalLostSaleCost=",TotalLostSaleCost);
      writeln("TotalSmallProductsVolume=",TotalSmallProductsVolume);
      writeln("TotalBigProductsVolume=",TotalBigProductsVolume);

        }

И данные следующие:

 I=10;
 S=3;

Cj=[2,500];

Hi=[38  33  23  23  23  33  43  43  47  41];

Vi=[0.02    0.03    0.01    0.38    1.02    1.86    0.48    1.00    1.31    1.19];

Si=[63  81  174 119 157 177 125 101 97  176];

Pi=[0.83    0.69    0.10    0.07    0.51    0.20    0.92    0.60    0.32    0.33];

Ki=[20  24  13  22  16  24  13  12  20  13];


Di=[67  20  212 406 417 423 134 425 103 447];

M=999999999999999999;

1 Ответ

0 голосов
/ 26 мая 2020

действительно. Мое предложение: выключите предварительное решение.

Добавьте

execute
{
  cplex.preind=0;
}

в начале вашей модели

Плюс, если вы используете datacheck 2

execute
{
  cplex.datacheck=2;
}

вы получите

CPLEX Предупреждение 1041: в ограничении 50, где переменная 'Xi (1)' имеет коэффициент 1e + 18, рассмотрите возможность использования индикатора.

Поэтому вместо использования большого M вы можете использовать логические ограничения.

Если x - это двоичная переменная решения, а y - целочисленная переменная решения, вы можете записать в OPL

(x==(y>=7));
...