exponenta event banner

Просмотр или изменение проблем оптимизации

Просмотреть проблему с помощью show или write

После создания задачи оптимизации можно просмотреть ее формулировку с помощью show. Для решения больших проблем используйте write вместо этого. Например,

prob = optimproblem;
x = optimvar('x',2,'LowerBound',0);
prob.Objective = x(1) - 2*x(2);
prob.Constraints.cons1 = x(1) + 2*x(2) <= 4;
prob.Constraints.cons2 = -x(1) + x(2) <= 1;

show(prob)
  OptimizationProblem : 

	Solve for:
       x

	minimize :
       x(1) - 2*x(2)


	subject to cons1:
       x(1) + 2*x(2) <= 4

	subject to cons2:
       -x(1) + x(2) <= 1

	variable bounds:
       0 <= x(1)
       0 <= x(2)

В этом обзоре показаны основные элементы задачи, такие как необходимость минимизации или максимизации задачи, а также границы переменных. В обзоре показаны имена индексов, если таковые имеются, используемые в переменных. Проверка не показывает, являются ли переменные целочисленными.

Изменить решатель или опции по умолчанию

Чтобы попытаться улучшить решение или скорость решения, проверьте и измените решатель или опции по умолчанию.

Чтобы увидеть решатель по умолчанию и опции, используйте optimoptions(prob). Например,

rng default
x = optimvar('x',3,'LowerBound',0);
expr = sum((rand(3,1).*x).^2);
prob = optimproblem('Objective',expr);
prob.Constraints.lincon = sum(sum(randn(size(x)).*x)) <= randn;
options = optimoptions(prob)
options = 

  lsqlin options:

   Options used by current Algorithm ('interior-point'):
   (Other available algorithms: 'trust-region-reflective')

   Set properties:
     No options set.

   Default properties:
              Algorithm: 'interior-point'
    ConstraintTolerance: 1.0000e-08
                Display: 'final'
           LinearSolver: 'auto'
          MaxIterations: 200
    OptimalityTolerance: 1.0000e-08
          StepTolerance: 1.0000e-12

   Show options not used by current Algorithm ('interior-point')

Решатель по умолчанию для этой проблемы: lsqlinи вы можете увидеть параметры по умолчанию.

Чтобы изменить решатель, установите 'Solver' пара имя-значение в solve. Чтобы просмотреть применимые опции для другого решателя, используйте optimoptions для передачи текущих опций в другой решатель. Например, продолжая проблему,

options = optimoptions('quadprog',options)
options = 

  quadprog options:

   Options used by current Algorithm ('interior-point-convex'):
   (Other available algorithms: 'trust-region-reflective')

   Set properties:
    ConstraintTolerance: 1.0000e-08
          MaxIterations: 200
    OptimalityTolerance: 1.0000e-08
          StepTolerance: 1.0000e-12

   Default properties:
              Algorithm: 'interior-point-convex'
                Display: 'final'
           LinearSolver: 'auto'

   Show options not used by current Algorithm ('interior-point-convex')

Чтобы изменить параметры, используйте optimoptions или точечная нотация для задания опций и передачи опций в solve в 'Options' пара имя-значение. См. раздел Общие параметры: настройка и устранение неполадок. Продолжая пример,

options.Display = 'iter';
sol = solve(prob,'Options',options,'Solver','quadprog');
 Iter            Fval  Primal Infeas    Dual Infeas  Complementarity  
    0    1.500359e+00   3.068423e-01   2.275437e+00     2.500000e-01  
    1    1.728717e-01   0.000000e+00   7.719860e-03     3.637874e-02  
    2    2.604108e-02   0.000000e+00   0.000000e+00     5.245260e-03  
    3    7.822161e-03   0.000000e+00   2.775558e-17     1.407915e-03  
    4    2.909218e-03   0.000000e+00   6.938894e-18     2.070784e-04  
    5    1.931264e-03   0.000000e+00   1.734723e-18     2.907724e-05  
    6    1.797508e-03   0.000000e+00   2.602085e-18     4.083167e-06  
    7    1.775398e-03   0.000000e+00   4.336809e-19     5.102453e-07  
    8    1.772971e-03   0.000000e+00   2.632684e-19     3.064243e-08  
    9    1.772848e-03   0.000000e+00   5.228973e-19     4.371356e-11  

Minimum found that satisfies the constraints.

Optimization completed because the objective function is non-decreasing in 
feasible directions, to within the value of the optimality tolerance,
and constraints are satisfied to within the value of the constraint tolerance.

Исправить неполадку с ошибками

Чтобы убедиться в правильности вашей проблемы, просмотрите все ее аспекты. Например, создайте задачу оптимизации для решения проблемы Судоку, запустив этот сценарий.

x = optimvar('x',9,9,9,'LowerBound',0,'UpperBound',1);
cons1 = sum(x,1) == 1;
cons2 = sum(x,2) == 1;
cons3 = sum(x,3) == 1;
prob = optimproblem;
prob.Constraints.cons1 = cons1;
prob.Constraints.cons2 = cons2;
prob.Constraints.cons3 = cons3;
mul = ones(1,1,9);
mul = cumsum(mul,3);
prob.Objective = sum(sum(sum(x,1),2).*mul);
cons4 = optimconstr(3,3,9);

