goto: Handle oversized costs with a special bucket
This is a bit redundant because the current usage of goto does not trigger it. It can be triggered by: * increasing goalRadius * decreasing NUMQUEUEBUCKETS * decreasing BM_DIM_STEP * increasing edge costsfix-squashed-planets
parent
e38835cfd4
commit
2d794d1a32
|
@ -1807,6 +1807,34 @@ Error CTaskGoto::PathFindingSearch(const Math::Vector &start, const Math::Vector
|
||||||
while (m_bfsQueue[m_bfsQueueMin % NUMQUEUEBUCKETS].empty())
|
while (m_bfsQueue[m_bfsQueueMin % NUMQUEUEBUCKETS].empty())
|
||||||
{
|
{
|
||||||
m_bfsQueueMin += 1;
|
m_bfsQueueMin += 1;
|
||||||
|
if (m_bfsQueueMin % NUMQUEUEBUCKETS == 0 && !m_bfsQueue[NUMQUEUEBUCKETS].empty())
|
||||||
|
{
|
||||||
|
// Process nodes with oversized costs.
|
||||||
|
const size_t countBefore = m_bfsQueue[NUMQUEUEBUCKETS].size();
|
||||||
|
for (size_t i = 0; i < m_bfsQueue[NUMQUEUEBUCKETS].size();)
|
||||||
|
{
|
||||||
|
const uint32_t indexInMap = m_bfsQueue[NUMQUEUEBUCKETS][i];
|
||||||
|
const int x = indexInMap % m_bmSize;
|
||||||
|
const int y = indexInMap / m_bmSize;
|
||||||
|
const int32_t distance = m_bfsDistances[indexInMap];
|
||||||
|
const int totalDistance = distance + HeuristicDistance(x, y, startX, startY);
|
||||||
|
if (totalDistance < m_bfsQueueMin + NUMQUEUEBUCKETS)
|
||||||
|
{
|
||||||
|
// Move node to a regular bucket.
|
||||||
|
m_bfsQueue[totalDistance % NUMQUEUEBUCKETS].push_back(indexInMap);
|
||||||
|
m_bfsQueue[NUMQUEUEBUCKETS][i] = m_bfsQueue[NUMQUEUEBUCKETS].back();
|
||||||
|
m_bfsQueue[NUMQUEUEBUCKETS].pop_back();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Look at next node.
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const size_t countAfter = m_bfsQueue[NUMQUEUEBUCKETS].size();
|
||||||
|
GetLogger()->Debug("Redistributed %lu of %lu nodes from the bucket with oversized costs.\n",
|
||||||
|
countBefore - countAfter, countBefore);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
auto& bucket = m_bfsQueue[m_bfsQueueMin % NUMQUEUEBUCKETS];
|
auto& bucket = m_bfsQueue[m_bfsQueueMin % NUMQUEUEBUCKETS];
|
||||||
const uint32_t indexInMap = bucket.back();
|
const uint32_t indexInMap = bucket.back();
|
||||||
|
@ -1820,9 +1848,32 @@ Error CTaskGoto::PathFindingSearch(const Math::Vector &start, const Math::Vector
|
||||||
|
|
||||||
if (totalDistance != m_bfsQueueMin)
|
if (totalDistance != m_bfsQueueMin)
|
||||||
{
|
{
|
||||||
m_bfsQueueCountSkipped += 1;
|
if (totalDistance < m_bfsQueueMin)
|
||||||
GetLogger()->Debug("Skipping node with mismatched distance, distance: %d, totalDistance: %d, m_bfsQueueMin: %d\n",
|
{
|
||||||
distance, totalDistance, m_bfsQueueMin);
|
// This node has been updated to a lower cost and has allready been processed.
|
||||||
|
m_bfsQueueCountSkipped += 1;
|
||||||
|
// GetLogger()->Debug("Skipping node with smaller distance, distance: %d, totalDistance: %d, m_bfsQueueMin: %d\n",
|
||||||
|
// distance, totalDistance, m_bfsQueueMin);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (totalDistance < m_bfsQueueMin + NUMQUEUEBUCKETS)
|
||||||
|
{
|
||||||
|
// Move node to a regular bucket.
|
||||||
|
m_bfsQueue[totalDistance % NUMQUEUEBUCKETS].push_back(indexInMap);
|
||||||
|
m_bfsQueueCountPushed += 1;
|
||||||
|
GetLogger()->Debug("Moving node with bigger distance into regular bucket, distance: %d, totalDistance: %d, m_bfsQueueMin: %d\n",
|
||||||
|
distance, totalDistance, m_bfsQueueMin);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Move node to the bucket with oversized costs.
|
||||||
|
m_bfsQueue[NUMQUEUEBUCKETS].push_back(indexInMap);
|
||||||
|
m_bfsQueueCountPushed += 1;
|
||||||
|
GetLogger()->Debug("Moving node with bigger distance into bucket with oversized costs, distance: %d, totalDistance: %d, m_bfsQueueMin: %d\n",
|
||||||
|
distance, totalDistance, m_bfsQueueMin);
|
||||||
|
}
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -144,7 +144,7 @@ protected:
|
||||||
int m_bmLine = 0; // increment line m_bmSize/8
|
int m_bmLine = 0; // increment line m_bmSize/8
|
||||||
std::unique_ptr<unsigned char[]> m_bmArray; // Bit table
|
std::unique_ptr<unsigned char[]> m_bmArray; // Bit table
|
||||||
std::unique_ptr<int32_t[]> m_bfsDistances; // Distances to the goal for breadth-first search.
|
std::unique_ptr<int32_t[]> m_bfsDistances; // Distances to the goal for breadth-first search.
|
||||||
std::array<std::vector<uint32_t>, NUMQUEUEBUCKETS> m_bfsQueue; // Priority queue with indices to nodes. Nodes are sorted into buckets.
|
std::array<std::vector<uint32_t>, NUMQUEUEBUCKETS + 1> m_bfsQueue; // Priority queue with indices to nodes. Nodes are sorted into buckets. The last bucket contains oversized costs.
|
||||||
int m_bfsQueueMin = 0; // Front of the queue. This value mod 8 is the index to the bucket with the next node to be expanded.
|
int m_bfsQueueMin = 0; // Front of the queue. This value mod 8 is the index to the bucket with the next node to be expanded.
|
||||||
int m_bfsQueueCountPushed = 0; // Number of nodes inserted into the queue.
|
int m_bfsQueueCountPushed = 0; // Number of nodes inserted into the queue.
|
||||||
int m_bfsQueueCountPopped = 0; // Number of nodes extacted from the queue.
|
int m_bfsQueueCountPopped = 0; // Number of nodes extacted from the queue.
|
||||||
|
|
Loading…
Reference in New Issue