Задать вопрос
Ответы пользователя по тегу Графы
  • Как решать задачу с графом?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Рекурсивный перебор в глубину из узлов-выходов, ограниченный временем жизни лабиринта, с обнулением посещённых узлов (можно через список посещённых).
    Запоминаем маршрут с максимальной выгодой, потом разворачиваем его, получая прямой путь.
    Отдельно надо обрабатывать вариант, когда два узла соединены путём с нулевым временем. Тут обход может зациклиться.
    Вариант на PHP

    <?php
    
    /*
     * Комната 0 введена для унификации алгоритма.
     * Из неё можно попаст в любой выход, в неё попасть из других комнат нельзя.
     */
    const NODES = [
        0 => ['battleTime' => 0, 'loot' => 0],
        1 => ['battleTime' => 5, 'loot' => 15],
        2 => ['battleTime' => 2, 'loot' => 1],
        3 => ['battleTime' => 3, 'loot' => 5],
        4 => ['battleTime' => 3, 'loot' => 6],
        5 => ['battleTime' => 4, 'loot' => 7],
        6 => ['battleTime' => 5, 'loot' => 9],
        7 => ['battleTime' => 7, 'loot' => 16],
        8 => ['battleTime' => 2, 'loot' => 3],
        9 => ['battleTime' => 0, 'loot' => 0],
        10 => ['battleTime' => 0, 'loot' => 0],
    ];
    
    const ROUTE_TIMES = [
        0 => [9 => 0, 10 => 0],
        1 => [2 => 1],
        2 => [1 => 1, 8 => 2, 9 => 3, 4 => 1],
        3 => [9 => 2, 4 => 4],
        4 => [3 => 4, 2 => 1, 5 => 3],
        5 => [4 => 3, 10 => 1],
        6 => [10 => 4, 7 => 4],
        7 => [8 => 4, 6 => 4],
        8 => [2 => 2, 7 => 4, 10 => 6],
        9 => [3 => 2, 2 => 3],
        10 => [5 => 1, 8 => 6, 6 => 4],
    ];
    
    const MAX_LIFETIME = 25;
    
    function findRoute(array $state): array
    {
        $bestState = $state;
        foreach (ROUTE_TIMES[$state['currentNode']] as $nextNode => $travelTime) {
            $nodeTime = $state['lifetime'] + $travelTime +
                (in_array($nextNode, $state['route']) ? 0 : NODES[$nextNode]['battleTime']);
            if ($nodeTime > MAX_LIFETIME) {
                continue;
            }
            $nodeState = findRoute([
                'lifetime' => $nodeTime,
                'currentNode' => $nextNode,
                'wealth' => $state['wealth'] + (in_array($nextNode, $state['route']) ? 0 : NODES[$nextNode]['loot']),
                'route' => [...$state['route'], $nextNode],
            ]);
            if ($nodeState['wealth'] > $bestState['wealth']) {
                $bestState = $nodeState;
            }
        }
        return $bestState;
    }
    
    $state = findRoute([
        'lifetime' => 0,
        'currentNode' => 0,
        'wealth' => 0,
        'route' => [],
    ]);
    
    echo "Route: ", implode(' => ', array_reverse($state['route'])), "\n";
    echo "Wealth: ", $state['wealth'], "\n";
    echo "Time: ", $state['lifetime'], "\n";

    Route: 8 => 2 => 1 => 2 => 4 => 5 => 10
    Wealth: 32
    Time: 25
    Ответ написан
    Комментировать
  • Как в графе найти самый "большой" полный подграф?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Найти все подграфы, выбрать из них самый большой.
    Ответ написан
  • Как нужно изменить алгоритм Дейкстры чтобы он искал самый длинный путь?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Никак, максимальный путь - бесконечность.
    Ответ написан
    Комментировать
  • В чем ошибка алгоритма(8 Puzzle, A*)?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Насколько я понял из примера в описании задачи, алгоритм строит сразу всё дерево решений, параллельно продвигаясь по самым оптимальным позициям в дереве. То есть, для каждой позиции надо хранить предка, тогда, после достижения в одной из веток финальной позиции, можно будет построить всю цепочку ходов.
    Ответ написан
    1 комментарий
  • Как написать алгоритм для для поиска кратчайшего расстояния?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Тогда придётся повторно пересматривать вершины если для них нашёлся более короткий путь.
    Пример:
    .  A  B  C
    A  -  4  1
    B  4  -  1
    C  1  1  -

    Начальная точка A (A = 0). Строим пути из A (B = 4, C = 1), добавляем их в очередь. Строим пути из B (С = 1). Строим пути из C (B = 2). И снова надо перестраивать пути из B, поскольку до него нашёлся более короткий путь.
    Поэтому у Дейкстры и используется сортированная очередь, тогда не возникает необходимости в повторном просмотре точек.
    Ответ написан
  • Как найти кратчайший путь в динамическом графе?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    IMHO, у Вас не совсем корректная модель. Сами рёбра графа никуда не исчезают, меняется их цена. То есть, если из A в B мы можем попасть в момент T, то цена ребра B-C будет равняться времени от момента T до момента самого раннего прибытия маршрута из B в C с учётом отправления не ранее T+время на пересадку.
    Ответ написан
    4 комментария
  • Задача расчета расстояния путей между городами с использование графов в C++?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Самое простое - двумерный массив w[N][N], где w[i][j] - стоимость перехода из узла i в узел j или -1 если такого пути нет. Если узлов много, а связность низкая, то надо уже копать в сторону разреженных массивов.
    Ответ написан
    Комментировать