boost tree query point intersection - c++

I am trying to implement boost trees in a c++ code. Currently I'm doing the following: given a vector of bounding boxes v_bboxes, I build a tree out of it.
LinearPointRtree built_tree(v_bboxes.begin(), v_bboxes.end());
Then, given a point, I'd like to know in which of the bounding boxes from v_bboxes the point lies (it might be one or more). Currently I'm making the following query:
built_tree.query(bgi::intersects(point), std::back_inserter(result));
The result is a vector containing the bounding boxes which contain the point, while I'm interested in indexes referring to the original vector v_bboxes.
I could compare "result" with the original vector and find which bounding boxes were returned, but this would be inefficient and I believe there is a better way of doing this directly with boost, I just cannot find anything in the documentation.
Currently what I am also trying to do is to build a tree starting from a vector of tuples (bounding boxes, index), but it is throwing a very long and bad looking compilation error:
error: no matching function for call to
‘boost::geometry::index::detail::varray >,
17>::push_back(std::tuple >, unsigned int>&)’
Does someone know what I should change or has suggestions?

Unless a better idea is presented, the thing I was trying is correct (the problem was I didn't define the tree properly). So, define the tree
template<int spacedim, int leaf_number>
using LinearPointRtree = bgi::rtree<std::tuple<bgBox<spacedim>,unsigned int>, bgi::linear<leaf_number>>;
Now create the object:
std::vector< std::tuple<bgBox<spacedim>, unsigned int> > boxes_and_indices;
Where for each entry there's a bounding box and the desired index. Finally simply build the tree (as boost handles automatically pairs and tuples):
LinearPointRtree<spacedim,leaf_number> rstar_tree(flat_global_bboxes.begin(), flat_global_bboxes.end());
Then, when querying, you can use the second entry to get the index.
The idea came to me just after posting the question here...anyway, maybe it will help someone else...
Thanks everyone!

Related

Memory Error when using combination and intersection in python

I am coding for large graph sampling and meet some memory problems.
possible_edges = set(itertools.combinations(list(sampled_nodes), 2))
sampled_graph = list(possible_edges.intersection(ori_edges))
The code is supposed to find all combinations of nodes in sampled_nodes, which provided all possible edges formed by these nodes. Then take the intersection with original_edges to find which edge exactly exists.
The problem is when the graph is enormous, the itertools.combinations function would cause memory error.
I've thought to write for loop to iteratively calculate the intersection but takes too much time.
Any help from you guys would be appreciated. Thank you!
Found one solution, instead of take intersection of 2 lists, I choose not to create all combinations for possible_edges.
I pick edges in ori_edges to see if both of the node exists in sampled_nodes.
sampled_graph = list(set([(e[0], e[1]) for e in ori_edges if int(e[0]) in result_nodes and int(e[1]) in result_nodes]))
This code won't create the huge list and the speed is acceptable.

Apply a function to a range of cells in a spreadsheet

The answers in topics with similar titles haven't given me much of a resolution to my particular problem, but possibly I am not asking the right question. It might help knowing I'm an absolute noob when it comes to spreadsheets, so finding my way around is next to nil.
Currently I can set a basic function in the first cell A1 =ROW()
Simple right? Well now here comes the complication. If I click on the bottom right of the cell and start dragging I can then apply that very same function to a whole range of cells. Let's say I apply it from A1:A10. Every cell within this group now has the same function.
Hooray! We did it, right? I applied a function to a range of cells each with their own output. But wait, if I then go back to the original cell and change its formula none of the other cells change with it. GRRRRR!!!!
There are a couple of fixes I've come up with but don't necessarily know how to implement. The first is to have every cell link back to the original cell and reference its function. This would be useful if I wanted to randomly scatter dependent cells about the document. The other would be much more useful in an orderly group where you know the exact dimensions by specifying in the original cell the size of the array you want to apply the function to.
With that said, let me hear your thoughts.
The closest I've come to an answer is to use FORMULA() which returns the formula used by a cell as text. Unfortunately all answers on evaluating the text resort to scripting. How strange! I thought something like this would be common. Might as well get to scripting.
Hold on, I may have spoke too soon. An array can be made with =MUNIT(), but it's only square. Drats!
Ok... I'm hoping the zebra stripes will eventually become its own answer unless someone else beats me to it. So a simple array can be made with ={1,2;3,4} where commas separate values by column and semicolons for values by row except to generate it you have to press Control+Shift+Enter (because reasons?). I'm thinking now that I'll need to have functions that can generate lists of values based on a single function for each row, and pray that it'll work. So, back to looking. (Wow this is taking forever)
The way I was hypothesizing can't even generate a 1x1, e.g., ={ROW()} returns Err:512 which is a formula overflow.
Alright, in summary so far I've narrowed down the two options,
1) link every cell to the original formula
2) populate an array with a single formula
each with their own incomplete answer,
a) use FORMULA() to return the formula of a cell as text
b) create a hypothetical array like so ={LIST_OF_VALUES()}
These both require a strange form of the nonexistent EVALUATE() function to 'function' correctly. Isn't that fun?
Google Sheets handles case b by allowing ={ROW()}Control+Shift+Enter to generate =ArrayFormula({ROW()}). Working with the general case of any sized array being filled with a single function doesn't exist in the world of spreadsheets it seems. That's very saddening because I can't think of a much better tool for what I want to do. Copy paste it is until I need to use macros.
Depending on your specific use case, creating a user-defined function may help:
use the Basic IDE to create your function;
apply it to any cells on any sheet;
modifying the Basic code will affect all cells where the function is used.
I've elaborated the steps in an answer on superuser.
Sure, you could write some complex code to update functions, but wouldn't the easy way be just to drag it to the same range of cells the same way you did before? It should properly overwrite the existing code in there, and if it doesn't, you can just as easily delete the outdated code and drag the new code in.
Probably the best approach is to simply drag the amended formula over the range of cells (as advised by OldBunny2800). This is less error prone and easier to maintain than a custom macro.
Another option would be to use an array function. Then you only have to edit the function once, and the same edit will be automatically applied to the whole range of cells in that array function.

Sorting a 2D vector of objects

I am working on a little puzzle game ( Gem Puzzle).
I have a puzzle Piece object for each piece on the board that has the following attributes:
Position Pcorrect_;
Position Pactuel_;
bool estvide_;
(the 3rd attribute is irrelevant for this question)
The Position is simple structure consisting of:
unsigned ligne;
unsigned colonne;
Each Piece is stored in a vector of a vector.
std::vector<std::vector<Piece>> board_;
The Pieces eventually get mixed around so the correct attribute (location) does not match the actual attribute (location).
I am stuck on a method that should sort the board.The actual position has to match the current position for each piece of the board.
Is there an elegant way of doing this with a sort function ?My current approach is using 4 loops and lots of conditions which is probably the wrong way of doing it.
if you use C++11, you can create a tuple and sort it.
You can define a custom comparison, like in this example:
http://www.hongliangjie.com/2011/10/10/sortin-tuples-in-c/

Convert array to nodes

Let me start off with saying that I have very basic knowledge of nodes and graphs.
My goal is to make a solver for a maze which is stored as an array. I know exactly how to implement the algorithm for solving (I'm actually implementing a couple of them) but what my problem is, is that I am very confused on how to implement the nodes that the solver will use in each empty cell.
Here is an example array:
char maze[5][9] =
"#########",
"# # #",
"# ## ## #",
"# # #",
"#########"
My solver starts at the top left and the solution (exit) is at the bottom right.
I've read up on how nodes work and how graphs are implemented, so here is how I think I need to make this:
Starting point will become a node
Each node will have as property the column and the row number
Each node will also have as property the visited state
Visited state can be visited, visited and leads to dead end, not visited
Every time a node gets visited, every directly adjacent, empty and not visited cell becomes the visited node's child
Every visited node gets put on top of the solutionPath stack (and marked on the map as '*')
Every node that led to a dead end is removed from the stack (and marked on the map as '~')
Example of finished maze:
"#########",
"#*~#****#",
"#*##*##*#",
"#****~#*#",
"#########"
Basically my question is, am I doing something really stupid here with my way of thinking (since I am really inexperienced with nodes) and if it is could you please explain to me why? Also if possible provide me other websites to check which implement examples of graphs on real world applications so I can get a better grasp of it.
The answer really depends on what you find most important in the problem. If you're searching for efficiency and speed - you're adding way too many nodes. There's no need for so many.
The efficient method
Your solver only needs nodes at the start and end of the path, and at every possible corner on the map. Like this:
"#########",
"#oo#o o#",
"# ## ## #",
"#o oo#o#",
"#########"
There's no real need to test the other places on the map - you'll either HAVE TO walk thru them, or won't have need to even bother testing.
If it helps you - I got a template digraph class that I designed for simple graph representation. It's not very well written, but it's perfect for showing the possible solution.
#include <set>
#include <map>
template <class _nodeType, class _edgeType>
class digraph
{
public:
set<_nodeType> _nodes;
map<pair<unsigned int,unsigned int>,_edgeType> _edges;
};
I use this class to find a path in a tower defence game using the Dijkstra's algorithm. The representation should be sufficient for any other algorithm tho.
Nodes can be of any given type - you'll probably end up using pair<unsigned int, unsigned int>. The _edges connect two _nodes by their position in the set.
The easy to code method
On the other hand - if you're looking for an easy to implement method - you just need to treat every free space in the array as a possible node. And if that's what you're looking for - there's no need for designing a graph, because the array represents the problem in a perfect way.
You don't need dedicated classes to solve it this way.
bool myMap[9][5]; //the array containing the map info. 0 = impassable, 1 = passable
vector<pair<int,int>> route; //the way you need to go
pair<int,int> start = pair<int,int>(1,1); //The route starts at (1,1)
pair<int,int> end = pair<int,int>(7,3); //The road ends at (7,3)
route = findWay(myMap,start,end); //Finding the way with the algorithm you code
Where findWay has a prototype of vector<pair<int,int>> findWay(int[][] map, pair<int,int> begin, pair<int,int> end), and implements the algorithm you desire. Inside the function you'll probably need another two dimensional array of type bool, that indicates which places were tested.
When the algorithm finds a route, you usually have to read it in reverse, but I guess it depends on the algorithm.
In your particular example, myMap would contain:
bool myMap[9][5] = {0,0,0,0,0,0,0,0,0,
0,1,1,0,1,1,1,1,0,
0,1,0,0,1,0,0,1,0,
0,1,1,1,1,1,0,1,0,
0,0,0,0,0,0,0,0,0};
And findWay would return a vector containing (1,1),(1,2),(1,3),(2,3),(3,3),(4,3),(4,2),(4,1),(5,1),(6,1),(7,1),(7,2),(7,3)

Choosing the best stucture for my list of players

I am in trouble choosing the most pertinent structure for my data, here are the explanations:
I am actually working on a game project for school, a Bomberman like game in c++.
I am designing the Map object, who contain Bombs, Boxes, Players and Walls.
The map is 2D, I have already 2 containers of type:
std::unordered_map<int, std::unordered_map<int, AEntity*> > *UMap;
One contain Walls, the other contain destructible objects (Bombs, Boxes).
I have already discussed this choice here -> Choice of unsorted_map.
It's mainly for fast access time and because there can only be one element per map's box.
Now as the title suggest I'am in trouble choosing a data container for my players, because there can be multiple players on a single map's box, unordered_maps can't be used.
In a first time I was going to use a std::list<AEntity*> sorted with std::sorted, AEntity containing the entity information (coords), but while coding my
playerOn(const int x, const int y);
function I found it was a poor choice. I can't retrieve fast enough which player(s) is on the given box using dichotomies, and if there is no player of this box it's a waste of time.
How should I store my (AEntity)Players in order to be able to retrieve them fast
(On of the itchy thing is that there can be more than 500 player at the single time, on big map, that's why I am looking for optimization)
I am running out of brain juice. Thanks for your future answers.
Edit about my probleme
It's mainly because I want to know if there is another solution to go trough my whole std::list of player to find if there is someone on box(x, y). Looks slow and not optimized, but i can't figure another way to do this.
(I can change container type if needed)
First of all, before trying any optimization, you should profile your code to detect where is the bottleneck. You will be surprised. Once that said :
1) Your unordered_maps seem like a lot of over-engineering. The answers provided in your previous post are true but I think it is useless in your case. You absolutely do not care of a O(log(n)) cost when n = 500. Just make a vector of Entities*. It is much enough.
2) You seem to be falling in the god object anti-design pattern. A bomberman game is an excellent project for studying OOP, as it teaches you to avoid the God Object design pattern. Make sure each class does its own business and no class handles all the logic (I suspect your class Map or Game has too much power).
a) Create a vector of players, a vector of bombs, a vector of walls, a vector of fires, etc.
b) Map should be a 2-dimensionnal array storing list of pointers to the entities that are present on each Map's box. (Each Map[i][j] holds pointers to all the elements that are on the box of index (i,j)).
c) Bombs should create fire elements.
d) Your central routine should be something like :
while(gameContinued)
{
for each entity in the game
{
entity.Update(map);
}
game.Render();
}
Bomb update consists in making the bomb's texture rendering dynamic and create fires if delay is over-due (and update the Map with the fires pointers accordingly).
Fire update consists in nothing except vanishing if delay is over-due (and update the Map).
Player update consists in moving through keyboard event handling (and updating their current internal x and y values ), creating bomb if needed, dying if for their position (x,y), there is a fire in the Map[i][j] list of entities.
3) In most of my students implementation of bomberman, the only issue they can get is with textures and deep copy of objects. Make sure you have a Texture Loader (using Singleton Pattern) to avoid loading multiple times the same textures, and you should be fine.