DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Universal Implementation of BFS, DFS, Dijkstra, and A-Star Algorithms
  • Solving Three Medium-Level Coding
  • Blue Skies Ahead: An AI Case Study on LLM Use for a Graph Theory Related Application
  • Predicting Ad Viewability With XGBoost Regressor Algorithm

Trending

  • A Simple, Convenience Package for the Azure Cosmos DB Go SDK
  • Detection and Mitigation of Lateral Movement in Cloud Networks
  • FIPS 140-3: The Security Standard That Protects Our Federal Data
  • Beyond Code Coverage: A Risk-Driven Revolution in Software Testing With Machine Learning
  1. DZone
  2. Data Engineering
  3. AI/ML
  4. Algorithm of the Week: Graphs and Their Representation

Algorithm of the Week: Graphs and Their Representation

Although this post is supposed to be about algorithms I’ll cover more on graphs and their computer representation.

By 
Stoimen Popov user avatar
Stoimen Popov
·
Sep. 04, 12 · Tutorial
Likes (8)
Comment
Save
Tweet
Share
58.6K Views

Join the DZone community and get the full member experience.

Join For Free

Introduction

Although this post is supposed to be about algorithms I’ll cover more on graphs and their computer representation. I consider this very important, because there are lots of problems solved by using graphs and it is important to understand different types of representation.

First of all let’s try to explain what is a graph?

A graph is a specific data structure known in the computer science, that is often used to give a model of different kind of problems where a set of objects relate to each other in some way . For instance, trees are mainly used in order to represent a well-structured hierarchy, but that isn’t enough when modeling objects of the same type. Their relation isn’t always hierarchical! A typical example of graph is a geo map, where we have cities and the roads connecting them. In fact most of the problems solved with graphs relate to finding the shortest or longest path.

Although this is one very typical example actually a huge set of problems is can be solved by using graphs.

Graph & Tree

 


As shown on the image above the graph is a “more complex” data structure than the ordinary tree. Thus a graph supports cycles, while the tree doesn’t. In the other hand the nodes of a tree are defined by their parents and children, while in a graph that isn’t true.

In this case each graph is defined by its edges and its vertices. In most of the cases, in order to model and solve our problem, we can assume that the vertices are consecutive numbers starting from (1, or 0 in case of 0 based arrays, as we will see later).

As we see each tree is a graph, but not every graph is a tree.

In first place we must now that graphs can be divided in several categories.

They can be undirected and directed. An undirected graph means that in case there is an edge between the nodes i and j we shell assume that there is a path from i to j, as well as from j to i. In the case of directed graph, we’ll assume that if (i,j) exists there only path from node i to node j and there’s no path between j and i.

Directed Graph

 

In this example we assume that all the edges are the same, which in practice isn’t always true. Taking a look back to the example of cities and roads, we know that the roads between different cities are different. In many cases their length in kilometers or miles are defining the algorithm (for instance longest/shortest path). To model this we can use weighted graphs, where each edge is associated with a weight. Note that, in the example below, the weight can be even a negative number. Of course in the example of cities and road that can’t be true, because we can’t have negative distance, but in some cases (let’s say where the path saves us some money) we can have negative values.

Weithened Graph

 

To complete the whole image, let’s give another example which will make the difference between graphs and trees even bigger. Graphs can be connected and disconnected. This means that the graph is constructed out of two or more sub-graphs without a path between these components. You can think of a disconnected graph as for the roads of the UK and France, since they aren’t connected by land.

Connected Graph

 

Overview

We know what a graph is in general. However we need an appropriate way to represent them in our programs.

There are many type of representation, which can be very useful in some cases and very useless in others. Two of the mostly used types of representation are the adjacency matrix and the adjacency list.

Adjacency Matrix

In the first case we store a matrix (two-dimensional array) with size NxN, where N is the number of vertices. This means that for each edge between the vertices i and j we have the value of 1 (A[i][j] = 1), and 0 otherwise.

Undirected Graph & Adjacency Matrix

 

In case of directed graph, we can use 1 for the edge (i,j) and -1 for (j,i) in case the edge is directed from i to j.

Directed Graph & Adjacency Matrix

 

For a weighted directed graph we can put the weights instead of 1s.

Weighted Graph & Adjacency Matrix

 

Adjacency Lists

Another useful representation of graphs are the adjacency lists. In this case for each vertex we store a linked lists consisting of all of his successors.

Directed Graph & Adjacency List

 

Although these two ways are the mostly used, there are also some other type of representations. Such a useful representation is storing only the connectivity between two vertices i and j only if there’s a path between them. Of course this can help us answer the question “is there a path between i and j” in O(1), but unfortunately we lose the information about the graph and we can’t build it again out of this representation.

Complexity

Most of the basic operations in a graph are:

  1. Adding an edge;
  2. Deleting an edge;
  3. Answering the question “is there an edge between i and j”;
  4. Finding the successors of a given vertex;
  5. Finding (if exists) a path between two vertices;

Thus depending on the representation these operations can have different complexities. In case that we’re using adjacency matrix we have:

  1. Adding an edge – O(1);
  2. Deleting an edge – O(1);
  3. Answering the question “is there an edge between i and j” – O(1);
  4. Finding the successors of a given vertex – O(n);
  5. Finding (if exists) a path between two vertices – O(n2);

While for an adjacency list we can have:

  1. Adding an edge – O(log(n));
  2. Deleting an edge – O(log(n));
  3. Answering the question “is there an edge between i and j” – O(log(n));
  4. Finding the successors of a given vertex – O(k), where “k” is the length of the lists containing the successors of i;
  5. Finding (if exists) a path between two vertices – O(n+m) – where m <= n;

We now see that depending of the representation of the graph we can have different complexities for the same operations. This is very important while trying to solve a problem and can be crucial while chosing the algorithm.

Graph (Unix) Algorithm

Published at DZone with permission of Stoimen Popov, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Universal Implementation of BFS, DFS, Dijkstra, and A-Star Algorithms
  • Solving Three Medium-Level Coding
  • Blue Skies Ahead: An AI Case Study on LLM Use for a Graph Theory Related Application
  • Predicting Ad Viewability With XGBoost Regressor Algorithm

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!