Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.63/40: Рейтинг темы: голосов - 40, средняя оценка - 4.63
0 / 0 / 0
Регистрация: 05.11.2011
Сообщений: 44

Найти самый короткий путь от точки до точки в матрице

09.10.2012, 21:29. Показов 7812. Ответов 12
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Народ, помогите...
Такая задача, имеется массив символов(char arr[][]) в котором в рандомных местах установлены препятствия(к примеру символы '*') и имеем 2 точки, нужно найти самый короткий путь от 1й точки ко 2й, двигаться можно только по верикали или горизонтали(двигаться по диагонали нельзя).
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
09.10.2012, 21:29
Ответы с готовыми решениями:

Отсортировать массив, который ищет самый короткий путь до точки
Дорогие форумчане, прошу вашей помощи. Пытаюсь написать алгоритм для монстра в игре. Алгоритм высчитывает самый короткий путь до...

Лабиринт, найти самый короткий путь
Лабиринт задан квадратной матрицей случайных чисел. Непроходимые клетки - 1, проходимые - 0. Начальное положение путника на нулевой строке,...

Лабиринт. Найти самый короткий путь от входа в выходу
Я написал программу для обработки таблицы. Я представляю таблицу в качестве лабиринта. Ячейка заполненная 0 означает, что по этой клетки...

12
0 / 0 / 0
Регистрация: 08.10.2012
Сообщений: 3
10.10.2012, 00:15
используй очередь
0
 Аватар для I.M.
576 / 559 / 47
Регистрация: 16.12.2011
Сообщений: 1,389
10.10.2012, 00:26
Вроде бы это динамическое программирование
вам для чего это надо - это задачка с какого-то сайта и есть ограничения по времени или это задачка из универа? если второе, то к какой теме это приурочено? случаем, не к рекурсии?
0
0 / 0 / 0
Регистрация: 05.11.2011
Сообщений: 44
10.10.2012, 10:15  [ТС]
Второе, не важно к какой теме, с++ мы давно прошли(по крайней мере основы) задача заключается в следующем: создать класс с закрытым членом-динамическим 2хмерным массивом символов, конструктор имеет 2 аргумента(стороны массива), есть еще несколько открытых функций: показать массив, поставить на указанное место препятствие, назначить те самые 2 точки ну и найти самый короткий путь между ними, обходя, естественно, препятствия...Не важно что использовать перезагрузку функций, рекурсию, лямбда-выражения и т.д. мы давно прошли...Все сделал за 20 минут, но вот с алгоритмом поиска кратчайшего пути не могу справится вот уже 3 недели
0
 Аватар для I.M.
576 / 559 / 47
Регистрация: 16.12.2011
Сообщений: 1,389
10.10.2012, 11:08
Я сам не большой знаток динам/программирования. На форуме есть ребята, которые в этом разбираются гораздо лучше. Если увидят вашу тему, то наверняка выдадут вам оптимальный алгоритм)
А я сам могу предложить самое простое решение (но и самое медленное) - рекурсия. Или разворачиваете свой массив как граф и ищите кратчайший путь уже в графе.
0
0 / 0 / 0
Регистрация: 05.11.2011
Сообщений: 44
10.10.2012, 11:48  [ТС]
Совет про граф слышу не в первый раз, но я с графами раньше никогда не работал, что же касается рекурсии, то я пробывал, но всегда нахожу какой-то косяк в алгоритме, пробывал даже вычислить все возможные пути и выбрать самый короткий из них, тоже ничего путного не вышло
0
0 / 0 / 0
Регистрация: 08.10.2012
Сообщений: 3
10.10.2012, 12:23
я же писал это примитивная очередь. (Поищи на википедии есть, и ещё...)

добавил 1 точку в очередь она нашла вторую. Теперь коротко расскажу как: В общем добавил первую точку. В каком то массиве записал это. Увеличил счётчик начала(на вики как start описана) А потом пока start!=finish берёшь ту предыдущую точку и пытаешься идти в 4 стороны, куда пройти можно добавяешь в массив. И так дальше пока не найдёшь вторую точку. Кароче по-гугли код там предельно понятно.

что касается динамики... она тут подольше будет. Я б писал такую. Та точка в которой мы стоим взял бы за 1 шаг, на следующем проходе по массиву если в соседней точке 1 и в данную точку можно пройти то в данной клетке массива 2, и т.д. В итоге в конце в конечной точке будет тоже число за которое ты дошёл до этой точки. Но динамика гораздо медленнее тут... Это типичная задача на ОЧЕРЕДЬ!
0
 Аватар для Кот Ангенс
320 / 270 / 128
Регистрация: 24.05.2012
Сообщений: 629
10.10.2012, 13:42
Реализовал алгоритм Дейкстры.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#include <cstdlib>
#include <vector>
 
typedef unsigned /*short*/ dist_t;
typedef unsigned short fsize_t;
 
struct Field {
    dist_t dist;
    bool pathable;
 
    Field() {
        dist = dist_t(-1);//Максимальное значение
        pathable = true;
    }
};
 
