Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

[C++]Project #3 – Traversing Property Graphs EDIT: in reply to the comment, what

ID: 3913947 • Letter: #

Question

[C++]Project #3 – Traversing Property Graphs

EDIT: in reply to the comment, what excerpt are you talking about?

EDIT #2 : Need to construct a directed graph, where the property names label edges connecting nodes; either using array or linked list implementation.

Learning Objectives

Implement a data structure to meet given specifications

Design, implement, and use a graph data structure

Perform analysis of algorithm performance

Utilize Dijkstra's algorithm

Overview

Your task for this assignment is to implement a graph data structure and find appropriate shortest paths, while accounting for property-labelled edges.

The Graph class

At this point in the course, I leave it to your discretion to choose an appropriate implementation (i.e. array vs linked). Note that you may need a class for Nodes or Edges. Furthermore, you may use vectors, hashtables, or any other data structure used in class. Any manually implemented classes beyond the Graph shall be inline.

The first block consists of an integer telling the reader how many people (nodes) to expect, followed by that many names. It is not guaranteed that only first names will be in the file. The second block consists of an integer that tells the reader how many properties to expect. Then, for that many properties, the property name is given, followed by an adjacency matrix for that property. Of course the adjacency matrix is square, with rows and columns equal to the number of nodes in the graph. No property is reflexive.

Using the information in this file, you are to construct a directed graph, where the property names label edges connecting nodes.

I obviously made up the property names after drawing the graph... hahaha

bool Graph::construct(string filename) – construct the graph from the file called filename and return false if the graph construction failed. The file will have the following structure.

Node Graph::findPerson(string name) – If there is a node with the given name in the graph, it is returned, otherwise the function returns nullptr.

bool Graph::findPath(string name, string other) – If both people are in the graph, find the shortest path between them.

Your Graph should overload operator<< such that cout << myGraph prints all the nodes in the graph, along with their related nodes. See below for an excerpt.

Your Graph also should overload operator== such that mG1 == mG2 is accurately determined.

Turn in and Grading

The Graph class should be implemented as an inline class in the file Graph.h.

This project is worth 50 points, distributed as follows:

Task Points Graph::construct properly constructs the graph from the given file. 10 Graph::findPerson successfully determines if a person is in a graph. 5 Graph::findPath correctly finds the shortest path between two nodes. It shall print out the path or state that no path could be found. 15 operator<< is correctly overloaded to print the graph. Each node and their relationship to other nodes shall be printed. 5 operator== is correctly overloaded to determine equivalence between two graphs. 5 Code is well organized, well documented, and properly formatted. Variable names are clear, and readable. 10

Explanation / Answer

need for construct a directed graph, where the property names label edges connecting nodes; either using array or linked list implementation.

Digraph(directed graph) objects represent directed graphs, which have directional edges connecting the nodes. After you create a digraph object, you can learn more about the graph by using the object functions to perform queries against the object. For example, you can add or remove nodes or edges, determine the shortest path between two nodes, or locate a specific node or edge.

G = digraph([1 1], [2 3])

e = G.Edges

G = addedge(G,2,3)

G = addnode(G,4)

plot(G)

Syntax

G = digraph

G = digraph(A)

G = digraph(A,nodenames)

G = digraph(A,NodeTable)

G = digraph(A,___,'OmitSelfLoops')

G = digraph(s,t)

G = digraph(s,t,weights)

G = digraph(s,t,weights,nodenames)

G = digraph(s,t,weights,NodeTable)

G = digraph(s,t,weights,num)

G = digraph(s,t,___,'OmitSelfLoops')

G = digraph(s,t,EdgeTable,___)

G = digraph(EdgeTable)

G = digraph(EdgeTable,NodeTable)

G = digraph(EdgeTable,___,'OmitSelfLoops')

2.Implement a data structure to meet given specifications

Design, implement, and use a graph data structure

Code::-

// Program to print BFS traversal from a given

// source vertex. BFS(int s) traverses vertices

// reachable from s.

#include<iostream>

#include <list>

using namespace std;

// This class represents a directed graph using

// adjacency list representation

class Graph

{

    int V;    // No. of vertices

    // Pointer to an array containing adjacency

    // lists

    list<int> *adj;  

public:

    Graph(int V); // Constructor

    // function to add an edge to graph

    void addEdge(int v, int w);

    // prints BFS traversal from a given source s

    void BFS(int s);

};

Graph::Graph(int V)

{

    this->V = V;

    adj = new list<int>[V];

}

void Graph::addEdge(int v, int w)

{

    adj[v].push_back(w); // Add w to v’s list.

}

