Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 20.02.2015, 21:02   #1
IvaniuS
Форумчанин
 
Аватар для IvaniuS
 
Регистрация: 16.04.2007
Сообщений: 225
По умолчанию И Снова Графы :)

Вот моя функция поиска минимального расстояния, Проблема в бесконечном цикле т.е. где-то алгоритм зацикливается и никогда не приходит в конечную точку - не понимаю почему, коменты по максимуму добавил.
Проверил и на 100% знаю что в конец можно попасть.
Проверил на небольших Остовах - работает.
Код:
var
    I,j,PFinish,minIndex,PStart,min,N,CurrNode,sum:integer;
    time:TDateTime;
    CurrPoint,pathPoint:TPoint;
    nodesCost,nodesBackLink,nodesBackLink_tmp : Array Of Integer;
    path:String;
    Finded:Boolean;
  begin
    Finded:=True;
    PStart:=ClosedBoneTo;
    PFinish:=ClosedBoneTo(X,Y,Z);
    Setlength(nodesCost,COunt);
    Setlength(nodesBackLink,COunt);
    Setlength(nodesBackLink_tmp,COunt);
    //Инициализаия, заполнение
     time:=now;
     For i := 0 to Count-1 do
     begin
        nodesCost[i] := 999999999;  // nodesCos - стоимость маршрута тп из начальной точки в данную
        nodesBackLink[i] := 100;    // nodesBackLink - индекс из какого узла мы пришли в этот узел
        nodesBackLink_tmp[i] := 100;
        //Просчитываем стоимости ребер
        CurrPoint:=FItems[I].Point;
        //print('I='+inttostr(I+1)+' : '+inttostr(CurrPoint.X)+' N='+inttostr(FItems[I].Count));
        For j:=1 To FItems[I].Count do
        begin
          CurrNode:=FItems[I].Bones(J).Bone;
          PathPoint:=FItems[CurrNode-1].Point;
          FItems[I].FBones[J].Weight:=Distance(CurrPoint.X,pathPoint.X,CurrPoint.Y,pathPoint.Y,CurrPoint.Z,pathPoint.Z);
          //print('I='+inttostr(I+1)+' -> '+inttostr(CurrNode)+'='+inttostr(FItems[I].FBones[J].Weight));
        end;
     End;
     PStart:=PStart-1;
     PFinish:=PFinish-1;
     print(FormatDateTime('hh:mm:ss.zzz',now-time));
     print(FItems[PStart].Name+'('+inttostr(PStart)+')');
     print(FItems[PFinish].Name+'('+inttostr(PFinish)+')');
     nodesCost[PStart] := 0;     // общая стоимость пути в начальной точке равна нулю
     nodesBackLink[PStart] := PStart;   // в начальную точку мы попали из начальной точки :)
     N:=0;
     While nodesBackLink[PFinish] = 100 do    // если в конечной точке обратный индекс не константа 100, то мы в конечную точку откуда-то пришли
     //For N:=0 to Count-1 do
     Begin
        For i:=0 To Count-1 do
          If nodesBackLink[i] < 100 Then    // проверяем все узлы где мы уже побывали
          begin
            For j:=1 To FItems[I].Count do
              //If FItems[I].FBones[J].Weight > 0 Then    // рассматриваем все узлы куда есть переход из узла i
              Begin
                CurrNode:=FItems[I].Bones(J).Bone-1;
                sum := nodesCost[i] + FItems[I].FBones[J].Weight;
                If nodesCost[CurrNode] > sum Then   // оцениваем непосещённые узлы
                begin
                  nodesCost[CurrNode] := sum;
                  nodesBackLink_tmp[CurrNode] := i; // и запоминаем откуда мы пришли в этот узел с такой оценкой
                End;
              End;
              break;
            end;
        min := 999999999;
        For i:=0 To Count-1 do
          If nodesBackLink[i] <> nodesBackLink_tmp[i] Then // рассматриваем узлы, оценка которых изменилась
             If nodesCost[i] < min Then           // и ищем среди них узел с минимальной оценкой
             Begin
                min := nodesCost[i];
                minIndex := i;
             End;
        nodesBackLink[minIndex] := nodesBackLink_tmp[minIndex];//Записываем откуда пришли
        N:=N+1;
        //if nodesBackLink[PFinish] <> 100 then Break;//print(N);
     End;
     print(FormatDateTime('hh:mm:ss.zzz',now-time));
     //Построение обратного маршрута
     If N<SQRT(Count) then
     begin
     path := '';
     i := PFinish;
     while (i<>PStart) do
     begin
        path := ' -> ' + FItems[i].Name+'('+inttostr(I)+')'+ path;
        i := nodesBackLink[i];
     end;  
     path := FItems[PStart].Name+'('+inttostr(I)+')'+ path;
     end;
  end;
IvaniuS вне форума Ответить с цитированием
Старый 21.02.2015, 00:01   #2
IvaniuS
Форумчанин
 
Аватар для IvaniuS
 
Регистрация: 16.04.2007
Сообщений: 225
По умолчанию

Может кому пригодится - я нашел сам ошибку
Нужно было break; -убрать в середине кода, они не проходился по всем ребрам
IvaniuS вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Снова я и снова геморрой, только уже с многопоточностью FleXik Общие вопросы Delphi 26 07.07.2013 16:48
графы Evelin_18 Паскаль, Turbo Pascal, PascalABC.NET 0 17.02.2013 17:30
Графы DTroy Помощь студентам 0 24.11.2011 20:28
Графы в С++ lilu777 C++ Builder 3 26.05.2011 00:59
MDIChild снова и снова... Siber_Dec Общие вопросы Delphi 2 13.12.2009 03:24