class Graph {
    Field* f;
    fsize_t w, h;
 
protected:
    Field& F(fsize_t x, fsize_t y) {
        return f[x + y * w];
    }
 
    void SetDist(fsize_t x, fsize_t y, dist_t d) {
        if (d < F(x, y).dist) {
            F(x, y).dist = d;
            if (x && F(x - 1, y).pathable)
                SetDist(x - 1, y, d + 1);
            if (x < w - 1 && F(x + 1, y).pathable)
                SetDist(x + 1, y, d + 1);
            if (y && F(x, y - 1).pathable)
                SetDist(x, y - 1, d + 1);
            if (y < h - 1 && F(x, y + 1).pathable)
                SetDist(x, y + 1, d + 1);
        }
    }
 
public:
    Graph() {
        f = NULL;
        w = h = 0;
    }
 
    Graph(fsize_t width, fsize_t height) {
        f = new Field[width * height];
        w = width;
        h = height;
    }
 
    ~Graph() { delete[ ] f; }
 
    void Resize(fsize_t width, fsize_t height) {
        delete[ ] f;
        f = new Field[width * height];
        w = width;
        h = height;
    }
 
    void SetPathable(fsize_t x, fsize_t y, bool state) {
        F(x, y).pathable = state;
    }
 
    /*
        0 - вверх
        1 - влево
        2 - вправо
        3 - вниз
    */
 
    std::vector<char> Find(fsize_t x0, fsize_t y0, fsize_t x1, fsize_t y1) {
        SetDist(x0, y0, 0);
        dist_t i = F(x1, y1).dist;
        std::vector<char> v(i);
        //Идем в обратном направлении, от конца к началу
        while (i--)
            if (y1 && F(x1, y1 - 1).dist < F(x1, y1).dist) {
                y1--;
                v[i] = 3;
            } else if (x1 && F(x1 - 1, y1).dist < F(x1, y1).dist) {
                x1--;
                v[i] = 2;
            } else if (x1 < w - 1 && F(x1 + 1, y1).dist < F(x1, y1).dist) {
                x1++;
                v[i] = 1;
            } else {
                y1++;
                v[i] = 0;
            }
        return v;
    }
};
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <algorithm>
#include <iostream>
#include <vector>
 
using namespace std;
 
void PrintPath(char d) {
    switch (d) {
        case 0: cout << "up\n"; break;
        case 1: cout << "left\n"; break;
        case 2: cout << "right\n"; break;
        default: cout << "down\n";
    }
}
 
int main() {
    /*
          0 1 2
        0 @ # $
        1 . # .
        2 . . .
    */
    Graph g(3, 3);
    g.SetPathable(1, 0, false);
    g.SetPathable(1, 1, false);
    vector<char> v = g.Find(0, 0, 2, 0);
    for_each(v.begin(), v.end(), PrintPath);
    cout << endl;
    /*
          0 1 2 3
        0 $ # . .
        1 . . # .
        2 # . . .
        3 . # . #
        4 @ . . .
    */
    g.Resize(4, 5);
    g.SetPathable(1, 0, false);
    g.SetPathable(2, 1, false);
    g.SetPathable(0, 2, false);
    g.SetPathable(1, 3, false);
    g.SetPathable(3, 3, false);
    v = g.Find(0, 4, 0, 0);
    for_each(v.begin(), v.end(), PrintPath);
    cin.get();
}
Миниатюры
Найти самый короткий путь от точки до точки в матрице  
1
 Аватар для Кот Ангенс
320 / 270 / 128
Регистрация: 24.05.2012
Сообщений: 629
10.10.2012, 14:01
Кстати, можно заменить хвостовую рекурсию циклом:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void SetDist(fsize_t x, fsize_t y, dist_t d) {
    while (d < F(x, y).dist) {
        F(x, y).dist = d;
        if (x && F(x - 1, y).pathable)
            SetDist(x - 1, y, d + 1);
        if (x < w - 1 && F(x + 1, y).pathable)
            SetDist(x + 1, y, d + 1);
        if (y && F(x, y - 1).pathable)
            SetDist(x, y - 1, d + 1);
        if (!(y < h - 1 && F(x, y + 1).pathable))
            return;
        y++;
        d++;
    }
}
1
0 / 0 / 0
Регистрация: 05.11.2011
Сообщений: 44
10.10.2012, 15:11  [ТС]
Кот Ангенс, спасибо большое, осталось все это понять и переварить
0
Эксперт С++
 Аватар для valeriikozlov
4728 / 2549 / 757
Регистрация: 18.08.2009
Сообщений: 4,568
10.10.2012, 16:30
Цитата Сообщение от actium Посмотреть сообщение
Это типичная задача на ОЧЕРЕДЬ!
абсолютно верно.
0
0 / 0 / 0
Регистрация: 05.11.2011
Сообщений: 44
10.10.2012, 19:22  [ТС]
Про очереди почитал на вики, обьяснения довольно туманны, а примеров реализации алгоритма на каком-нибудь языке программирования вообще нет, вариант с графами хотя бы понятен
0
0 / 0 / 0
Регистрация: 08.10.2012
Сообщений: 3
10.10.2012, 22:43
эм.... могу на Pascal дать! На С++ переделать просто. Ну в принципе на вот, если разберёшься норм, нет то потом на с++ переписать могу... хотя блин ладно щас напишу:
блин долго напишу вот так псевдокодом почти...

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <stdio.h>
 