void Graph::BFS(int s)

{

    // Mark all the vertices as not visited

    bool *visited = new bool[V];

    for(int i = 0; i < V; i++)

        visited[i] = false;

    // Create a queue for BFS

    list<int> queue;

    // Mark the current node as visited and enqueue it

    visited[s] = true;

    queue.push_back(s);

    // 'i' will be used to get all adjacent

    // vertices of a vertex

    list<int>::iterator i;

    while(!queue.empty())

    {

        // Dequeue a vertex from queue and print it

        s = queue.front();

        cout << s << " ";

        queue.pop_front();

        // Get all adjacent vertices of the dequeued

        // vertex s. If a adjacent has not been visited,

        // then mark it visited and enqueue it

        for (i = adj[s].begin(); i != adj[s].end(); ++i)

        {

            if (!visited[*i])

            {

                visited[*i] = true;

                queue.push_back(*i);

            }

        }

    }

}

// Driver program to test methods of graph class

int main()

{

    // Create a graph given in the above diagram

    Graph g(4);

    g.addEdge(0, 1);

    g.addEdge(0, 2);

    g.addEdge(1, 2);

    g.addEdge(2, 0);

    g.addEdge(2, 3);

    g.addEdge(3, 3);

    cout << "Following is Breadth First Traversal "

         << "(starting from vertex 2) ";

    g.BFS(2);

    return 0;

}

Run on IDE

3.

Perform analysis of algorithm performance

How long does breadth-first search take for a graph with vertex set VVV and edge set EEE? The answer is O(V+E)O(V+E)O, left parenthesis, V, plus, E, right parenthesis time.

Let's see what O(V+E)O(V+E)O, left parenthesis, V, plus, E, right parenthesis time means. Assume for the moment that |E| geq |V|?E???V?vertical bar, E, vertical bar, is greater than or equal to, vertical bar, V, vertical bar, which is the case for most graphs, especially those for which we run breadth-first search. Then |V| + |E| leq |E| + |E| = 2 cdot |E|?V?+?E???E?+?E?=2??E?vertical bar, V, vertical bar, plus, vertical bar, E, vertical bar, is less than or equal to, vertical bar, E, vertical bar, plus, vertical bar, E, vertical bar, equals, 2, dot, vertical bar, E, vertical bar. Because we ignore constant factors in asymptotic notation, we see that when |E| geq |V|?E???V?vertical bar, E, vertical bar, is greater than or equal to, vertical bar, V, vertical bar, O(V+E)O(V+E)O, left parenthesis, V, plus, E, right parenthesis really means O(E)O(E)O, left parenthesis, E, right parenthesis. If, however, we have |E| < |V|?E?<?V?vertical bar, E, vertical bar, is less than, vertical bar, V, vertical bar, then |V| + |E| leq |V| + |V| = 2 cdot |V|?V?+?E???V?+?V?=2??V?vertical bar, V, vertical bar, plus, vertical bar, E, vertical bar, is less than or equal to, vertical bar, V, vertical bar, plus, vertical bar, V, vertical bar, equals, 2, dot, vertical bar, V, vertical bar, and so O(V+E)O(V+E)O, left parenthesis, V, plus, E, right parenthesis really means O(V)O(V)O, left parenthesis, V, right parenthesis. We can put both cases together by saying that O(V+E)O(V+E)O, left parenthesis, V, plus, E, right parenthesis really means O(max(V,E))O(max(V,E)). In general, if we have parameters xxxand yyy, then O(x+y)O(x+y)O, left parenthesis, x, plus, y, right parenthesis really means O(max(x,y))O(max(x,y)).

(Note, by the way, that a graph is connected if there is a path from every vertex to all other vertices. The minimum number of edges that a graph can have and still be connected is |V|-1?V??1vertical bar, V, vertical bar, minus, 1. A graph in which |E| = |V|-1?E?=?V??1vertical bar, E, vertical bar, equals, vertical bar, V, vertical bar, minus, 1 is called a free tree.)

How is it that breadth-first search runs in O(V+E)O(V+E)O, left parenthesis, V, plus, E, right parenthesis time? It takes O(V)O(V)O, left parenthesis, V, right parenthesis time to initialize the distance and predecessor for each vertex (Theta(V)?(V) time, actually). Each vertex is visited at most one time, because only the first time that it is reached is its distance null, and so each vertex is enqueued at most one time. Since we examine the edges incident on a vertex only when we visit from it, each edge is examined at most twice, once for each of the vertices it's incident on. Thus, breadth-first search spends O(V+E)O(V+E)O, left parenthesis, V, plus, E, right parenthesis time visiting vertices.

