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

Просмотрите проблему с помощью 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.

Исправление миссицифицированной задачи

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

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)

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

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

См. также

| | | | | | |

Похожие темы