Путь в марице
От: mafiya  
Дата: 03.02.03 09:21
Оценка:
Есть матрица размером s где s>=5
Генерирую ее следующим образом

label
  1;
const
   s=10;
var
   m : array[1..s,1..s] of integer;
   i : integer;
   j : integer;
   r : integer;
   ss : string;
begin
  randomize;
  memo1.lines.Clear;
  for i:=1 to s do
  begin
    ss:='';
    for j:=1 to s do
    begin
1:    if random(2)=0
        then r:=0
        else r:=random(10);
      if r=1 then goto 1;
      m[i,j]:=r;
      ss:=ss+inttostr(m[i,j])+' ';
    end;
    memo1.Lines.add(ss);
  end;
end;


Далее задаем координаты старта и координаты финиша. И нужно проставить короткий путь цифрой 1 от старта к финишу. Двигаться можно только только там где 0. Если пути нет то облом.
Re: Путь в матрице
От: Кодт Россия  
Дата: 03.02.03 10:51
Оценка: 30 (1)
Здравствуйте, mafiya, Вы писали:

M>Есть матрица размером s где s>=5

M>Далее задаем координаты старта и координаты финиша. И нужно проставить короткий путь цифрой 1 от старта к финишу. Двигаться можно только только там где 0. Если пути нет то облом.

Волновой алгоритм.

Заведем карту, где в каждой точке будет расстояние от старта. А также нам пригодится список точек фронта волны (фронт — это совокупность точек с одинаковым расстоянием от старта).
type
  coordT = 1..s;
  coord2T = record x,y: coordT end;
  indexT = 1..s*s;

  rangeT = -1..s*s; { -1 -- это метка "не рассчитан" }
var
  range: array[coordT,coordT] of rangeT; { расстояние от старта }
  rx,ry: coordT;
  waverange:

  wavefront: array[indexT] of coord2T; { волновой фронт }
  wave1, wave2, wave3, w: indexT;
  { начало текущего фронта, конец текущего/начало следующего, конец следующего фронта }
  { а также точка, которую рассматриваем сейчас }

Очистим карту и начнем:
for rx := 1 to s do for ry := 1 to s do range[x,y] := -1;
range[1,1] := 0;

with wavefront[1] do begin x := 1; y := 1; end;
wave1 := 1; wave2 := 2; wave3 := 2;
waverange := 1; { следующий фронт }

Далее будем перебирать точки текущего фронта, строя следующий фронт
for w := wave1 to wave2-1 do
begin
  with wavefront[w] do
  begin
    { перебираем варианты }
    if x>1 then examine(x-1,y);
    if x<s then examine(x+1,y);
    if y>1 then examine(x,y-1);
    if y<s then examine(x,y+1);
  end;
end;
{ наконец, перейдем к следующему фронту }
wave1 := wave2;
wave2 := wave3;
waverange := waverange+1;

где процедура examine
procedure examine(xx,yy: coordT)
begin
  if m[xx,yy] = 0 { если ячейка свободна }
  and range[xx,yy] < 0 { и туда мы еще не ходили }
  then begin
    { пометим на карте }
    range[xx,yy] := waverange; { расстояние следующего фронта }
    { добавим в список }
    with wavefront[wave3] do begin
      x := xx; y := yy;
    end;
    wave3 := wave3+1;
  end;
end;

Будем так делать, пока не достигнем точки финиша.
Далее — находим путь по карте расстояний от финиша к старту: каждая следующая точка имеет расстояние на 1 меньшее текущей.
(Это ты уже — сам).
Перекуём баги на фичи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.