СЦЕНАРИЙ ПРИЛОЖЕНИЯ GOOGLE - LinearOptimizationService - Минимизация абсолютных дельт - Проблема невыполнима - PullRequest
1 голос
/ 17 января 2020

В настоящее время я настраиваю задачу оптимизации, цель которой состоит в том, чтобы определить некоторые параметры, минимизирующие расстояние от некоторых целевых параметров, учитывая некоторые фиксированные ограничения

Привет, уже настроил проблему в Excel Solver и работает нормально, но когда я перевожу в сервисы LinearOptimization, я становлюсь невозможным в результате оптимизации.

К сожалению, я не могу понять, настроил ли я математику для минимизации абсолютных разностей или просто сделал несколько ошибок при переводе модели на язык Google Linear Optimization Services. Я не могу изучить детали модели, которую я настроил.

Вот формулировка проблемы

i = 1, 2, 3

Переменные
Xi
Di

Параметры
target_i
coeff_i
targetvalue

Я хочу определить Xi таким образом, чтобы

минимизировать сумму (abs (Di))
Di = target_i-Xi

с следующие ограничения

Xi находится в диапазоне от 0 до 1
sum (Xi) = 1
Sum (Xi * coeff_i) = targetvalue

, чтобы отклонить его в Службе линейной оптимизации, которую я использовал эквивалентная задача:

минимизировать сумму (Di)

со следующими ограничениями
Di> = target_i-Xi
Di <= - (target_i-Xi) <br>Xi находится между 0 и 1
sum (Xi) = 1
Sum (Xi * coeff_i) = targetvalue

Вот скрипт, который я написал для его реализации

// test data  
  var TargetFrequency=2
  var ActualVolumesByBand=[50,100,1200]
  var AvgDropByBand=[5,15,25]
  var TargetDistribution=[0.25,0.5,0.25]
  var Weight=[2,1,2]
  var NumberOfPeriods=52

  var tolerance=0.0001
  var nBands=ActualVolumesByBand.length
  var engine = LinearOptimizationService.createEngine();

// adds a variable for each distribution band

 for (var i=0; i<nBands; i++)

  {
   engine.addVariable('distance'+i, 0, 10000)
   engine.addVariable('FinalDistribution'+i, 0, 1)
  }

 // set objective coefficients using weight and distance 

   for (var i=0; i<nBands; i++)  
  {
   engine.setObjectiveCoefficient('distance'+i, Weight[i])
  }

// set problem
  engine.setMinimization()



////Start Setting COntraints


  // define support arrays
  var LowerBound0=new Array
  for (var i=0;i<nBands;i++ )
  {
    LowerBound0[i]=0
  }
  Logger.log(LowerBound0)
  var UpperBound1000=new Array
  for (var i=0;i<nBands;i++ )
  {
    UpperBound1000[i]=10000
  }
  Logger.log(UpperBound1000)


  var C12VariblesArray= []
  for (var i=0;i<nBands;i++ )
  {
    C12VariblesArray[i]=['distance'+i, 'FinalDistribution'+i]
  }

  Logger.log(C12VariblesArray)


  var C1Coefficients=[]
  for (var i=0;i<nBands;i++ )
  {
    C1Coefficients[i]=[1, 1]
  }
  Logger.log(C1Coefficients)



/// Adding fist constraint for absolute value minimization

engine.addConstraints(TargetDistribution, UpperBound1000 ,C12VariblesArray ,C1Coefficients )
//

    var C2Coefficients=[]
  for (var i=0;i<nBands;i++ )
  {
    C2Coefficients[i]=[-1,1]
  }
  Logger.log(C2Coefficients)

// Adding second constraint for absolute value minimization


engine.addConstraints(TargetDistribution, UpperBound1000,C12VariblesArray ,C2Coefficients )


// adding constraint for integrity of distribution 


  var C34VariblesArray= []
  for (var i=0;i<nBands;i++ )
  {
    C34VariblesArray[i]='FinalDistribution'+i
  }

  Logger.log(C34VariblesArray)


  var C3Coefficients = []
  for (var i=0;i<nBands;i++ )
  {
    c=1
  }

  Logger.log(C3Coefficients)                

  var c3=engine.addConstraint(1, 1)

  for (var i=0;i<nBands;i++ ){
    c3.setCoefficient('FinalDistribution'+i,1 )
  }


// adding constraint for target frequency 

// calculate total volume

var TotalVolume=0

  for (var i=0;i<nBands;i++ )
{
    TotalVolume=TotalVolume+ActualVolumesByBand[i]
}


    var C4Coefficients = []
  for (var i=0;i<nBands;i++ )
  {
    C4Coefficients[i]=TotalVolume/NumberOfPeriods/AvgDropByBand[i]
  }

  Logger.log(C4Coefficients)                  

  var c4=engine.addConstraint(TargetFrequency,TargetFrequency)
  for (var i=0;i<nBands;i++ ){
    c4.setCoefficient('FinalDistribution'+i,C4Coefficients[i] )
  }

  ////Finish setting COntraints


// start solving

var solution = engine.solve();
if (!solution.isValid()) {
  Logger.log('No solution ' + solution.getStatus());
} else {
   for (var i=0;i<nBands;i++ )
  {
    Logger.log('Value of band '+i+': ' + solution.getVariableValue('FinalDistribution'+i));
  }
}

Не могли бы вы помочь мне понять, где ошибка?

1 Ответ

0 голосов
/ 21 января 2020

Я не смотрел исходный код, но увидел в вашем описании проблему. Вы пишете:

minimize sum(Di)
with the following contraints
Di >= target_i-Xi
Di <= -(target_i-Xi)

Это выглядит неправильно. Математика обычно получается как:

min sum(i, |target(i)-X(i)|)

<=>

min sum(i, d(i))
-d(i) <= target(i)-X(i) <= d(i)

<=>

min sum(i, d(i))
d(i) >= target(i)-X(i)
d(i) >= -(target(i)-X(i))    
...