char a[10][10];
const maxQ=100;
int q1,q2,qx[maxQ],qy[maxQ],qz[maxQ],ans=-1,x1,y1,x2,y2;
 
int add(int y, int x, int z){   // y,x - координаты рассматриваемой точки, z - шаг на котором до неё дошли.
    if (a[y,x]!="*") return 0;  // если по клетке пойти нельзя (преграда) выход из процедуры
    a[y][x]='#';     // мусорим клетку чтоб не пойти второй раз
    qx[q1]=x;
    qy[q1]=y;        // запоминаем клетку и с какого раза пришли
    qz[q1]=z;
    if (q1>maxQ) q1=0;     // опять же зацикливание... внизу писал
    if( (y==y2)&(x==x2)){  // проверка если вдруг это клетка куда надо прийти то запоминаем на каком щаге и выходим.
        q1=q2+1;
        ans=z;
    }
    return 1;
}
 
void main(){
//ну тут чтение размера массива, массив, стартовую точку (y1,x1) и конечную (y2,x2)
    q1=0; q2=0;
    add(y1,x1,0);   
    while (q1!=q2){  //пока начало очереди не дошло до конца
        x=qx[q2];
        y=qx[q2];            // присваиваем точку из очереди
        z=qz[q2];
        add(y-1,x,z+1);     // попытка пойти во все 4 направления вверх, вниз, влево, вправо
        add(y+1,x,z+1);
        add(y,x-1,z+1);
        add(y,x+1,z+1);
        q2++;           // отодвигаем конец
        if (q2>maxQ) q2=0;   // зацикливание очереди, в принципе если не разбираешься можно опустить.
    }
    printf("%d",ans);
}
P.S: по "*" можно ходить по "#" нельзя!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
10.10.2012, 22:43
Помогаю со студенческими работами здесь

Найти самый короткий путь от левого столбца массива к правому
Дан двумерный числовой массив размером N1xN2. Найти такой путь от левого столбца массива к правому, чтобы сумма чисел по данному пути...

Массив, заполненный 1 и 0. Найти путь, состоящий из нулей, от точки до точки.
Доброго времени суток всем! Вот такая задача, ничего не могу даже сообразить по ней, подкиньте идеи, пожалуйста (ну или код в C++ )

Найти самый короткий путь из первой вершины в последнюю по счету в заданном графе методом динамического программирования
Всем добрый день! У меня вопрос - найти кротчайший путь из первой вершины в последнюю по счету в заданном графе методом динамического...

Самый короткий путь алгоритм Флойда
Не все тесты проходит, где ошибка? Дан ориентированный взвешенный полный граф, рёбрам которого приписаны некоторые веса (длины). Веса...

Выбрать самый короткий путь в задаче о шахматах
Привет,нам дали такую задачу, только вот мозг не додумывается до решения. Как бы понятно,что нужно использовать волновой алгоритм, но как...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Новые блоги и статьи
Знаешь почему 90% людей редко бывают счастливыми?
kumehtar 14.04.2026
Потому что они ждут. Ждут выходных, ждут отпуска, ждут удачного момента. . . а удачный момент так и не приходит.
Фиксация колонок в отчете СКД
Maks 14.04.2026
Фиксация колонок в СКД отчета типа Таблица. Задача: зафиксировать три левых колонки в отчете. Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка) / / . . .
Настройки VS Code
Loafer 13.04.2026
{ "cmake. configureOnOpen": false, "diffEditor. ignoreTrimWhitespace": true, "editor. guides. bracketPairs": "active", "extensions. ignoreRecommendations": true, . . .
Оптимизация кода на разграничение прав доступа к элементам формы
Maks 13.04.2026
Алгоритм из решения ниже реализован на нетиповом документе, разработанного в конфигурации КА2. Задачи, как таковой, поставлено не было, проделанное ниже исключительно моя инициатива. Было так:. . .
Контроль заполнения и очистка дат в зависимости от значения перечислений
Maks 12.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: реализовать контроль корректности заполнения дат назначения. . .
Архитектура слоя интернета для сервера-слоя.
Hrethgir 11.04.2026
В продолжение https:/ / www. cyberforum. ru/ blogs/ 223907/ 10860. html Знаешь что я подумал? Раз мы все источники пишем в голове ветки, то ничего не мешает добавить в голову такой источник, который сам. . .
Подстановка значения реквизита справочника в табличную часть документа
Maks 10.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача №1: при указании работ (справочник РаботыПоРемонтуСпецтехники),. . .
Очистка реквизитов документа при копировании
Maks 09.04.2026
Алгоритм из решения ниже применим как для типовых, так и для нетиповых документов на самых различных конфигурациях. Задача: при копировании документа очищать определенные реквизиты и табличную. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru