Есть два способа приблизиться к этому:
- Из метода, который вы разработали в своем посте. Произвольно сгенерируйте
x1
и x2
и убедитесь, что vt < v1*x1 + v2*x2
, а затем найдите x3
.
- Сформулируйте это в виде линейной программы. Линейная программа в основном решает систему уравнений, которые подчиняются ограничениям неравенства или равенства. Другими словами:
![blah](https://upload.wikimedia.org/math/5/c/e/5ce84c5828275c1c7750f2b622c0049e.png)
Таким образом, мы можем перевести вашу проблему в задачу линейного программирования. Утверждение «максимизировать» — это то, что известно как целевая функция — общая цель того, чего вы пытаетесь достичь. В задачах линейного программирования мы пытаемся минимизировать или максимизировать эту цель. Для этого мы должны удовлетворить неравенства, наблюдаемые в условии subject to. Обычно эта программа представлена в канонической форме, поэтому ограничения на каждую переменную должны быть положительными.
Условие максимизации может быть произвольным, поскольку вас не волнует цель. Вы просто заботитесь о любом решении. Вся эта парадигма может быть достигнута с помощью linprog
в MATLAB. С чем вам следует быть осторожным, так это с тем, как указывается linprog
. На самом деле цель минимизирована, а не максимизирована. Однако условия те же, за исключением того, что все переменные должны быть положительными. Нам придется кодировать это в себе.
С точки зрения произвольной цели мы можем просто сделать x1 + x2 + x3
. Таким образом, c = [1 1 1]
. Наше ограничение равенства: v1*x1 + v2*x2 + v3*x3 = vt
. Мы также должны убедиться, что x
положительное. Чтобы закодировать это, мы можем выбрать небольшую константу, чтобы все значения x
были больше этого значения. Прямо сейчас linprog
не поддерживает строгое неравенство (т. е. x > 0
), поэтому нам нужно обойти это, проделав этот трюк. Кроме того, чтобы гарантировать, что значения положительны, linprog
предполагает, что Ax <= b
. Таким образом, общий трюк, который используется, состоит в том, чтобы отрицать неравенство x >= 0
, и поэтому это эквивалентно -x <= 0
. Чтобы гарантировать, что значения не равны нулю, мы на самом деле сделали бы: -x <= -eps
, где eps
— небольшая константа. Однако, когда я проводил эксперименты, делая это таким образом, две переменные оказывались одним и тем же решением. Таким образом, я бы порекомендовал нам генерировать хорошие решения, которые каждый раз случайны, давайте нарисуем b
из равномерного случайного распределения, как вы сказали. Это даст нам отправную точку каждый раз, когда мы хотим решить эту проблему.
Следовательно, наши неравенства:
-x1 <= -rand1
-x2 <= -rand2
-x3 <= -rand3
rand1, rand2, rand3
— это три случайно сгенерированных числа в диапазоне от 0
до 1
. В матричной форме это:
[-1 0 0][x1] [-rand1]
[0 -1 0][x2] <= [-rand2]
[0 0 -1][x3] [-rand3]
Наконец, наше ограничение равенства из предыдущего:
[v1 v2 v3][x1] [vt]
[x2] =
[x3]
Теперь, чтобы использовать linprog
, вы должны сделать это:
X = linprog(c, A, b, Aeq, beq);
c
— это массив коэффициентов, определенный для цели. В этом случае он будет определен как [1 1 1]
, A
и b
— это матрица и вектор-столбец, определенные для ограничений неравенства, а Aeq
и beq
— это матрица и вектор-столбец, определенные для ограничений равенства. Таким образом, X
даст нам решение после того, как linprog
сходится (т.е. x1, x2, x3
). Таким образом, вы бы сделали это:
A = -eye(3,3);
b = -rand(3,1);
Aeq = [v1 v2 v3];
beq = vt;
c = [1 1 1];
X = linprog(c, A, b, Aeq, beq);
В качестве примера предположим v1 = 0.33, v2 = 0.5, v3 = 0.2
и vt = 2.5
. Следовательно:
rng(123); %// Set seed for reproducibility
v1 = 0.33; v2 = 0.5; v3 = 0.2;
vt = 2.5;
A = -eye(3,3);
b = -rand(3,1);
Aeq = [v1 v2 v3];
beq = vt;
c = [1 1 1];
X = linprog(c, A, b, Aeq, beq);
Я получил:
X =
0.6964
4.4495
0.2268
Чтобы убедиться, что это равно vt
, мы должны сделать:
s = Aeq*X
s = 2.5000
Вышеупомянутое просто делает v1*x1 + v2*x2 + v3*x3
. Это вычисляется в форме скалярного произведения, чтобы упростить задачу, поскольку X
— это вектор-столбец, а v1, v2, v3
уже задано в Aeq
и является вектором-строкой.
Таким образом, любой вариант хорош, но, по крайней мере, с linprog
вам не нужно продолжать цикл, пока вы не добьетесь выполнения этого условия!
Небольшое предостережение
Одно небольшое предостережение, которое я забыл упомянуть в приведенном выше подходе, заключается в том, что вам нужно убедиться, что vt >= v1*rand1 + v2*rand2 + v3*rand3
обеспечивает сходимость. Поскольку вы сказали, что v1,v2,v3
ограничены между 0
и 1
, наихудший случай, когда все v1,v2,v3
равны 1. Таким образом, нам действительно нужно убедиться, что vt > rand1 + rand2 + rand3
. Если это не, просто возьмите каждое значение rand1, rand2, rand3
и разделите на (rand1 + rand2 + rand3) / vt
. Таким образом, это гарантирует, что общая сумма будет равна vt
, предполагая, что все веса равны 1, и это позволит линейной программе сходиться должным образом.
Если вы этого не сделаете, решение не сойдется из-за условий неравенства для b
, и вы не получите правильного ответа. Просто пища для размышлений! Таким образом, сделайте это для b
перед запуском linprog
if sum(-b) > vt
b = b ./ (sum(-b) / vt);
end
Удачи!
person
rayryeng
schedule
16.07.2014
x1
иx2
и найтиx3
.x1
иx2
могут быть установлены вами или сгенерированы случайным образом. Если вы генерируете их случайным образом, вы должны убедиться, чтоvt
меньшеv1*x1 + v2*x2
. Вы также можете использоватьlinprog
и превратить это в линейную программу и решить для нее. Имеет ли значение, еслиx1
иx2
совпадают? - person rayryeng   schedule 16.07.2014linprog
. Я напишу вам ответ. - person rayryeng   schedule 16.07.2014