Storing cost between nodes - c++

I am making a maze solver using Uniform Cost Search and basically what I want to do is store random costs between rooms in my maze.
Data structure of rooms (named cells):
struct Cell
{
int row;
int column;
vector<Cell*> neighbors;
State state;
};
row and column are the position in the maze vector of the Cell, the vector<Cell*> neighbors defines with which cells this particular cell is connected to and state keeps a state of the cell (visited, empty etc.).
What I tried doing is making a property of the Cell struct like this: vector<int> cost where every element of that array matches the neighbor element.
For example:
012345
0 ######
1 # ##
2 # # #
3 ######
maze[1][1] has in it's neighbors vector:
neighbors[0] = *maze[1][2];
neighbors[1] = *maze[2][1];
it's cost vector now is:
cost[0] = 5;
cost[1] = 10;
But that way of doing it created a lot of problems.
What I have thought is that I need a cost matrix which will match one node with another and store the cost in the matrix, something like this:
0 1 2
0[0][2][4]
1[2][0][6]
2[4][6][0]
But in order to do this how will I make my matrix know which cell is which? how instead of 0's and 1's I make it know that it's [0][0] [0][1] [0][2] etc.
Do I need to utilize a 3D vector for something like this? If I do I would prefer to avoid it since I am inexperienced with 3D vectors.

Couldn't you use a custom object for your link to another room? Eg:
struct Cell;
struct CellLink {
const Cell *cell;
const int weight;
..
};
struct Cell {
int row;
int column;
vector<CellLink> neighbors;
State state;
};
This would keep cost and cell coupled with no worries. Only drawback is that you will store each cost twice (assuming it's symmetric) but this is true in many other approaches (matrix included).

Related

C++ creating a graph out of dot coordinates and finding MST

I'm trying to make a program in which the user inputs n dot coordinates, 0 < n <= 100. Supposedly, the dots have to be connected, lets say, with ink in a way that you can get e.g from point A to point X while following the inked line and using the least amount of ink possible.
I thought of using Prim Algorithm or something like that to get the MST but for that I need a graph. In all the webpages I've looked they don't really explain that, they always already have the graph with its edges already in there.
I need help specifically creating a graph in C++ out of a bunch of (x, y) coordinates, like the user inputs:
0 0
4 4
4 0
0 4
Please note I'm just starting with C++ and that I can't use any weird libraries since this would be for a page like CodeForces where you only get to use the native libraries.
(For the ones that are also doing this and are here for help, the correct output for this input would be 12)
To assume a complete graph may be most appropriate as suggested by "Beta".
Following code may creates edges between every pair of two dots from a list of dots in the array dots and returns the number of edges created.
After execute this code, you may be able to apply Prim Algorithm for finding MST.
// Definition of Structure "node" and an array to store inputs
typedef struct node {
int x; // x-cordinate of dot
int y; // y-cordinate of dot
} dots[100];
// Definition of Structure "edge"
typedef struct edge {
int t1; // index of dot in dots[] for an end.
int t2; // index of dot in dots[] for another end.
float weight; // weight (geometric distance between two ends)
} lines[];
// Function to create edges of complete graph from an array of nodes.
// Argument: number of nodes stored in the array dots.
// ReturnValue: number of edges created.
// Assumption: the array lines is large enough to store all edges of complete graph
int createCompleteGraph(int numberOfNodes){
int i,j,k,x-diff,y-diff;
k=0; // k is index of array lines
for (i=0; i<numberOfNodes-1; i++) {// index of a node at one end
for (j=i+1; j<numberOfNodes; j++) {// index of a node at another end
lines[k].t1 = i;
lines[k].t2 = j;
x-diff = dots[i].x - dots[j].x;
y-diff = dots[i].y - dots[j].y;
lines[k].weight = sqrt(x-diff * x-diff + y-diff * y-diff) // calculate geometric distance
k++;
}
}
return k;
}

Cpp grid with boolean value

For a project we have an expanding grid which loads random chunks. In this chunk we place random objects. The chuncks are loaded vertical and horizontal. The player starts at 0,0 going up is 0,-1 going left -1,0. I want to see if a chunk is loaded. Because the area is expanding an array is not an option so i lookee at options with vectors. But vectors cant have negative indexes. How can i store a grid (with 2 posible negative) values and a boolean. Should i just cretate a class with 3 variables (2 ints and a boolean) or are there other options, where i can use some kind of multidimensional vector with negative values.?
You could use a map, for example:
typedef std::pair<int, int> coord;
typedef std::map<coord, bool> coord_bool_map;
usage:
coord_bool_map m;
m[coord(-1, -3)] = true;
But vectors cant have negative indexes
No, but you can translate the indices with an offset. Say, you have a vector of size 5, which should represent a one dimensional grid of idices from -2...2:
std::vector<T> grid = std::vector<T>(5);
int offset = 2; // the offset, also index of origin
int start = -offset; // first index
int end = grid.size() - offset // one past last index
// example use
int index = -1;
T element_at_index = grid[index + offset];
A std::deque might be more efficient for expanding the container from the front side.
When you do expand the front side, remember to update the offset.
If you use a vector of vectors (or deques), then you need an offset for both dimensions.

Use map instead of array in C++ to protect searching outside of array bounds?

I have a gridded rectangular file that I have read into an array. This gridded file contains data values and NODATA values; the data values make up a continuous odd shape inside of the array, with NODATA values filling in the rest to keep the gridded file rectangular. I perform operations on the data values and skip the NODATA values.
The operations I perform on the data values consist of examining the 8 surrounding neighbors (the current cell is the center of a 3x3 grid). I can handle when any of the eight neighbors are NODATA values, but when actual data values fall in the first or last row/column, I trigger an error by trying to access an array value that doesn't exist.
To get around this I have considered three options:
Add a new first and last row/column with NODATA values, and adjust my code accordingly - I can cycle through the internal 'original' array and handle the new NODATA values like the edges I'm already handling that don't fall in the first and last row/column.
I can create specific processes for handling the cells in first and last row/column that have data - modified for loops (a for loop that steps through a specific sequence/range) that only examine the surrounding cells that exist, though since I still need 8 neighboring values (NODATA/non-existent cells are given the same value as the central cell) I would have to copy blank/NODATA values to a secondary 3x3 grid. Though there maybe a way to avoid the secondary grid. This solution is annoying as I have to code up specialized routines to all corner cells (4 different for loops) and any cell in the 1st or last row/column (another 4 different for loops). With a single for loop for any non-edge cell.
Use a map, which based on my reading, appears capable of storing the original array while letting me search for locations outside the array without triggering an error. In this case, I still have to give these non-existent cells a value (equal to the center of the array) and so may or may not have to set up a secondary 3x3 grid as well; once again there maybe a way to avoid the secondary grid.
Solution 1 seems the simplest, solution 3 the most clever, and 2 the most annoying. Are there any solutions I'm missing? Or does one of these solutions deserve to be the clear winner?
My advice is to replace all read accesses to the array by a function. For example, arr[i][j] by getarr(i,j). That way, all your algorithmic code stays more or less unchanged and you can easily return NODATA for indices outside bounds.
But I must admit that it is only my opinion.
I've had to do this before and the fastest solution was to expand the region with NODATA values and iterate over the interior. This way the core loop is simple for the compiler to optimize.
If this is not a computational hot-spot in the code, I'd go with Serge's approach instead though.
To minimize rippling effects I used an array structure with explicit row/column strides, something like this:
class Grid {
private:
shared_ptr<vector<double>> data;
int origin;
int xStride;
int yStride;
public:
Grid(int nx, int ny) :
data( new vector<double>(nx*ny) ),
origin(0),
xStride(1),
yStride(nx) {
}
Grid(int nx, int ny, int padx, int pady) :
data( new vector<double>((nx+2*padx)*(ny+2*pady));
xStride(1),
yStride(nx+2*padx),
origin(nx+3*padx) {
}
double& operator()(int x, int y) {
return (*data)[origin + x*xStride + y*yStride];
}
}
Now you can do
Grid g(5,5,1,1);
Grid g2(5,5);
//Initialise
for(int i=0; i<5; ++i) {
for(int j=0; j<5; ++j) {
g(i,j)=i+j;
}
}
// Convolve (note we don't care about going outside the
// range, and our indices are unchanged between the two
// grids.
for(int i=0; i<5; ++i) {
for(int j=0; j<5; ++j) {
g2(i,j)=0;
g2(i,j)+=g(i-1,j);
g2(i,j)+=g(i+1,j);
g2(i,j)+=g(i,j-1);
g2(i,j)+=g(i,j+1);
}
}
Aside: This data structure is awesome for working with transposes, and sub-matrices. Each of those is just an adjustment of the offset and stride values.
Solution 1 is the standard solution. It takes maximum advantage of modern computer architectures, where a few bytes of memory are no big deal, and correct instruction prediction accelerates performance. As you keep accessing memory in a predictable pattern (with fixed strides), the CPU prefetcher will successfully read ahead.
Solution 2 saves a small amount of memory, but the special handling of the edges incurs a real slowdown. Still, the large chunk in the middle benefits from the prefetcher.
Solution 3 is horrible. Map access is O(log N) instead of O(1), and in practice it can be 10-20 times slower. Maps have poor locality of reference; the CPU prefetcher will not kick in.
If simple means "easy to read" I'd recommend you declare a class with an overloaded [] operator. Use it like a regular array but it'll have bounds checking to handle NODATA.
If simple means "high performance" and you have sparse grid with isolated DATA consider implementing linked lists to the DATA values and implement optimal operators that go directly to tge DATA values.
1 wastes memory proportional to your overall rectangle size, 3/maps are clumsy here, 2 is actually very easy to do:
T d[X][Y] = ...;
for (int x = 0; x < X; ++x)
for (int y = 0; y < Y; ++y) // move over d[x][y] centres
{
T r[3][3] = { { d[i,j], d[i,j], d[i,j] },
d[i,j], d[i,j], d[i,j] },
d[i,j], d[i,j], d[i,j] } };
for (int i = std::min(0, x-1); i < std::max(X-1, x+1); ++i)
for (int j = std::min(0, y-1); j < std::max(Y-1, y+1); ++j)
if (d[i][j] != NoData)
r[i-x][j-y] = d[i][j];
// use r for whatever...
}
Note that I'm using signed int very deliberately so x-1 and y-1 don't become huge positive numbers (as they would with say size_t) and break the std::min logic... but you could express it differently if you had some reason to prefer size_t (e.g. x == 0 ? 0 : x - 1).

Implementation of Adjacent Matrix with 2D vectors c++

I am a beginner in c++ and I have worked on vectors just not on 2D vectors. I have surfed a lot, but data on internet is very specific related to 2D vectors.
I need to build a graph given an input file and then apply Kruskal's algorithm for minimum spanning tree.
My approach:
A1, A2, A3.....An would be the first row and col of my 2d Vectors and they will
contain name. I will read the input file and start matching the names.
And then at graph[i][j] I will put the weight.
A1 A2 A3......
A1 w w w .......
A2 w w w .......
A3 w w w .......
.
.
.
.
Now I am trying something like this:
struct mat{
string name;
}
int main(){
vector<vector<mat>> matrix;
// In order to insert
vector<mat> tempVec;
tempVec[0].name = "stack";
matrix.push_back(tempVec);
}
Now I have no idea that when I do tempVec[0].name, 0 indicates which row or col of Matrix. If it indicates row then how do I know which col is being accessed.
I mean vector.push_back(tempVec), assigns which position in my Matrix to data. I know I can access individual elements like Matrix[i][j]. But How can I assign weight to a particular row, col position and then access it.
Further do you think will be a good implementation for Kruskal's Method.
Please be simple in your code and explanatory.
And thanks in advance.
Using vector<vector<T>> is a fairly suboptimal way to represent matrices, even though it is often used. It would be better to make a one-dimensional vector<T> of size rows x cols. You can then index it as follows (assuming you follow C-style row major ordering):
vector<mat> matrix(rows*cols);
...
element_ij=matrix[i*cols+j];
In your current code, you never insert anything into matrix:
vector<vector<mat>> matrix;
// In order to insert
vector<mat> tempVec;
tempVec[0].name = "stack";
vector.push_back(tempVec);
I assume the last line should be matrix.push_back(tempVec);.

Top 5 most frequent from an array c++

Hi i've an array and im looking to get the top 5 most frequently occuring from this array.
static std::string pickRandomStockSymbol()
{
static std::string stockSymbols[] = {"SIRI", "INTC", "ZNGA", "BBRY", "MSFT",
"QQQ", "CSCO", "FB", "MU", "DELL", "AMAT", "NWSA", "AAPL", "AFFY", "ORCL",
"YHOO", "GRPN", "MDLZ", "VOD", "CMCSA" };
return stockSymbols[rand() % 20];
^^ this is the array i will be using.
the transactions are randomly created using this struct:
struct Transaction
{
string stockSymbol; // String containing the stock symbol, e.g. "AAPL"
string buyerName; // String containing the buyer's name e.g. "Mr Brown"
int buyerAccount; // Integer containing an eight digit account code
int numShares; // Integer containing the number of sold shares
int pricePerShare; // Integer containing the buy price per share
};
it is within this function i plan to do this in, i just dont really know what way i approach this:
string* Analyser::topFiveStocks()
{
return new string[5];
}
is there anyone out there willing to show me how i could run through the transactions to get these top 5 occuring elements?
if there would be any more information needed i'll be more than happy to provide.
Thanks in advance, Andrew
You could use a std::unordered_map with the stock symbol as the key, and the transaction count as the value. Then just put the five highest in a std::vector and return that.
As for putting the top N in the vector, you could keep it sorted, and re-sort it after every insert so that the stock with the highest transaction count is first. Then it's easy to see if the current stock when iterating over the map has a higher transaction count than the last item in the vector (which is the item in the vector with the smallest transaction count), then add it to the vector and re-sort it.
You could also just add all stocks from the map into a vector, and then sort it using the value in the map, and get the first five entries in the vector.
This can be something like this:
using transaction_map_type = std::unordered_map<std::string, unsigned int>;
transaction_map_type transactions;
// ...
std::vector<std::string> topFiveStocks()
{
std::vector<transaction_map_type::value_type> all_trans;
// Copy all transaction into our vector
std::copy(std::begin(transactions), std::end(transactions),
std::back_inserter(all_trans));
// Now sort the transactions
std::sort(std::begin(all_trans), std::end(all_trans),
[](const transaction_map_type::value_type& t1,
const transaction_map_type::value_type& t2)
{ return t1.second > t2.second; });
// And get the top five (or less) results into a separate vector
std::vector<std::string> top_five;
auto count = std::min(5UL, all_trans.size());
for (unsigned i = 0; i < count; i++)
top_five.push_back(all_trans[i].first);
return top_five;
}
Also, remember to increase the counter for the transactions in the map whenever you do a transaction.
Note: This solution not tested, just written in the browser. May not even compile.
Just sort the array and then loop over it to calculate longest interval of elements which are equal.
Accumulate the stock symbols:
the counts into a map<string, int>
the highest 5 symbols into a set<string>
the lowest frequency of the highest 5 symbols into an int
the lowest of the highest 5 symbols into a string