Map::Map(int numPlayers, int gameMapLayout) { roomDefs = new ROOM*[numRooms]; memset(roomDefs, 0, numRooms*sizeof(ROOM*)); defaultRooms(); ConfigureMaze(numPlayers, gameMapLayout); ComputeDistances(0 , NULL); }
void Map::addCastles(int numPorts, Portcullis** ports) { ComputeDistances(numPorts, ports); }
inline void CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::CreateChildren( arma::Col<size_t>& indices, arma::vec& distances, size_t nearSetSize, size_t& farSetSize, size_t& usedSetSize) { // Determine the next scale level. This should be the first level where there // are any points in the far set. So, if we know the maximum distance in the // distances array, this will be the largest i such that // maxDistance > pow(base, i) // and using this for the scale factor should guarantee we are not creating an // implicit node. If the maximum distance is 0, every point in the near set // will be created as a leaf, and a child to this node. We also do not need // to change the furthestChildDistance or furthestDescendantDistance. const ElemType maxDistance = max(distances.rows(0, nearSetSize + farSetSize - 1)); if (maxDistance == 0) { // Make the self child at the lowest possible level. // This should not modify farSetSize or usedSetSize. size_t tempSize = 0; children.push_back(new CoverTree(*dataset, base, point, INT_MIN, this, 0, indices, distances, 0, tempSize, usedSetSize, *metric)); distanceComps += children.back()->DistanceComps(); // Every point in the near set should be a leaf. for (size_t i = 0; i < nearSetSize; ++i) { // farSetSize and usedSetSize will not be modified. children.push_back(new CoverTree(*dataset, base, indices[i], INT_MIN, this, distances[i], indices, distances, 0, tempSize, usedSetSize, *metric)); distanceComps += children.back()->DistanceComps(); usedSetSize++; } // The number of descendants is just the number of children, because each of // them are leaves and contain one point. numDescendants = children.size(); // Re-sort the dataset. We have // [ used | far | other used ] // and we want // [ far | all used ]. SortPointSet(indices, distances, 0, usedSetSize, farSetSize); return; } const int nextScale = std::min(scale, (int) ceil(log(maxDistance) / log(base))) - 1; const ElemType bound = pow(base, nextScale); // First, make the self child. We must split the given near set into the near // set and far set for the self child. size_t childNearSetSize = SplitNearFar(indices, distances, bound, nearSetSize); // Build the self child (recursively). size_t childFarSetSize = nearSetSize - childNearSetSize; size_t childUsedSetSize = 0; children.push_back(new CoverTree(*dataset, base, point, nextScale, this, 0, indices, distances, childNearSetSize, childFarSetSize, childUsedSetSize, *metric)); // Don't double-count the self-child (so, subtract one). numDescendants += children[0]->NumDescendants(); // The self-child can't modify the furthestChildDistance away from 0, but it // can modify the furthestDescendantDistance. furthestDescendantDistance = children[0]->FurthestDescendantDistance(); // Remove any implicit nodes we may have created. RemoveNewImplicitNodes(); distanceComps += children[0]->DistanceComps(); // Now the arrays, in memory, look like this: // [ childFar | childUsed | far | used ] // but we need to move the used points past our far set: // [ childFar | far | childUsed + used ] // and keeping in mind that childFar = our near set, // [ near | far | childUsed + used ] // is what we are trying to make. SortPointSet(indices, distances, childFarSetSize, childUsedSetSize, farSetSize); // Update size of near set and used set. nearSetSize -= childUsedSetSize; usedSetSize += childUsedSetSize; // Now for each point in the near set, we need to make children. To save // computation later, we'll create an array holding the points in the near // set, and then after each run we'll check which of those (if any) were used // and we will remove them. ...if that's faster. I think it is. while (nearSetSize > 0) { size_t newPointIndex = nearSetSize - 1; // Swap to front if necessary. if (newPointIndex != 0) { const size_t tempIndex = indices[newPointIndex]; const ElemType tempDist = distances[newPointIndex]; indices[newPointIndex] = indices[0]; distances[newPointIndex] = distances[0]; indices[0] = tempIndex; distances[0] = tempDist; } // Will this be a new furthest child? if (distances[0] > furthestDescendantDistance) furthestDescendantDistance = distances[0]; // If there's only one point left, we don't need this crap. if ((nearSetSize == 1) && (farSetSize == 0)) { size_t childNearSetSize = 0; children.push_back(new CoverTree(*dataset, base, indices[0], nextScale, this, distances[0], indices, distances, childNearSetSize, farSetSize, usedSetSize, *metric)); distanceComps += children.back()->DistanceComps(); numDescendants += children.back()->NumDescendants(); // Because the far set size is 0, we don't have to do any swapping to // move the point into the used set. ++usedSetSize; --nearSetSize; // And we're done. break; } // Create the near and far set indices and distance vectors. We don't fill // in the self-point, yet. arma::Col<size_t> childIndices(nearSetSize + farSetSize); childIndices.rows(0, (nearSetSize + farSetSize - 2)) = indices.rows(1, nearSetSize + farSetSize - 1); arma::vec childDistances(nearSetSize + farSetSize); // Build distances for the child. ComputeDistances(indices[0], childIndices, childDistances, nearSetSize + farSetSize - 1); // Split into near and far sets for this point. childNearSetSize = SplitNearFar(childIndices, childDistances, bound, nearSetSize + farSetSize - 1); childFarSetSize = PruneFarSet(childIndices, childDistances, base * bound, childNearSetSize, (nearSetSize + farSetSize - 1)); // Now that we know the near and far set sizes, we can put the used point // (the self point) in the correct place; now, when we call // MoveToUsedSet(), it will move the self-point correctly. The distance // does not matter. childIndices(childNearSetSize + childFarSetSize) = indices[0]; childDistances(childNearSetSize + childFarSetSize) = 0; // Build this child (recursively). childUsedSetSize = 1; // Mark self point as used. children.push_back(new CoverTree(*dataset, base, indices[0], nextScale, this, distances[0], childIndices, childDistances, childNearSetSize, childFarSetSize, childUsedSetSize, *metric)); numDescendants += children.back()->NumDescendants(); // Remove any implicit nodes. RemoveNewImplicitNodes(); distanceComps += children.back()->DistanceComps(); // Now with the child created, it returns the childIndices and // childDistances vectors in this form: // [ childFar | childUsed ] // For each point in the childUsed set, we must move that point to the used // set in our own vector. MoveToUsedSet(indices, distances, nearSetSize, farSetSize, usedSetSize, childIndices, childFarSetSize, childUsedSetSize); } // Calculate furthest descendant. for (size_t i = (nearSetSize + farSetSize); i < (nearSetSize + farSetSize + usedSetSize); ++i) if (distances[i] > furthestDescendantDistance) furthestDescendantDistance = distances[i]; }
void Floor::ComputeDistances() { for (int c = 0; c < NumCells(); c++) dist_.push_back(ComputeDistances(c)); }
CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::CoverTree( MatType&& data, MetricType& metric, const ElemType base) : dataset(new MatType(std::move(data))), point(RootPointPolicy::ChooseRoot(dataset)), scale(INT_MAX), base(base), numDescendants(0), parent(NULL), parentDistance(0), furthestDescendantDistance(0), localMetric(false), localDataset(true), metric(&metric), distanceComps(0) { // If there is only one point or zero points in the dataset... uh, we're done. // Technically, if the dataset has zero points, our node is not correct... if (dataset->n_cols <= 1) { scale = INT_MIN; return; } // Kick off the building. Create the indices array and the distances array. arma::Col<size_t> indices = arma::linspace<arma::Col<size_t> >(1, dataset->n_cols - 1, dataset->n_cols - 1); // This is now [1 2 3 4 ... n]. We must be sure that our point does not // occur. if (point != 0) indices[point - 1] = 0; // Put 0 back into the set; remove what was there. arma::vec distances(dataset->n_cols - 1); // Build the initial distances. ComputeDistances(point, indices, distances, dataset->n_cols - 1); // Create the children. size_t farSetSize = 0; size_t usedSetSize = 0; CreateChildren(indices, distances, dataset->n_cols - 1, farSetSize, usedSetSize); // If we ended up creating only one child, remove the implicit node. while (children.size() == 1) { // Prepare to delete the implicit child node. CoverTree* old = children[0]; // Now take its children and set their parent correctly. children.erase(children.begin()); for (size_t i = 0; i < old->NumChildren(); ++i) { children.push_back(&(old->Child(i))); // Set its parent correctly, and rebuild the statistic. old->Child(i).Parent() = this; old->Child(i).Stat() = StatisticType(old->Child(i)); } // Remove all the children so they don't get erased. old->Children().clear(); // Reduce our own scale. scale = old->Scale(); // Now delete it. delete old; } // Use the furthest descendant distance to determine the scale of the root // node. if (furthestDescendantDistance == 0.0) scale = INT_MIN; else scale = (int) ceil(log(furthestDescendantDistance) / log(base)); // Initialize statistic. stat = StatisticType(*this); Log::Info << distanceComps << " distance computations during tree " << "construction." << std::endl; }