Показать сообщение отдельно
Старый 30.08.2007, 13:52
vcj вне форума Посмотреть профиль Отправить личное сообщение для vcj Посетить домашнюю страницу vcj Найти все сообщения от vcj
  № 8  
Ответить с цитированием
vcj
 
Аватар для vcj

Регистрация: Aug 2004
Адрес: дома
Сообщений: 194
Отправить сообщение для vcj с помощью ICQ
помогите разобратся почему не работает.
Код:
///VARS
var infinity = 10000;
var oppositeMove:Array = new Array();
var dx:Array = Array(0, -1,  0, 1);
var dy:Array = Array(1,  0, -1, 0);
trace(dx);
var moveDescription:Array = new Array();
var i:Number;
var j:Number;
var value1:Number;
var transpos:Number
var count:Number;
var manhattan:Number;
var newx:Number;
var newx:Number;
var x0:Number;
var y0:Number;
//---------------------

initGoalArrays();
function avto()
{ 
	 	if (isSolvable()) //если доска нерешаема
     	trace("Неразрешима!!!");
      	else if (estimate()==0) //если это уже цель
      	trace("Это уже цель");
      	else
        if (idaStar()) //делаем IDA* поиск
		 trace("!!!rabotaem!!!"+ resultString); //выводим результат
		 else trace("IDA* failed.");
}

function swap(y1, x1, y2, x2) 
{	//trace("Start swap");
    Value1 = A[y1][x1]; Value2 = A[y2][x2];
    A[y1][x1] = Value2; A[y2][x2] = Value1;
	trace("swap "+Value1+" <--> "+Value2);
  }

function isSolvable()
{
	trace("Start isSolvable");
	var a=new Array();
	for(i=1;i<16;i++)
	{
		a[i]=new Array();
	}
    
      for (i=1; i<=4; i++)
      if (i%2==0) 
	  for (j=1; j<=4; j++) 
	  {
        value1 = A[i][j];
        if (value1>0) a[count++] = value1;
      }
      else for (j=4; j>=1; j--) {
        value1 = A[i][j];
        if (value1>0) a[count++] = value1;
      }
    for (i=0; i<count-1; i++) 
	for (j=i+1; j<count; j++)
      if (a[i]>a[j]) transpos++;
	  trace("END isSolvable");
    return (transpos%2 == 1);
}
//--------------------------------------------------------------------
function initGoalArrays() {
    goalX = new Array();
    goalY = new Array();
    for (i=1; i<=15; i++) {
      goalX[i] = i % 4;
      goalY[i] = i / 4;
   // trace(i+" | "+goalX[i]+" @ "+goalY[i]);
	}
    goalX[1] = 3; goalY[1] = 3;
 }
 
function estimate()  //эвристическая оценочная функция "Манхеттеновское расстояние"
 {
	//trace("Start estimate");
	manhattan =0; 
	 for (i=1; i<=4; i++) 
	 for (j=1; j<=4; j++) 
	 {
	 	 
      value1 = A[i][j];
      if (value1>0) manhattan += Math.abs(i-goalX[value1]) + Math.abs(j-goalY[value1]);
	 // trace("A="+A[j][i]+" goalX[]= "+goalX[value1]+" goalY[]= "+goalY[value1]+" manhattan= "+manhattan);
    } 
	trace("END estimate manhattan= "+manhattan);
    return manhattan;
}
//--------------------------------------------------------------------
 //DFS с обрезанием f=g+h < deepness
  function recSearch(g,previousMove,x0,y0)
  {
	 
     h = estimate(); // h = минимум ходов к цели
    if (h == 0) return true; //если это цель - ура!
    //если то, что мы прошли (g) + то, что нам как минимум осталось (h)
    //больше допустимой глубины - выход.
    f = g + h;
	
	
    if (f > deepness) 
	{  //находим минимум стоимости среди "обрезаных" узлов
      if (minPrevIteration > f) minPrevIteration = f;
	  return false;
    }
    // делаем всевозможные ходы
    for (i=1; i<=4; i++)
    if (oppositeMove[i] != previousMove) {
	find0(); 
    
	  newx = x0 + dx[i]; 
	  newy = y0 + dy[i]; //новые координаты пустой клетки
      if ((newy<=4) and (newy>=1) and (newx<=4) and (newx>=1)) {
        swap(y0, x0, newy, newx); //двигаем пустую клетку на новое место
        		res = recSearch(g+1, i, newx, newy); //рекурсивный поиск с новой позиции
        
		swap(y0, x0, newy, newx); //возвращаем пустую клетку назад
        if (res) { //если было найдено решение
          resultString+=moveDescription[i]; //записываем этот ход
		  
          return true; //и выходим
		  
        }
      }
    }
    return false; //цели не нашли
  }

  //итерация глубины и IDA*
  function idaStar() {

    res = false;
    deepness = estimate(); //начинаем с h для начального состояния
    do {
      minPrevIteration = infinity; //инициализация для поиска минимума
      find0();
	  res = recSearch(0, -1, x0, y0);
      deepness = minPrevIteration;
    } while ((!res) and (deepness<=100)); //следующее значение «обрезающей» глубины
	//////////////////////////////////
	
    return res;
  }


Последний раз редактировалось vcj; 31.08.2007 в 11:47.