Не сходится метод наискорейшего градиентного спуска
Рядовая университется задачка, но появились трудности, с которыми долгое время не могу справиться.
Дана исходная функция (описана в коде JS) Дана точность. Необходимо найти точку минимума, используя метод наискорейшего градиентного спуска. Проблема: Метод должен сходиться к единственной точке для любого начального вектора. Мое решение существенно зависит от исходных, вводимых данных. Предположение, где может быть ошибка: Мне кажется, что-то с условием остановки, в самом условии while. HTML-код. Здесь вводим точность и координаты трехмерного начального вектора. <html> <head> <title>МНГС</title> <script src="6.js"></script> </head> <body> <h1><div id="one">Вычисление точки минимума для заданной функции (МНГС)</div></h1> <h2><div id="third"><form name="forma11"> Введите точность:<input type="text""size="20" name="e" value="0.000001" onFocus="this.value=''" onBlur="if (this.value==''){this.value='0'}"> <br> Введите начальный вектор:<br> Первая координата:<input type="text""size="10" name="x00" value="1" onFocus="this.value=''" onBlur="if (this.value==''){this.value='0'}"> <br> Вторая координата:<input type="text""size="10" name="x01" value="0" onFocus="this.value=''" onBlur="if (this.value==''){this.value='0'}"> <br> Третья координата:<input type="text""size="10" name="x02" value="0" onFocus="this.value=''" onBlur="if (this.value==''){this.value='0'}"> <br> <input type="button" value="Определить" onClick="numword(forma11);"> <input type="reset" value="Отменить"><hr> </div> </div></h2> </body> </html> Javascript - код //МНГС function f(x, y, z) { var f=2*x*x+ 3.2*y*y+4.2*z*z+x*y-y*z+x*z+x-2*y+3*z+2; // заданная квадратичная форма return f } function gradX(x, y, z) { var gradX=4*x+y+z+1; return gradX } function gradY(x, y, z) { var gradY=6.4*y+x-z-2; return gradY } function gradZ(x, y, z) { var gradZ=8.4*z+x-y+3; return gradZ } function numword(obj) { var e =1*obj.e.value; //точность из html-формы var x0 = new Array(3); //вектор из html-формы x0[0]=1*obj.x00.value; x0[1]=1*obj.x01.value; x0[2]=1*obj.x02.value; var x1 = new Array(3); var A = new Array (3); //матрица коэффициентов квадратичной формы for (var i=0; i<3; i++) { A[i]=new Array(3); } var m=0; // коэффициент "мю" из МНГС A[0][0]=2; //задание коэффициентов A[1][1]=3.2; A[2][2]=4.2; A[0][1]=A[1][0]=A[2][0]=A[0][2]=1; A[2][1]=A[1][2]=-1; var Q= new Array(3); //вектор-градиент (Ax+b) for (var j=0; j<3; j++) { Q[j]=0; } var count=0; //счетчиков шагов var grad= new Array(3); //градиент var Agrad= new Array(3); // матрица*градиент for (var j=0; j<3; j++) { Agrad[j]=0; } var fi = new Array(100000); //массив для значений функций var keyQ=0; произведение Градиент*матрица*градиент var fx1=1; //два соседних значения функции var fx0=0; while (Math.abs(fx1-fx0)>e) { for (var j=0; j<3; j++) { x1[j]=x0[j]; //присвоили новое значение } fx1 = f(x1[0],x1[1],x1[2]); grad[0]=gradX(x1[0], x1[1], x1[2]); //градиенты в новой точке grad[1]=gradY(x1[0], x1[1], x1[2]); grad[2]=gradZ(x1[0], x1[1], x1[2]); for (var i=0; i<3; i++) { for (var j=0; j<3; j++) { Agrad[i]+=A[i][j]*grad[j]; //A*градиент } } for (var j=0; j<3; j++) { keyQ+=grad[j]*Agrad[j]; градиент*А*градиент } var quatGrad=0; for (var j=0; j<3; j++) { quatGrad+=grad[j]*grad[j]; //градиент в квадрате } m=-(quatGrad)/keyQ; //коэффициент спуска for (var j=0; j<3; j++) { x0[j]=x1[j]+m*grad[j]; // новая точка } fx0 = f(x0[0],x0[1],x0[2]); //новое значение fi[count]=fx0; //записали в массив count++; } alert ("Шагов сделано: " + count); var keyF = 0; keyF = fi[count-1]; //-1 т.к. цикл делает на 1 шаг больше, и последнее значение fx1>fx0 x0[0] = x0[0].toFixed(3); x0[1] = x0[1].toFixed(3); x0[2] = x0[2].toFixed(3); keyF = keyF.toFixed(3); alert("точка минимума = [" + x0[1]+", " + x0[1] + ", " +x0[2]+"], значение функции в этой точке " + keyF); } |
Часовой пояс GMT +3, время: 02:20. |