4.Utilize Dijkstra's algorithm

5. graph class

Building a simple tree

Now let’s look how to build a tree in ActionScript. First we create the root of the tree and get an iterator pointing to this node:

var tree:TreeNode = new TreeNode("root");
var itr:TreeIterator = tree.getTreeIterator();

The root has three children, so lets add them:

for (var i:int = 0; i < 3; i++)
{
itr.appendChild("node" + i);
}

Now the root’s second child (‘node1’) has children by itself. To insert them, we first have to adjust the vertical iterator so it points to ‘node1’. First one step to the right, then one step down the tree:

itr.nextChild();
itr.down();

Now we can add ‘node3’ and ‘node4’, this time in a reverse order:

itr.prependChild("node" + 3);
itr.prependChild("node" + 4);

The first time we add a child node to an empty node, the horizontal iterator is automatically initialized to point to the first child, which in this case is ‘node4’. So to create ‘node5’ and ‘node6’ we only need to go another step down.

itr.down();
itr.appendChild("node" + 5);
itr.appendChild("node" + 6);

Finally we want to add ‘node7’. Therefore we ‘bubble up’ the tree until we arrive at the root node, go to the rightmost child, one step down and add it:

itr.root();
itr.childEnd();
itr.down();
itr.appendChild("node" + 7);

The dump() method invoked on the root node prints out the complete tree, as you can see it matches the tree above.

[TreeNode > (root) has 3 child nodes, data=root]
+---[TreeNode > (leaf), data=node0]
+---[TreeNode > has 2 child nodes, data=node1]
| +---[TreeNode > has 2 child nodes, data=node4]
| | +---[TreeNode > (leaf), data=node5]
| | +---[TreeNode > (leaf), data=node6]
| +---[TreeNode > (leaf), data=node3]
+---[TreeNode > has 1 child nodes, data=node2]
| +---[TreeNode > (leaf), data=node7]

Preorder and postorder traversal

Now that you have created a tree structure, you need a way of traversing the nodes so you access the node’s data. There are two common recursive algorithms for doing this. The preorder function first visits the node that is passed to the function and then loops through each child calling the preorder function on each child. The postorder on the other hand does the opposite: It visits the current node after its child nodes.
To see this in action just click a node in the demo below. The numbers indicate the order in which the nodes are visited.

The TreeNode class also supports a regular iterator using hasNext() and next(). This matches the preorder iterator, but is implemented in a non-recursive way.

// Program to print BFS traversal from a given

// source vertex. BFS(int s) traverses vertices

// reachable from s.

#include<iostream>

#include <list>

using namespace std;

// This class represents a directed graph using

// adjacency list representation

class Graph

{

    int V;    // No. of vertices

    // Pointer to an array containing adjacency

    // lists

    list<int> *adj;  

public:

    Graph(int V); // Constructor

    // function to add an edge to graph

    void addEdge(int v, int w);

    // prints BFS traversal from a given source s

    void BFS(int s);

};

Graph::Graph(int V)

{

    this->V = V;

    adj = new list<int>[V];

}

void Graph::addEdge(int v, int w)

{

    adj[v].push_back(w); // Add w to v’s list.

}

void Graph::BFS(int s)

{

    // Mark all the vertices as not visited

    bool *visited = new bool[V];

    for(int i = 0; i < V; i++)

        visited[i] = false;

    // Create a queue for BFS

    list<int> queue;

    // Mark the current node as visited and enqueue it

    visited[s] = true;

    queue.push_back(s);

    // 'i' will be used to get all adjacent

    // vertices of a vertex

    list<int>::iterator i;

    while(!queue.empty())

    {

        // Dequeue a vertex from queue and print it

        s = queue.front();

        cout << s << " ";

        queue.pop_front();

        // Get all adjacent vertices of the dequeued

        // vertex s. If a adjacent has not been visited,

        // then mark it visited and enqueue it

        for (i = adj[s].begin(); i != adj[s].end(); ++i)

        {

            if (!visited[*i])

            {

                visited[*i] = true;

                queue.push_back(*i);

            }

        }

    }

}

// Driver program to test methods of graph class

int main()

{

    // Create a graph given in the above diagram

    Graph g(4);

    g.addEdge(0, 1);

    g.addEdge(0, 2);

    g.addEdge(1, 2);

    g.addEdge(2, 0);

    g.addEdge(2, 3);

    g.addEdge(3, 3);

    cout << "Following is Breadth First Traversal "

         << "(starting from vertex 2) ";

    g.BFS(2);

    return 0;

}

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote