Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 20.04.2012, 20:19
Новичок на форуме
Отправить личное сообщение для Eva O'Donnel Посмотреть профиль Найти все сообщения от Eva O'Donnel
 
Регистрация: 20.04.2012
Сообщений: 1

Не сходится метод наискорейшего градиентного спуска
Рядовая университется задачка, но появились трудности, с которыми долгое время не могу справиться.

Дана исходная функция (описана в коде 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);
	}

Последний раз редактировалось Eva O'Donnel, 23.04.2012 в 17:50. Причина: javascript.ru/formatting
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск