I'm using OGDF version 2012.07.
I have a GraphCopy which represents a copy of a Graph instance. It holds references to the original nodes and edges when operating on the graph copy. In the documentation of GraphCopy, it says:
Copies of graphs supporting edge splitting.
The class GraphCopy represents a copy of a graph and maintains a mapping between the nodes and edges of the original graph to the copy and vice versa.
[...]
There is a method ogdf::GraphCopy::newEdge(edge eOrig) which is documented as follows:
Creates a new edge (v,w) with original edge eOrig.
The method is implemented as follows:
edge GraphCopy::newEdge(edge eOrig)
{
OGDF_ASSERT(eOrig != 0 && eOrig->graphOf() == m_pGraph);
OGDF_ASSERT(m_eCopy[eOrig].empty()); // no support for edge splitting!
edge e = Graph::newEdge(m_vCopy[eOrig->source()], m_vCopy[eOrig->target()]);
m_eCopy[m_eOrig[e] = eOrig].pushBack(e);
return e;
}
In the second assertion, the number of associated edge copies of the edge eOrig in the original graph has to be zero, which is only possible when the edge copy has been deleted, since initially (when the GraphCopy was initialized with an original graph) all edges in the graph copy are associated with the corresponding original edge in the original graph; thus, m_eCopy[eOrig].empty() is false for all edges.
How am I supposed to duplicate an edge in the graph copy while not changing the original graph?
I can not follow your explanations about the implementation. When I browse the source code GraphCopy.h on the OGDF website (which says its for 2012.07.), I see totally different classes. There is one class GraphCopy (which is an interface for derrived GraphCopy classes supporting edge splitting) and another class GraphCopySimple which doesn't support edge spliting.
So my advice is to check if you really have the right version.
The method newEdge(edge eOrig) in GraphCopySimple looks like it does what you want:
edge newEdge(edge eOrig) {
OGDF_ASSERT(eOrig != 0 && eOrig->graphOf() == m_pGraph);
edge e = Graph::newEdge(m_vCopy[eOrig->source()], m_vCopy[eOrig->target()]);
m_eCopy[m_eOrig[e] = eOrig] = e;
return e;
}
But there is one issue remaining. GraphCopySimple has no implementation for the constructors, so I guess it meant as abstract base class, so you need to derive your own GraphCopy-class and implement the missing functions.
Related
I want to build a n-arry tree from a document. For that i have 3 different types of elements for the tree:
Struct Nodes
Have a name
can contain other Nodes
Depth
Element Node (Leaf of the tree)
Have a Key
Have a value
Depth
Element Template Node (Leaf of the tree)
Have a placeholder which should be resolved later in the program
Depth
At the moment i think about something like this:
class Node {
public:
Node(int depth);
int depth() const;
private:
int depth_;
};
class StructNode : public Node {
...
private:
std::vector<std::unique_ptr<Node>> children;
};
class ElementNode : public Node {
...
};
class ElementTemplateNode : public Node {
...
};
The Tree will be generated from an File on Startup and reused to create an output string like this:
Structname:
key = value
key = value
Structname:
key = value
Structname:
key = value
...
Where the Key and value where directly read from the ElementNode or read from another file with the value of the placeholder inside the ElementTemplateNode
Is there maybe a better Structure for the Tree? Because with the current one i have to check first if its a StructNode, ElementNode or ElementTemplateNode
This is a typical structure for implementing a tree with different kind of nodes. Another variant would be the composite pattern.
The problem that you describe, is usually caused by asking the nodes about what they know, instead of telling them what to do. If you'd do it the other way round (tell, don't ask), you could get rid of those checks and benefit from polymorphism.
The different kind of nodes inherit from Node. You could design your tree using a uniform interface, with virtual functions defined for Node which then can be overridden for the different types of nodes. Calling the method would then do the right things, without need for a manual type check. For generating the output string, you'd tell the root node to generate a string. If it's a structure, it would add the heading and tell its children to generate a string, but if it's a leaf it would just add the key/value pair to the string. No need from outside to know anything about each node.
If the operation of exploring the tree shall not be implemented by the tree itself, the usual approach is to use a visitor pattern. The big advantage is that you write the vistor once, and it's then easy to specialize a new kind of visitor for different algorithms. Again, no need to check the type of the nodes. The pattern makes sure that the right elementary function is called for the right type of node.
To be clear, this question is not about geometry or about the actual physics of collision detection, but determining if two object belong to compatible categories for colliding (nothing to do with the actual physics part).
Take a look at this image:
Many physics engines (Box2d etc) follow such a system, where they allow you to define which category (Cat.) that an object belongs to, and the Mask - the categories of objects that it can collide with, and based on this determine if a collision should take place. I'm trying to implement the same, as I have an analogous problem, and need only this (no physics).
For example, an object (Object1) may belong to multiple categories - 0,1,2,3 and collide with categories (Mask), 5,8,9. Another Object (Object2), can belong to category (5), and collide only with Category (3). In this case a collision between Object1 and Object2 can take place.
Additional example, an object (Object1) may belong to multiple categories - 0,1,2,3 and collide with categories (Mask), 5,8,9. Another Object (Object2), can belong to category (5), and collide only with Category (4). In this case a collision between Object1 and Object2 will not take place, because although Object1 is interested in colliding with objects in category 5, Object2 is not interested in colliding with any of Object1's categories.
The collisions will take place only if A collides with B, and B collides with A.
I am trying to implement something which does the same, and am trying to figure out the data structure and algorithm to use, to efficiently check if two objects should "collide", according to the above logic. By efficiently, I mean use minimal memory and cpu required, so that I can do this check every clock tick - I am not trying to optimize specifically for memory or cpu, but simply find a solution that doesn't use more than it requires of each!
Here is the algorithm and data structures I've considered so far:
std::unordered_map<int,std::unordered_set<GameObject*>> categoryToObject
std::unordered_map<int,std::unordered_set<GameObject*>> maskToObject
std::unordered_map<GameObject*,std::unordered_set<GameObject*> objectsItCollidesWith
Algorithm:
Each time a new GameObject is created, for every category and mask it belongs to, it is added to the appropriate vector in each map. That means an object with Cat{1,3,7} & Mask{2,7} would be added to three vectors in the Cat map and two vectors in the mask map.
Just before adding to each map, for a new object, iterate through the categories of the new object, and use each category as a key in maskToObject, to see which gameObjects are interested in colliding with it. For each of these objects, check their category, and see if any of their categories fall into the mask that this object collides with. If that is the case, then add this object to a set of objects that this object collides with, and vice versa for the other object.
This way, as long as the categories / masks don't change, we just need to refer to the objectItCollidesWith map.
Is there a more efficient way than this ? Since the initial calculation needs to be done only once, and doesn't need to be done again unless the category / mask changes and I thought this was good.
Heres the solution I came up with.
Included only the part of my CollisionDetector class that is used for computing if two objects are in compatible categories for collision. Unlike the bitwise example, which I assume was used to quickly check all objects against each other, I think mine will be faster, since I check only against compatible categories and masks, rather than all objects.
The actual physics part - space subdivision, or checking for overlaps of objects is not relevant to this question, so not included.
typedef enum{
COLLISION_CATEGORY_NO_CAT = 0, //Used only for looping.
COLLISION_CATEGORY_PLAYER,
COLLISION_CATEGORY_GROUND,
COLLISION_CATEGORY_END_CAT, //Used only for looping.
}COLLISION_CATEGORIES;
class CollisionDetector{
private:
std::unordered_map<int,std::unordered_set<GameObject*>> categoryToObject; //Each gameObject belongs to the category key
std::unordered_map<int,std::unordered_set<GameObject*>> maskToObject; //Each gameObject contains the key as a mask
public:
CollisionDetector(){
for (int i = COLLISION_CATEGORY_NO_CAT + 1; i<COLLISION_CATEGORY_END_CAT; i++ ){
std::unordered_set<GameObject*> o;
categoryToObject[i] = o;
maskToObject[i] = o;
}
}
void addObject(GameObject* o){
auto objectCategories = o->getCategories();
auto objectMasks = o->getMasks();
//Check if A collides with B, and B collides with A. If so, make both objects keep note of each other.
for(auto& mask : objectMasks){
if(categoryToObject.find(mask)!=categoryToObject.end()){
//Get the objects whose category matches the mask.
auto& setOfObjectsWithCategoryMatchingMaskOfO = categoryToObject[mask];
for(auto otherObject : setOfObjectsWithCategoryMatchingMaskOfO){
//Check if this objects category is in the other objects mask
auto otherObjectsMasks = otherObject->getMasks();
for(auto& thisObjectsCategory : objectCategories){
if(otherObjectsMasks.find(thisObjectsCategory) != otherObjectsMasks.end()){
//Set both objects to collide with each other
o->addGameObjectICollideWith(otherObject);
otherObject->addGameObjectICollideWith(o);
//If even one of this objects category, is in the other objects mask, then we have fullfilled the condition that this objects category is in the other objects mask, and the other objects category is in this objects mask.
break;
}
}
}
}
}
//Add this object to each of the sets of objects with these categories, so other objects can do the first part of this function.
for(auto cat : objectCategories){
auto& s = categoryToObject[cat];
s.insert(o);
}
//Add this object to each of the sets of objects with these masks, so other objects can do the first part of this function.
for(auto mask : objectMasks){
auto& s = maskToObject[mask];
s.insert(o);
}
}
void removeObject(GameObject* o){
auto c = o->getCategories();
for(auto cat : c){
auto& s = categoryToObject[cat];
s.erase(o);
}
auto m = o->getMasks();
for(auto mask : m){
auto& s = maskToObject[mask];
s.erase(o);
}
o->removeMyselfFromObjectsICollideWith();
}
};
GameObject Class:
class GameObject{
private:
std::unordered_set<GameObject*> _gameObjectsICollideWith;
std::unordered_set<int> _categoriesIBelongTo;
std::unordered_set<int> _masksICollideWith;
public:
Sprite* sprite = nullptr;
//TODO: Do Zorder
GameObject(Node* parent, const Vec2& initialPosition,std::string frameName){
sprite = Sprite::createWithSpriteFrameName(frameName);
parent->addChild(sprite);
sprite->setPosition(initialPosition);
}
~GameObject(){
for(auto otherObject : _gameObjectsICollideWith){
otherObject->removeGameObjectICollideWith(this);
}
if(sprite!=nullptr){
if(sprite->getParent()){
sprite->removeFromParent();
}
}
}
std::unordered_set<int> getCategories(){
return _categoriesIBelongTo;
}
std::unordered_set<int> getMasks(){
return _masksICollideWith;
}
void setCategories(const std::unordered_set<int>& categories){
_categoriesIBelongTo = categories;
}
void setMasks(const std::unordered_set<int>& masks){
_masksICollideWith = masks;
}
void addGameObjectICollideWith(GameObject* o){
_gameObjectsICollideWith.insert(o);
}
void removeGameObjectICollideWith(GameObject* o){
_gameObjectsICollideWith.erase(o);
}
void removeMyselfFromObjectsICollideWith(){
for(auto other : _gameObjectsICollideWith){
other->removeGameObjectICollideWith(this);
}
_gameObjectsICollideWith.clear();
}
};
Premise: suppose I have a rectangular subset of 2D space and a collection of points, all with different x-values, in this subset. In the interest of the optimization of an algorithm as yet unwritten, I want to split my box into cells according to the following process: I halve my rectangle into 2 equal parts along the x-axis. Then I repeatedly halve each sub-rectangle until every cell contains either 1 point or none at all.
In this illustration the vertical lines represent the “halving process” and the lines are ordered by darkness (darker is newer).
First I’ll define two basic classes:
class Point{
private:
double x;
double y;
public:
// [...]
// the relevant constructor and getter
// overloaded operators +, -, * for vector calculations
};
class Box{
private:
Point bottom_left_point;
double width;
double height;
public:
Box(Point my_point, double my_x, double my_y) : // constructor
bottom_left_point(my_point), width(my_x), height(my_y){}
bool contains(const Point& p); // returns true iff the box contains p in the geometric sense
Box halve(bool b) const; // takes a boolean as input and returns the left half-rectangle for false, and the right half-rectangle for true
};
Now to implement the “halving algorithm” I’ll need a binary tree-like structure. Each node will represent a sub-cell of the rectangle (with the root node representing the total rectangle). A node may have two children, in which case the children represent its left and right halves. A node may also have a pointer to a particle which exists in the cell. The ultimate idea will be to start with an empty tree and insert the points in, one by one using a method insert(Point* to_be_inserted).
So I’ll define the following recursive class, whose private attributes are rather self-explanatory:
class Node;
class Node{
private:
enum node_type{ INT, EXT, EMPTY };
node_type type;
// type == INT means that it is an interior node, i.e. has children
// type == EXT means that it is an exterior node, i.e. has no children but contains a point
// type == EMPTY means that it has no children and no point
std::array<Node*,2> children;
Box domain; // the geometric region which is being represented
Point* tenant; // address of the particle that exists in this cell (if one such exists)
public:
Node(Box my_domain) :
type(EMPTY), children({nullptr}), domain(my_domain){}
//
// to be continued...
The first order of business is to define a subdivide() method which endows my node with two children:
void Node::subdivide(void){
type = INT;
children[0] = new Node(domain.halve(false));
children[1] = new Node(domain.halve(true));
}
Now everything is in place to write the crux of this whole affair, the insert method. Since it will be written recursively, the easiest solution is to have a boolean return type which tells us if the insertion was a success or failure. With this in mind, here’s the code:
bool Node::insert(Point* to_be_inserted){
if(not domain.contains(*to_be_inserted)) return false;
switch(type){
case INT:{
for(Node* child : children) if(child->insert(to_be_inserted)) return true;
return false;
}
case EXT:{
subdivide();
for(Node* child : children) if(child->insert(to_be_inserted)) break;
tenant = nullptr;
for(Node* child : children) if(child->insert(to_be_inserted)) return true;
break;
}
case EMPTY:{
type = EXT;
tenant = to_be_inserted;
return true;
}
}
throw 1; // this line should not, in, theory ever be reached
}
(Note that, for the sake of abstraction and generality, I have used for loops on the array children when I could have simply written out the two cases.)
Explanation:
First we check if to_be_inserted is in the geometric region represented by this. If not, return false.
If this is an internal node, we pass the point on to the each child until it is successfully inserted.
If this is an external node, that means that we have to split the node in two in order to be able to properly isolate to_be_inserted from the point that currently lives in the node.
First we call multiply().
Then we attempt to insert the current tenant into one of the children (please excuse how obscene this sounds, I assure you that it’s unintentional).
Once that is done, we do the same with to_be_inserted and return the result. (Note that a priori the insertion would be a success at this point because of the preliminary call to box::contains.
Finally, if this is an EMPTY node, we simply have to assign tenant to *to_be_inserted and change type to EXT and we’re done.
Ok, so let's try it out with a simple main:
int main(void){
Box my_box(ORIGIN, 1.0, 1.0); // rectangle of vertices (0,0),(0,1),(1,0),(1,1)
Node tree(box); // initializes an empty tree representing the region of my_box
Point p(0.1, 0.1);
Point q(0.6, 0.7);
tree.insert(&p);
tree.insert(&q);
return 0;
}
This compiles, but upon running the exception at the bottom of insert is thrown after a few calls. How is this possible, given that at no point a Node is constructed without a type value?
Edit: I have noticed, as well as this one, several possible errors which may also occur with small changes in the code:
An inexplicable call to nullptr->insert(something)
A call to insert by the address 0x0000000000000018 which doesn't point to an initialized Node.
The entirety of the code, including a makefile with the relevant debugging flags, can be found at https://github.com/raphael-vock/phantom-call.
I have two classes MaxFlow and MinMaxFlow.
MaxFlow uses boost graph to create a graph from a network topology:
class MaxFlow {
public:
MaxFlow : g_() { createGraph(); } //constructor
void createGraph();
void modifyGraph(); // modify the graph to use boost maxflow algorithm
int maxFlowAlgo(); // use g_ and some other util local variables
private:
Graph g_;
... // some other helper containers created during createGraph()
}
MaxFlow maintains a local variable g_ since we only need one instance to do all the work here.
MinMaxFlow iterates every edge in the graph to find a minimum max flow if we fail that edge (set capacity to 0):
class MinMaxFlow {
public:
int getMinMaxFlow() {
int minMaxFlow = INT_MAX;
MaxFlow maxFlowObj; // create a new obj
maxFlowObj.modifyGraph(); // I suppose this modify current obj
for (auto edge : graph_edges) {
// maxFlowAlgo will return incorrect value after several runs
int maxFlowVal = maxFlowObj.maxFlowAlgo();
int minMaxFlow = std::min(minMaxFlow, maxFlowVal);
}
return minMaxFlow;
}
}
Now the problem is, maxFlowAlgo is based on local variable g_ in class MaxFlow, when I create new object maxFlowObj in MinMaxFlow, calling maxFlowObj.maxFlowAlgo() will use its own data, which makes the result unpredictable.
So my question is: how can I use the method(like maxFlowAlgo) belongs to MaxFlow in the second class MinMaxFlow if the method uses local variables in MaxFlow?
Update: I have figured out the problem is from boost::boykov_kolmogorov_max_flow, I use bundle properties and pass capacity property map into it, but this algorithm will not only modify the capacity property map, but also my original edge capacity variable! Now the workaround is that I have to store the capacity values before running the algorithm and restore them after it. It's not supposed to modify the original members, right?
In this case it's OK that edge capacities are changed.
Sometimes algorithms don't modify input data. On other hand, it's better to alter existing data to save resources (memory) and because altered data can make sense. After max flow algorithm is executed, edge capacities are residual capacities; in other words, how much capacity is left in each edge when graph is saturated by flow. At least one of edge will have zero residual capacity; when after second algorithm execution, it will return zero because graph is saturated.
If you want to run max flow algorithm several times, you have to preserve initial graph and copy it each time you run algorithm. Each time in the beginning of loop iteration you have to reconstruct your graph or copy it from preserved.
Since you run algorithm several times, you probably want to run it on different graphs. You probably want to copy graph and set edge capacity to zero.
It seems you asked a XY Problem.
IF you want to maintains a local variable g_ since we only need one instance, you should use Singleton Design Pattern, other than creating instance when you need it.
I just want to know if it is possible to do something like this:
#include "graph.h"
Graph A, B;
Node n;
A.insertNode(n);
A.nodeExists(n); // returns true
B.nodeExists(n); // returns false
Since now I only stored a boolean var inside Node class, which tells me if a Node object has been inserted inside a Graph. But in this way, what happens:
A.nodeExists(n); // returns true
B.nodeExists(n); // returns true
which is incorrect. How can I solve this?
Either you should store a pointer to the Graph object that the Node belongs to in the Node (thus replacing your bool by a Graph*). Then it's easy and fast to check has been assigned to a particular Graph object. Inside the Graph::nodeExists function just asK:
if (n.pOwnerGraph == this)
return true;
As an alternative you could scan your entire graph and look for the the given node. That is much slower, but it doesn't require a Graph pointer in the node.