for u = 1:3
    for v = 1:3
        arr = x(3*(u-1)+1:3*(u-1)+3,3*(v-1)+1:3*(v-1)+3,:);
        cons4(u,v,:) = sum(sum(arr,1),2) <= ones(1,1,9);
    end
end
prob.Constraints.cons4 = cons4;

B = [1,2,2;
1,5,3;
1,8,4;
2,1,6;
2,9,3;
3,3,4;
3,7,5;
4,4,8;
4,6,6;
5,1,8;
5,5,1;
5,9,6;
6,4,7;
6,6,5;
7,3,7;
7,7,6;
8,1,4;
8,9,8;
9,2,3;
9,5,4;
9,8,2];

for u = 1:size(B,1)
    x.LowerBound(B(u,1),B(u,1),B(u,1)) = 1;
end

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

x
x = 

  9×9×9 OptimizationVariable array with properties:

 Array-wide properties:
          Name: 'x'
          Type: 'continuous'
    IndexNames: {{}  {}  {}}

 Elementwise properties:
    LowerBound: [9×9×9 double]
    UpperBound: [9×9×9 double]

See variables with show.
See bounds with showbounds.

Этот экран показывает, что тип переменной является непрерывным. Переменная должна быть целочисленной. Измените тип.

x.Type = 'integer'
x = 

  9×9×9 OptimizationVariable array with properties:

 Array-wide properties:
          Name: 'x'
          Type: 'integer'
    IndexNames: {{}  {}  {}}

 Elementwise properties:
    LowerBound: [9×9×9 double]
    UpperBound: [9×9×9 double]

See variables with show.
See bounds with showbounds.

Проверьте границы. Должен быть 21 нижний предел со значением 1, по одному для каждой строки B. Поскольку x - это большой массив, запишите границы в файл, а не отображайте их в командной строке.

writebounds(x,'xbounds.txt')

Поиск в файле xbounds.txt для всех экземпляров 1 <=. Только девять нижних границ, имеющих значение 1, в переменных x(1,1,1), x(2,2,2), …, x(9,9,9). Чтобы выяснить это несоответствие, проверьте код, в котором установлены нижние границы:

for u = 1:size(B,1)
    x.LowerBound(B(u,1),B(u,1),B(u,1)) = 1;
end

Линия внутри петли должна говорить x.LowerBound(B(u,1),B(u,2),B(u,3)) = 1;. Сбросьте все нижние границы на ноль, а затем запустите исправленный код.

x.LowerBound = 0;
for u = 1:size(B,1)
    x.LowerBound(B(u,1),B(u,2),B(u,3)) = 1;
end
writebounds(x,'xbounds.txt')

xbounds.txt теперь имеет правильное число записей нижней границы, равное 1.

Осмотрите целевую функцию. Выражение целевой функции велико, поэтому запишите выражение в файл.

write(prob.Objective,'objectivedescription.txt')
    x(1, 1, 1) + x(2, 1, 1) + x(3, 1, 1) + x(4, 1, 1) + x(5, 1, 1) + x(6, 1, 1) + x(7, 1, 1) + x(8,
    1, 1) + x(9, 1, 1) + x(1, 2, 1) + x(2, 2, 1) + x(3, 2, 1) + x(4, 2, 1) + x(5, 2, 1) + x(6, 2,
    ...
    9*x(7, 8, 9) + 9*x(8, 8, 9) + 9*x(9, 8, 9) + 9*x(1, 9, 9) + 9*x(2, 9, 9) + 9*x(3, 9, 9) +
    9*x(4, 9, 9) + 9*x(5, 9, 9) + 9*x(6, 9, 9) + 9*x(7, 9, 9) + 9*x(8, 9, 9) + 9*x(9, 9, 9)

Объективная функция выглядит разумно, потому что это сумма скалярных выражений.

Запишите ограничения в файлы для проверки.

write(prob.Constraints.cons1,'cons1.txt')
write(prob.Constraints.cons2,'cons2.txt')
write(prob.Constraints.cons3,'cons3.txt')
write(prob.Constraints.cons4,'cons4.txt')

Обзор cons4.txt и вы видите ошибку. Все ограничения заключаются в неравенстве, а не в равенстве. Исправьте строки кода, создающие это ограничение, и поместите исправленное ограничение в проблему.

cons4 = optimconstr(3,3,9);

for u = 1:3
    for v = 1:3
        arr = x(3*(u-1)+1:3*(u-1)+3,3*(v-1)+1:3*(v-1)+3,:);
        cons4(u,v,:) = sum(sum(arr,1),2) == ones(1,1,9);
    end
end
prob.Constraints.cons4 = cons4;

После этих изменений можно успешно решить проблему.

sol = solve(prob);
x = round(sol.x);
y = ones(size(x));
for k = 2:9
    y(:,:,k) = k; % multiplier for each depth k
end
S = x.*y; % multiply each entry by its depth
S = sum(S,3); % S is 9-by-9 and holds the solved puzzle

drawSudoku(S)

Повторяющееся имя переменной

При повторном создании переменной, но уже имеющем выражение, использующее старую переменную, можно получить ошибки при включении выражений в одну задачу. См. раздел Переменные с недопустимыми повторяющимися именами.

См. также

| | | | | | |

Связанные темы