Как реализовать функцию, которая заставляет двигаться после неоднозначных движений в алгоритме поступления путиC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Как реализовать функцию, которая заставляет двигаться после неоднозначных движений в алгоритме поступления пути

Сообщение Anonymous »

Я нахожусь в процессе оптимизации многопоточного алгоритма пополнения пути для вопроса, который у меня был. Цель состоит в том, чтобы привлечь все кратчайшие возможные пути, которые касаются каждого квадрата в n n сеткой. Я сделал функцию force_obvious_moves, где я заставляю движения человека, явные для каждой стартовой позиции, где это применимо. В некоторых случаях один ход подразумевает еще несколько. < /P>
Существуют также узнаваемые последовательные структуры перемещения, обнаруженные в середине пути, но это не грубое, если они не доказаны. < /P>
  • Код: Выделить всё

    std::bitset()
    Bitmasks используются для отслеживания квадратов, которые касался пути
  • Код: Выделить всё

    vertex_masks
    - это матрица бит -маски, которые верны только для окружающих квадратов каждой вершины
  • -следующая вещь, которая докажет для справки
inline void force_obvious_moves(std::bitset& mask, std::vector& path) {
if (n < 3) return;

auto step = [&](int nx, int ny) {
path.push_back({nx, ny});
mask |= vertex_masks[nx][ny];
};
const auto& [x, y] = path.back();
if (y == 1){
switch (x) {
case 1:
step(2, 1);
break;
case 2:
step(1, 1);
step(1, 2);
break;
case 3:
step(2, 1);
step(1, 1);
step(1, 2);
break;
case 4:
step(3, 2);
step(2, 1);
step(1, 1);
step(1, 2);
step(1, 3);
step(2, 4);
step(1, 5);
break;
}
}
if (y == 2) {
step(x, 1);
}
}

inline void search_from(const std::pair& start) {
std::vector path;
std::bitset mask = vertex_masks[start.first][start.second];
path.reserve(MAX_LEN + 1);
path.push_back(start);
force_obvious_moves(mask, path);
dfs(mask, path);
}

inline void run_parallel_search(const std::array& starts) {
const int hw_concurrency = static_cast(std::thread::hardware_concurrency());
const int num_threads = starts.empty() ? 0 : std::clamp(hw_concurrency, 1, static_cast(starts.size()));
std::vector threads;
threads.reserve(num_threads);
for (int i = 0; i < num_threads; ++i) {
threads.emplace_back([i, num_threads, &starts] {
for (int j = i; j < static_cast(starts.size()); j += num_threads) {
search_from(starts[j]);
}
});
}
}
< /code>
Моя идея заключается в следующем: < /p>
switch (x) {
case 1:
step(2, 1);
/*
steps
dfs()
backtrack somehow
steps
dfs()
backtrack again?
...
*/
break;
}
< /code>
Это, очевидно, гораздо менее читабельно, и я не уверен, как предоставление одной потоке несколько стартовых позиций повлияет на производительность. В любом случае, у меня есть сильное ощущение, что есть что-то лучшее, что можно сделать.>

Подробнее здесь: https://stackoverflow.com/questions/795 ... -a-pathfin
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»