DAG based application - directed-acyclic-graphs

the other day I could not exprese myself correctly and get closed my answer, so here's my second shot:
I need to create a basic DAG (Directed Acyclic Graph) application, put on common words, a node based application. I don't need a GUI for nw, just a console example, that excecute the whole tree.
here's what I have so far :
typedef struct Node
{
int type;
void ( *excecute)(); //the callback function
struct Node *ins;
struct Node *outs;
}
//some functions
void root(float n,float *buffer)
{
buffer[0]=sqrtf(n);
}
void sum(float a, float b, float *buffer)
{
buffer[0]=a+b;
}
void Output_screen(float val)
{
printf(""The DAG output is: %f ", val);
}
The nodes could have any number of inputs and any umber of outputs (how do i handle them?)
My question is:
How do I construct a DAG with the output of a node sum be the input of a node root and that output be the input of the node Output_screen?
Node(sum)---> Node(root)--->Node(Output_screen)
I will preciate any help, since I could'nt find any tut on it

What you need is a copy of Knuth. I cannot recommend strongly enough reading him to learn about this kind of basic data structure.
Aside from which, you could use linked lists to represent the node lists. If you are in C++, you can also use STL vectors of pointers.

Related

C++ n-arry tree with different elements

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.

Dijkstra's Algorithm in String-type Graph

I am making an inter-city route planning program where the graph that is formed has string-type nodes (e.g. LHR, ISB, DXB). It's undirected but weighted, and is initialized as:
map<pair<string, string>, int> city;
and then I can add edges by for example:
Graph g;
g.addEdge("DXB", "LHR", 305);
g.addEdge("HTR", "LHR", 267);
g.addEdge("HTR", "ISB", 543);
and the resultant output will be:
ISB LHR
DXB 0 305
HTR 543 267
Now, the question... I'm trying to implement Dijkstra's algorithm in this graph but so far have been unable to correctly run it on string-type nodes and opposed to learning and doing it on int-type nodes. Can someone guide me through the correct steps of implementing it in the most efficient way possible?
The data structure used by a graph application has a big impact on the efficiency and ease of coding.
Many designs start off with the nodes. I guess the nodes, in the problems that are being modelled, often have a physical reality while the links can be abstract relationships. So it is more natural to start writing a node class, and add on the links later.
However, when coding algorithms that solve problems in graph theory, it becomes clear that the links are the real focus. So, lets start with a link class.
class cLink
{
public:
cLink(int c = 1)
: myCost(c)
{
}
int myCost; // a constraint e.g. distance of a road, max xapacity of a pipe
int myValue; // a calculated value, e.g. actual flow through a pipe
};
If we store the out edges of node in a map keyed by the destination node index, then the map will be an attribute of the source node.
class cNode
{
public:
cNode(const std::string &name = "???")
: myName(name)
{
}
std::string myName;
std::map<int, cLink> myLink; // out edges of node, keyed by destination
};
We have links and nodes, so we are ready to construct a class to store the graph
class cGraph {
public:
std::map<int, cNode> myG; // the graph, keyed by internal node index
};
 Where did the node index come from? Humans are terrible at counting, so better the computer generates the index when the node is added.
cGraph::createNode( const std::string& name )
{
int n = myG.size();
myG.insert(std::make_pair(n, cNode(name)));
}
Don't implement this! It has a snag - it can create two nodes with the same name. We need to be able to check if node with a specified name exists.
int cGraph::find(const std::string &name)
{
for (auto n : myG)
{
if (n.second.myName == name)
{
return n.first;
}
}
return -1;
}
This is inefficient. However, it only needs to be done once when the node is added. Then the algorithms that search through the graph can use fast lookup of nodes by index number.
Now we can prevent two nodes being created with the same name
int cGraph::findoradd(const std::string &name)
{
// search among the existing nodes
int n = find(name);
if (n < 0)
{
// node does not exist, create a new one
// with a new index and add it to the graph
n = myG.size();
myG.insert(std::make_pair(n, cNode(name)));
}
return n;
}
Humans, in addition to being terrible counters, are also over confident in their counting prowess. When they specify a graph like this
1 -> 2
1 -> 3
Let’s not be taken in. Let’s regard these numbers as names and continue to use our own node index system.
/** Add costed link between two nodes
*
* If the nodes do not exist, they will be added.
*
*/
void addLink(
const std::string & srcname,
const std::string & dstname,
double cost = 1)
{
int u = findoradd(srcname);
int v = findoradd(dstname);
myG.find(u)->second.myLink.insert(
std::make_pair(v, cLink(cost)));
if (!myfDirected)
myG.find(v)->second.myLink.insert(
std::make_pair(u, cLink(cost)));
}
With the addition of a few getters and setters, we are ready to start implementing graph algorithms!
To see an complete implementation, including Dijsktra, using these ideas, check out PathFinder.
The core problem is that when we work on graphs with integer vertices, the index of the adjacency list represents the node (since the indexes are also numbers). Now instead of using adjacency list like vector<pair<int, int> > adj[N]we can use map<string,vector<string, int> > adj. Now adj["DXB"] will contain a vector of pairs of the form <string, int> which is the <name, weight> for the cities connected to "DXB".
If this approach seems very complex, then you use some extra memory to map a city to a number, and then you can code everything considering that the graph has integer vertices.

Word Processing Application

I'm trying to implement a data structure that allows me to look up a number in a database as quickly as possible. Let's say I have a database that has 5450 different numbers. My primary concern is speed not memory efficiency. I found this article online about Multi Way Tree: http://c0.typesafety.net/courses/15122-f10/lectures/18-tries.pdf. So I decided to implement a 10-way tree where each node is an array size 10 but I'm having a bit of difficulty how to create classes for the structure. Here is a rough outline that I came up with:
class MSTNode{
bool isDigit; //is it one of the digit in the number
int arrayNode[];
MST(bool isWord): isWord(isWord){
arrayNode[] = [0,1,2,3,4,5,6,7,8,9];
}
}
class MST{
MSTNode * root;
//What functions should be included in this class?
//Insert Function?
//Search Function?
}
I just need a little help to get the ball rolling. I would appreciate very much if somebody can point out the potential problem with my design above. What should be included? what should not? Basically, I need help to come up with the design of the data structure. In no way, I'm looking to get free code from you. I just need help in the beginning with the design, I can implement the rest.
You may have something like:
class MSTNode{
public:
void Insert(unsigned int n) {
// GetOrCreate MSTNode in the first digit of n
// and recursively call insert with n without this digit
// once no more digit, set the isFinal flag.
}
bool Search(unsigned int n) const {
// Get MSTNode of the first digit of n
// if nullptr, return false.
// and recursively call Search with n without this digit
// once no more digit, return the isFinal flag.
}
private:
std::unique_ptr<MSTNode> arrayNode[10];
bool isFinal = false; //is it one of the digit in the number
};
With the first MSTNode the root.

c++ linked backtrace path

I have an algorithm - very performance sensitive that goes through a graph and make some decisions. As part of it I have to create a backtrace for the solution I find to be the best. At every step there are multiple choices and they are evaluated again and again until at the end there is only one. At every new step current backtraces could be made a subsolution for zero or more new possible solutions.
The complexity of the algorithm does not allow tricks so what I have so far is smart pointers for the nodes where the backtraces are dynamically hooked.
struct Node;
typedef boost::intrusive_ptr<Node> NodeSPtr;
struct Node
{
Node(NodePool& pool)
: mCount(0)
{
}
~Node()
{
}
size_t ref_count()
{
return mCount;
}
NodeSPtr mPreviousNode;
size_t mCount;
// ... some data
};
The problem with this is that it generates big number of small items and this slows down the algo.
The question is what other options you could suggest where both performance and memory are sensitive matters.

Implementing Hierholzer's algorithm for a general-purpose graph in C++

I have a node(basically the graph vertex) templated class like this:
template<class T>
class Node
{
public:
T Data;
Node<T>* Parent;
vector<Node<T>*> Children;
};
and then I have a templated graph class that encapsulates the root of the graph and I have a method the is supposed to generate an Eulerian Path(after it has checked if the conditions for the existence of an Eulerian Path are satisfied):
template<class T>
class Graph
{
public:
Node<T>* Root;
vector<Node<T>*> GetEulerianPath() const;
bool HasEulerianPath() const;
};
HasEulerianPath() just traverses the node(*vertex*) hierarchy and counts the amount of vertices that have an odd degree.If they are no more than two, it returns true.
Now the problem is - I'm not exactly quite sure how do implement the algorithm.Any tips?Should I just extract the entire hierarchy in a vector and iterate trough that or do I use some recursive method of Node?The Wikipedia Page suggest using a linked list...or maybe I should just generate an new smaller singledirectional Graph as an output for the GetEulerianPath() method?I'm confused at how to proceed here.
The way you have structured your Node class basically forms a doubly-linked list that is contained in a vector. There are a few issues (mathematically) that you appear to have:
A given "child" can have more than 1 "parent". In fact, if there are 2 "child" nodes, there would have to be 2 "parent" nodes in order for this to be an Eulerian cycle. You may want to redefine Node as follows:
template<class T>
class Node
{
public:
T Data;
list<shared_ptr<Node<T>>> Connections;
};
Which will allow you to change your Graph to:
template<class T>
class Graph
{
public:
shared_ptr<Node<T>> Start; // name change just to convey that there isn't a "root" node in an Eulerian cycle
list<shared_ptr<Node<T>>> GetEulerianPath() const;
bool HasEulerianPath() const;
};
This way, implementing Hierholzer's Algorithm is simply a matter of traversing the Connections for each node.
You need to convert your graph first. But definitely not to a std::vector.
For each node you need to be able to quickly get an unused edge (put them all in a linked list and remove when used).
Therefor each node should have a linked list of children not a std::vector.
Next, you need to be able to find nodes which have unused edges, you can just collect those in a linked list while traversing. You also need to build a linked list with your path while traversing, the list of unused edges should refer to this list so you can change the path in O(1).
(The Node<T>* Parent; in your code seems odd for a general graph.)