So firstly, here's my declaration and initialization:
int** GameField = 0;
GameField = new int*[mapsize];
for(int i = 0; i < mapsize; i++)
GameField[i] = new int[mapsize];
for(int j = 0; j < mapsize; j++)
for(int i = 0; i < mapsize; i++)
GameField[i][j] = 0;
Now i'm trying to insert data with a simple command:
if(!(Player1.find(Move) == Player1.end()) && iter>0)
{
GameResult=1;
}else
{
Player1[Move] = 1;
GameField[Move.first][Move.second]=1;
if(WinCheck(Player1, Move, x, mapsize))
GameResult = 1;
}
Simoultaneously i insert the data into an STL map. Visual Studio has no native display for dynamic data, so i'm unable to view the content of the table. Tried watching memory but it's pretty hard to make sense of it. There is a part of program that seems to be working till a certain point:
bool CheckIfMovePossible(int **GameField, pair <int,int> &Move, int MapSize)
{
int x = Move.first;
int y = Move.second;
bool Neighbour = false;
if(GameField[modulo(x+1,MapSize)][y]==(1||2)) // po prawej
Neighbour = true;
if(GameField[modulo(x+1,MapSize)][modulo(y+1,MapSize)]==(1||2))
Neighbour = true;
if(GameField[modulo(x+1,MapSize)][modulo(y-1,MapSize)]==(1||2))
Neighbour = true;
if(GameField[x][modulo(y+1,MapSize)]==(1||2)) // x
Neighbour = true;
if(GameField[x][modulo(y-1,MapSize)]==(1||2))
Neighbour = true;
if(GameField[modulo(x-1,MapSize)][modulo(y+1,MapSize)]==(1||2)) // po lewej
Neighbour = true;
if(GameField[modulo(x-1,MapSize)][y]==(1||2))
Neighbour = true;
if(GameField[modulo(x-1,MapSize)][modulo(y-1,MapSize)]==(1||2))
Neighbour = true;
return Neighbour;
}
It's supposed to check if there are any neighbouring data in the container. I calculate the values manualy and using the debugger, and in each case the program acts as if there is no data in requested location, while it must there for it is present in the map. Any info will be appreciated.
It appears that what you wanted to do with code like this
if(GameField[modulo(x+1,MapSize)][y]==(1||2))
is this.
if ( GameField[modulo(x+1,MapSize)][y] == 1 ||
GameField[modulo(x+1,MapSize)][y] == 2)
Unrelated to your question, it seems like your logic does a lot of work after it has been determined that the function will return true.
Consider using else if or having the code return true as soon as it's determined that that is the return value.
Your if statements should be like this:
if(GameField[modulo(x+1,MapSize)][y] == 1 ||
GameField[modulo(x+1,MapSize)][y] == 2) // po prawej
Neighbour = true;
You also might want to save your modulo values so as not to have to recalculate them so often.
Related
I have tried to solve the problem Rerouting at hacker rank. I am posting here for help as competition is over.
https://www.hackerrank.com/contests/hack-the-interview-v-asia-pacific/challenges/rerouting
I have tried to solve problem using Strong connected components, but test cases failed. I can understand we have to remove cycles. But I stuck how to approach problem. Below is solution i have written. I am looking for guidence how to move forward so that i can apply my knowledge future based on mistakes i made here. Thanks for your time and help
int getMinConnectionChange(vector<int> connection) {
// Idea: Get number of strongly connected components.
int numberOfVertices = connection.size();
for(int idx = 0; idx < numberOfVertices; idx++) {
cout << idx+1 <<":"<< connection[idx] << endl;
}
stack<int> stkVertices;
map<int, bool> mpVertexVisited; //is vertex visited.think this as a chalk mark for nodes visited.
int numOFSCCs = 0;
int currTime = 1;
for (int vertexId = 0; vertexId < numberOfVertices; vertexId++) {
// check if node is already visited.
if (mpVertexVisited.find(vertexId+1) == mpVertexVisited.end()) {
numOFSCCs++;
mpVertexVisited.insert(make_pair(vertexId+1, true));
stkVertices.push(vertexId+1);
currTime++;
while (!stkVertices.empty()) {
int iCurrentVertex = stkVertices.top();
stkVertices.pop();
// get adjacent vertices. In this excercise we have only one neighbour. i.e., edge
int neighbourVertexId = connection[iCurrentVertex-1];
// if vertex is already visisted, don't insert in to stack.
if (mpVertexVisited.find(neighbourVertexId) != mpVertexVisited.end()) {
continue;
}
mpVertexVisited.insert(make_pair(neighbourVertexId, true));
stkVertices.push(neighbourVertexId);
} // while loop
} // if condition m_mapVrtxTimes.find(*itr) == m_mapVrtxTimes.end()
} // for loop of vertices
return numOFSCCs - 1;
}
This is a problem that I just solved and would like to share the solution.
The problem can be solved with union-find.
Two main observation:
The number of edges that has to be changed is the number of components - 1 (not necessarily strongly connected) Thus, union-find is handy here for finding the number of components
Second observation is that some component doesn't have terminating node, consider 1<->2, in other words, a cycle exist. We can detect whether there exists a terminating node if some node doesn't have an outgoing edge.
If all components have a cycle, it means that we need to change every component instead of a number of components - 1. This is to make it such that the graph will have a terminating point.
Code:
struct UF {
vector<int> p, rank, size;
int cnt;
UF(int N) {
p = rank = size = vector<int>(N, 1);
for (int i = 0; i < N; i++) p[i] = i;
cnt = N;
}
int find(int i) {
return p[i] == i ? i : p[i] = find(p[i]);
}
bool connected(int i, int j) {
return find(i) == find(j);
}
void join(int i, int j) {
if (connected(i, j)) return;
int x = find(i), y = find(j);
cnt--;
if (rank[x] > rank[y]) {
p[y] = x;
size[x] += size[y];
} else {
p[x] = y;
size[y] += size[x];
if (rank[x] == rank[y]) rank[y]++;
}
}
};
int getMinConnectionChange(vector<int> connection) {
int nonCycle = 0;
int n = connection.size();
UF uf(n);
for(int i=0;i<n;i++) {
int to = connection[i] - 1;
if(to == i) nonCycle++;
else uf.join(i, to);
}
int components = uf.cnt;
int countCycle = uf.cnt - nonCycle;
int res = components - 1;
if(countCycle == components) res++; // all components have cycle
return res;
}
TL;DR: you can view this as looking for a minimal spanning arborescence problem.
More precisely, add a node for each server, and another one called "Terminate".
Make a complete graph (each node is linked to every other one) and set as cost 0 for the edges corresponding to your input, 1 for the other ones.
You can use for example Edmond's algorithm to solve this.
I'm trying to write a sort and sweep broadphase system, and I've run into some performance problems, during the overlap reporting stage.
My pair reporting code is where the bottleneck is:
The basic Idea, is to generate a temporary list of overlap pairs for every axis, then for every pair in X, check if the pair exists in Y and Z. Some extra checks are in the pair generation to deal with the stacking cube and containment edge cases.
The pair generation code is as follows:
//temporary pair generation for X axis
for (unsigned int i = 0; i < mXExtents.size()-1; i++)
{
if (!mXExtents[i].mMax)
{
for (unsigned int j = i + 1; j < mXExtents.size(); j++)
{
if (mXExtents[j].mOwner->getID() == mXExtents[i].mOwner->getID())
{
break;
}
else
{
tempXPairs.push_back(new Pair(mXExtents[i].mOwner, mXExtents[j].mOwner));
}
}
}
}
//temporary pair generation for Y axis
for (unsigned int i = 0; i < mYExtents.size()-1; i ++)
{
if (!mYExtents[i].mMax)
{
for (unsigned int j = i + 1; j < mYExtents.size(); j++)
{
if (mYExtents[j].mOwner->getID() == mYExtents[i].mOwner->getID())
{
break;
}
else
{
tempYPairs.push_back(new Pair(mYExtents[i].mOwner, mYExtents[j].mOwner));
}
}
}
}
//temporary pair generation for Z axis
for (unsigned int i = 0; i < mZExtents.size()-1; i ++)
{
if (!mZExtents[i].mMax)
{
for (unsigned int j = i + 1; j < mZExtents.size(); j++)
{
if (mZExtents[j].mOwner->getID() == mZExtents[i].mOwner->getID())
{
break;
}
else
{
tempZPairs.push_back(new Pair(mZExtents[i].mOwner, mZExtents[j].mOwner));
}
}
}
}
The bottleneck, found through profiling, occurs when pairs are compared via the == operator. I suspect that this is due to many such checks being carried out, rather than the overhead of the check itself.
Pair reporting code as follows:
bool found = false;
//now search Y & Z temp storage for matching pairs
for (unsigned int i = 0; i < tempXPairs.size(); i++)
{
if (tempXPairs[i] != nullptr)
{
//search Y first
for (unsigned int j = 0; j < tempYPairs.size(); j++)
{
if (tempYPairs[j] != nullptr)
{
//match found in Y
if (*tempXPairs[i] == *tempYPairs[j])
{
//make a quick copy and stop searching
found = true;
delete tempYPairs[j];
tempYPairs[j] = nullptr;
break;
}
}
}
//element in Y found
if (found)
{
found = false;
//search Z temp list for a match
for (unsigned int j = 0; j < tempZPairs.size(); j++)
{
if (tempZPairs[j] == nullptr)
continue;
//match in Z found
if (*tempXPairs[i] == *tempZPairs[j])
{
//if we are at this stage then we have a triple match, so an overlap on all axes.
//add the pair to the manager
mPairManager->addpair(tempXPairs[i]);
//delete extranious pairs
delete tempZPairs[j];
tempZPairs[j] = nullptr;
//clear variables
tempXPairs[i] = nullptr;
//and end search
break;
}
}
//not found so get rid of all relevant pairs and move on to next in X list
delete tempXPairs[i];
tempXPairs[i] = nullptr;
}
else
{
delete tempXPairs[i];
tempXPairs[i] = nullptr;
}
}
}
//finally clear temp storage
for (unsigned int i = 0; i < tempXPairs.size(); i++)
{
if (tempXPairs[i] != nullptr)
{
delete tempXPairs[i];
}
}
for (unsigned int i = 0; i < tempYPairs.size(); i++)
{
if (tempYPairs[i] != nullptr)
{
delete tempYPairs[i];
}
}
for (unsigned int i = 0; i < tempZPairs.size(); i++)
{
if (tempZPairs[i] != nullptr)
{
delete tempZPairs[i];
}
}
The material I have read on sort and sweep/sweep and prune doesn't elaborate a fast way to deal with fast searching for duplicate pairs, or indeed, a way to search the other axes for equivelant pairs in an efficient manner. I'm clearly missing something, so I would appreciate any help that could be given.
The performance problem does not surprise me here, given this algorithm's apparent quadratic complexity.
It's not clear what class, or POD, is being returned by getId(). For the sake of clarity, let's say that getId() returns an IdType class, and that the mxExtents is a container of ExtentsType classes.
If IdType implements strict weak ordering (which means that it implements operator<, in addition to operator==), and you believe you will achieve better performance if the number of IdType comparisons are returned, then I would suggest creating a
std::multimap<IdType, ExtentsType *> lookup;
Now populate lookup by making a single pass over mxExtents, inserting each value's IdType, and a pointer to the original instance of ExtentsType into the multimap. The insert operation will have logarithmic complexity, then after inserting everything, a single pass over the multimap container will make it trivial to grab all instances of ExtentsType with the same IdType. Since the original insert operations had logarithmic complexity, I would expect that the total number of comparisons, on the first pass, will be much fewer.
Of course, the second pass will have linear complexity, but this looks to me like the easiest low-hanging fruit to try first, to see if this fixes your suspected bottleneck.
Another potential variation would be to use a std::multiset instead of a std::multimap, with a custom comparator class. This will make it possible to employ some additional optimizations, based on the internal relationship between each ExtentsType and its inner IdType instance, to eliminate many internal copy/move constructions that are happening here, too. Which inherit the original algorithm's quadratic complexity (and would also be reduced accordingly, by switching to a multimap, and possibly eliminated completely, by using a custom multiset comparator).
After spending an entire day debugging, I've noticed that memory leaks always occur when the following function is called:
void merge(TContainer<T> List2)
{
TContainer<T> temp(this->Size);
for (int i = 0; i < this->Size; i++)
{
temp.Interface[i] = this->Interface[i];
}
this->Interface = new T[Size + List2.size()];
Size = Size + List2.size();
for(int i = 0; i < List2.size(); i++)
{
Interface[i] = List2[i];
}
for(int i = List2.size(); i < Size; i++)
{
Interface[i] = temp[i];
};
delete[] temp.Interface;
}
Within the code:
TContainer_Short<unsigned short> Temp = TContainer_Short<unsigned short>(0);
for(int i = (ToUpdate.size() - 1); i >= 0; i--)
{
UpdateInUse = true;
ToUpdate[i].Ad.push_back(AdQueue[i].Indirect[0].Address);
auto Entity = ToUpdate[i];
UpdateInUse = false;
float HighestScore = 0;
int Index = 0;
//Go through all the advertisements on their queue
//Make sure our last index is always the next plot point in our story.
for(int j = 0; j < ToUpdate[i].Ad.size(); j++)
{
AdvertisementBase Ad = *World::get()->getTemplateAd(Entity.Ad[j]);
float temp = returnScore(Entity.Index, Ad);
//If its higher than our current score, set i to this index
if(temp > HighestScore)
Index = j;
}
//Index is last pos when we're currently continuing our plot queue. We haven't changed our mind about what advertisement we want
if(Index !=(Entity.Ad.size() - 1))
{
AdvertisementBase *Ad = World::get()->getTemplateAd(Entity.Ad[Index]);
this->reduceAdChain(Entity.Index, Ad);
}
else
{
//Makes sure that the entity is on track for the next goal that it had already determined
plan(Entity.Index,AdQueue.Interface[Entity.Index].Indirect[0].Address);
}
Temp.push_back(Entity.Index);
ToUpdate.pop_back();
}
if(!ExecutingInUse)
{
ExecutingInUse = true;
Executing.merge(Temp);
ExecutingInUse = false;
}
delete[] Temp.Interface;
}
However, I can't seem to figure out why it only occurs when there are multiple threads. The array itself is only ever being referenced by one thread at a time, (Atomic), so it shouldn't be a problem.
Deleting the Executing::merge reference makes the memory leak go away, and definitely speeds up performance noticeably in single threaded scenarios.
The thing that’s even more odd is that merge is used in other places:
void reduceAdChain(unsigned short Index, TContainer<AdvertisementReference> Ads)
{
AdQueue[Index].Indirect.merge(Ads);
}
And no memory leak gets created, even though reduceAdChain is called almost a full magnitude more often than Executing::merge. And removing merge in this area, creates no noticeable performance increase, even though
A) The arrays being taken in by reduceAdChain for the merge are almost 3x the size on average than the arrays that pass into Executing::merge
and
B) The overall length of reduceAdChain is almost 5x the length of Executing.
However, executing does get cleared at the end of every iteration.
This is one of the weirdest things I've ever ran into in multithreaded environments.
Where Executing gets used:
if(!m_simulated_entities[i]->ExecutingInUse)
{
for (int j = 0; j < m_simulated_entities[i]->Executing.size(); )
{
// Retrieve Tag Data and Update Constants
m_simulated_entities[i]->ExecutingInUse = true;
ExecutingIndex = m_simulated_entities[i]->Executing[j];
m_simulated_entities[i]->ExecutingInUse = false;
TagIndex = m_simulated_entities[i]->TagIndicesPerEntity[ExecutingIndex];
now = std::chrono::system_clock::now();
time_now = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count();
if (m_simulated_entities[i]->Timing[m_simulated_entities[i]->Executing[j]].TimeConstant == 0)
{
//Make sure all of our new attribute values still allow this entity to live
if(!m_simulated_entities[i]->updateTick(ExecutingIndex))
m_simulated_entities[i]->removeInstance(ExecutingIndex);
else
{
//Compute our new transfer constant
m_simulated_entities[i]->prepare(ExecutingIndex);
//Update the tagging system
m_simulated_entities[i]->updateTags(ExecutingIndex);
//Search for new decisions
m_simulated_entities[i]->ToSearch.push_back(ExecutingIndex);
}
//Remove the index from execution
m_simulated_entities[i]->ExecutingInUse = true;
m_simulated_entities[i]->Executing.Remove(j);
m_simulated_entities[i]->ExecutingInUse = false;
}
else if (time_now - m_simulated_entities[i]->Timing[ExecutingIndex].LastUpdateTime > updateConstants[TagIndex])
{
m_simulated_entities[i]->Timing[ExecutingIndex].TimeConstant--;
m_simulated_entities[i]->Timing[ExecutingIndex].LastUpdateTime = time_now;
j++;
}
}
}
For the test, updateTick is disabled and will always return true, since allowing that function to properly execute would have made finding the memory leak a lot harder.
in the function merge:
this->Interface = new T[Size + List2.size()];
You should check if the pointer this->Interface is NULL or not, if it is not, it should be freed first. Otherwise if the function merge is called multiple times, it will leak.
So the code will be:
if (this->Interface != NULL)
delete[] this->Interface;
this->Interface = new T[Size + List2.size()];
Sorry for possibly stupid question: if you have vectors as "ToUpdate[i].Ad" etc, why don't you use "this->Interface" as vector too? This could save you a lot of time hunting this leak.
I'm working on a school project using C++ and SFML 2.0, it's due for Tuesday and I've just recently run in to this problem.
I've put an arrow on where the latest Call Stack is.
These are the code parts that I suspect might have something wrong in them. I'm also very new to c++ and I know I do alot of things wrong.
This is in my Background class, it loads all my tiles, sets their position and tiletype and so on.
The GetWayPointList returns a vector of tiles to my EnemyManager class
void Background::Load(QuadTree * quadTree) {
int tempTiles[32][32] = {... Lots of 1's and 0's in here };
for(int i = 0; i < 32; i++)
{
for(int j = 0; j < 32; j++)
{
---> tile[j][i]->tileType = tempTiles[j][i];
tile[j][i]->setPosition(sf::Vector2f((float)(i*32),(float)(j*32)));
if(tile[j][i]->tileType == 1)
{
quadTree->AddObject(tile[j][i]);
}
else if(tile[j][i]->tileType == 0)
{
tile[j][i]->distanceFromStart = INT_MAX;
tile[j][i]->parent = NULL;
vector<Tile*> tempTiles;
if(tile[j+1][i]->tileType == 0)
tempTiles.push_back(tile[j+1][i]);
if(tile[j-1][i]->tileType == 0)
tempTiles.push_back(tile[j-1][i]);
if(tile[j][i+1]->tileType == 0)
tempTiles.push_back(tile[j][i+1]);
if(tile[j][i-1]->tileType == 0)
tempTiles.push_back(tile[j][i-1]);
tile[j][i]->setSuccessors(tempTiles);
tilesList->push_back(tile[j][i]);
}
}
}
}
vector<Tile*>* Background::GetWayPointList()
{
return tilesList;
}
The Call Stack itself says TileShooter v0.1.exe!Background::Load(QuadTree*quadTree) Line 68 + 0x2e bytes.
Line 68 is where the arrow is.
If you need more code / info just say.
Any points on what's possibly wrong would be greatly appriciated.
Best Regards, Fredrik W
Edit
I've edited the code some including tile[j][i] = new Tile();
void Background::Load(QuadTree * quadTree) {
int tempTiles[32][32] = {... Lots of 1's and 0's in here };
for(int i = 0; i < 32; i++)
{
for(int j = 0; j < 32; j++)
{
tile[j][i] = new Tile();
tile[j][i]->tileType = tempTiles[j][i];
tile[j][i]->setPosition(sf::Vector2f((float)(i*32),(float)(j*32)));
if(tile[j][i]->tileType == 1)
{
quadTree->AddObject(tile[j][i]);
}
else if(tile[j][i]->tileType == 0)
{
tile[j][i]->distanceFromStart = INT_MAX;
tile[j][i]->parent = NULL;
vector<Tile*> tempTiles;
----> if(tile[j+1][i]->tileType == 0)
tempTiles.push_back(tile[j+1][i]);
if(tile[j-1][i]->tileType == 0)
tempTiles.push_back(tile[j-1][i]);
if(tile[j][i+1]->tileType == 0)
tempTiles.push_back(tile[j][i+1]);
if(tile[j][i-1]->tileType == 0)
tempTiles.push_back(tile[j][i-1]);
tile[j][i]->setSuccessors(tempTiles);
tilesList->push_back(tile[j][i]);
}
}
}
}
vector<Tile*>* Background::GetWayPointList()
{
return tilesList;
}
That didn't really solve but rather moved the error downwards, I've moved my arrow on where the Call Stack has it's latest call.
So your tile member is defined as Tile* tile[32][32]. That's a 2D array of size 32x32 where each element is a pointer to Tile. However, they are just pointers and currently don't point anywhere in particular - accessing them is undefined behaviour (in your case, an access violation). You need to allocate the actual Tile objects:
for (int i = 0; i < 32; i++) {
for (int j = 0; j < 32; j++) {
tile[i][j] = new Tile();
}
}
Don't forget to do the same kind of loop in the destructor of Background that instead does delete tile[i][j];.
Better yet, don't dynamically allocate your tiles and just define tile as:
Tile tile[32][32];
Even better yet (!), use std::array<std::array<Tile,32>,32>. :)
To answer your edit, even though it's invalidated my above answer: You're accessing the j+1th element of tile. When j is 31, you're accessing tile[32] which is outside the bounds of your array.
I'm having a problem with one of my functions, I'm working on a simple tile map editor, and I'm trying to implement a 3D array to keep track of tiles (x,y, layer). Before this I had a 1D array where all the tiles were just listed sequencially:
bool Map::OnLoad(char* File) {
TileList.clear();
FILE* FileHandle = fopen(File, "r");
if(FileHandle == NULL) {
return false;
}
for(int Y = 0;Y < MAP_HEIGHT;Y++) {
for(int X = 0;X < MAP_WIDTH;X++) {
Tile tempTile;
fscanf(FileHandle, "%d:%d ", &tempTile.TileID, &tempTile.TilePassage);
TileList.push_back(tempTile);
}
fscanf(FileHandle, "\n");
}
fclose(FileHandle);
return true;
}
This basically read strings from the file which looked like:
2:1 1:0 3:2...
Where the first number states the tileID and the second one states the Tile passability. The above function works. My 3D arrays are also correctly constructed, I tested them with simple assignments and calling values out of it. The function that gives me problems is the following (please note that the number 2 i.e. OnLoad2() was added so I can keep the old variables and the function untouched until the prototype is working):
bool Map::OnLoad2(char* File) {
TileList2.clear();
FILE* FileHandle2 = fopen(File, "r");
if(FileHandle2 == NULL) {
return false;
}
for(int Y = 0;Y < MAP_HEIGHT;Y++) {
for(int X = 0;X < MAP_WIDTH;X++) {
Tile tempTile;
fscanf(FileHandle2, "%d:%d ", &tempTile.TileID, &tempTile.TilePassage);
TileList2[X][Y][0] = tempTile;
}
fscanf(FileHandle2, "\n");
}
fclose(FileHandle2);
return true;
}
While this function doesn't trigger the compiler to report any errors, as soon as the application starts, it freezes up and crashes. For additional information MAP_WIDTH and MAP_HEIGHT are set to 40 each and the 3D array was constructed like this:
TileList2.resize(MAP_HEIGHT);
for (int i = 0; i < MAP_HEIGHT; ++i) {
TileList2[i].resize(MAP_WIDTH);
for (int j = 0; j < MAP_WIDTH; ++j)
TileList2[i][j].resize(3);
}
I would appreciate it if you could point me out what do I need to fix, as far as I know I must have messed up the for loop structure, as the 3D array initializes and works properly. Thank you for your help!
TileList2.clear();
This line reinitializes TileList2, so it is back to a zero-length vector. Delete that line, and you will probably be okay.