Skip to content

Commit

Permalink
Initial commit: release v1.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
kushalv238 committed Jul 27, 2024
0 parents commit 003890b
Show file tree
Hide file tree
Showing 11 changed files with 883 additions and 0 deletions.
42 changes: 42 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# IntelliJ IDEA specific files
.idea/
*.iws
*.iml
*.ipr

# Compiled class file
*.class

# Log file
*.log

# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar

# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*

# Maven specific files
target/
pom.xml
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties

# Eclipse specific files
.metadata
bin/
tmp/

# Other files
.DS_Store
*.swp
*.swo
30 changes: 30 additions & 0 deletions Graph Concepts.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
Graph Concepts for future reference

A. Graph Representations: Adjacency Matrix, Adjacency List, Incidence Matrix

B. Types of Graphs: Directed and Undirected Graphs, Weighted and Unweighted Graphs, Cyclic and Acyclic Graphs, Connected and Disconnected Graphs, Bipartite Graphs, Complete Graphs

C. Graph Algorithms
1. Traversal Algorithms: DFS, BFS
2. Shortest Path Algorithms: Dijkstra's, Bellman-Ford, Floyd-Warshall
3. Minimum Spanning Tree (MST) Algorithms: Prim's Algorithm, Kruskal's Algorithm
4. Topological Sorting
5. Strongly Connected Components (SCC)
6. Graph Coloring
7. Network Flow Algorithms: Ford-Fulkerson Algorithm, Edmonds-Karp Algorithm
8. Cycle Detection: Union-Find Algorithm, DFS
9. Eulerian and Hamiltonian Paths/Cycles
10. Graph Matching: Maximum Bipartite Matching, Hungarian Algorithm

D. Advanced Topics
1. Planar Graphs
2. Graph Isomorphism
3. Dynamic Graph Algorithms
4. Graph Databases

E. Practical Applications
1. Social Networks
2. Computer Networks
3. Geographical Information Systems (GIS)
4. Scheduling Problems
5. Recommendation Systems
32 changes: 32 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Graph Algorithms Library

Welcome to the Graph Algorithms Library! 🎉

This Java utility library for Graph data structure contains support for various types of graphs viz. Directed/Undirected, Weighted/Unweighted Graphs, Cyclic/Acyclic Graphs, Connected/Disconnected Graphs, Bipartite Graphs, Complete Graphs etc. With multiple algorithms to use with the Graph data structure, independent use cases of the nodes & edges is also possible for custom algorithms and projects.

## Algorithms

- **Breadth-First Search (BFS)**
- **Depth-First Search (DFS)**
- **Dijkstra's Algorithm**

## Contributing

With a dream of adding this library in the official Java Collections Framework, I am keeping this project open to contributions ☁️✨. Got an idea for an awesome new feature? Found a bug that's been bugging you? Want to add some witty comments of your own? We'd love to hear from you!

1. Fork the repository.
2. Create a new branch (git checkout -b feature-branch).
3. Make your changes.
4. Commit your changes (git commit -am 'Add new feature').
5. Push to the branch (git push origin feature-branch).
6. Create a new Pull Request.

## Contact
If you have any questions, suggestions, or just want to say hi, feel free to reach out:

- Email: kushalv238@gmail.com
- LinkedIn: [kushal-vadodaria](https://www.linkedin.com/in/kushal-vadodaria/)

***

Remember, life is just like a graph: complex, intertwined and confusing but there is always a way around. Sometimes you just need to take a step back (like a breadth-first search) to see the bigger picture, but other times you need to dive deep (like a depth-first search) to uncover the hidden treasures. Happy Graphing! 🚀
96 changes: 96 additions & 0 deletions src/main/java/graph/DirectedGraph.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package graph;

import java.util.ArrayList;
import java.util.List;

/**
* Represents a directed graph.
*
* @param <T> the type of the node data
*/
public class DirectedGraph<T> implements Graph<T> {
private final List<Node<T>> nodes;

public DirectedGraph() {
this.nodes = new ArrayList<>();
}

@Override
public List<Node<T>> getNodes() {
return new ArrayList<>(nodes); // Return a copy to prevent external modification
}

@Override
public Node<T> addNode(T data) {
if (data == null) {
throw new IllegalArgumentException("Node data cannot be null");
}

Node<T> node = new Node<>(data);
nodes.add(node);
return node;
}

@Override
public Node<T> addNode(T data, String name) {
Node<T> node = new Node<>(data, name);
nodes.add(node);
return node;
}

@Override
public void connect(Node<T> fromNode, Node<T> toNode, double weight) {
validateNodesInGraph(fromNode, toNode);
fromNode.connect(toNode, weight);
}

@Override
public void disconnect(Node<T> fromNode, Node<T> toNode) {
validateNodesInGraph(fromNode, toNode);
fromNode.disconnect(toNode);
}

@Override
public void updateNodeData(Node<T> node, T newData) {
if (node == null || newData == null) {
throw new IllegalArgumentException("Node and new data cannot be null");
}

if (!nodes.contains(node)) {
throw new IllegalArgumentException("Node must be part of the graph");
}

node.setData(newData);
}

@Override
public void updateEdgeWeight(Node<T> fromNode, Node<T> toNode, double newWeight) {
validateNodesInGraph(fromNode, toNode);

for (Edge<T> edge : fromNode.getEdges()) {
if (edge.getToNode().equals(toNode)) {
edge.setWeight(newWeight);
return;
}
}

throw new IllegalArgumentException("Edge does not exist");
}

/**
* Validates that both nodes are part of the graph.
*
* @param fromNode the starting node
* @param toNode the ending node
* @throws IllegalArgumentException if either node is not part of the graph
*/
private void validateNodesInGraph(Node<T> fromNode, Node<T> toNode) {
if (fromNode == null || toNode == null) {
throw new IllegalArgumentException("Nodes cannot be null");
}

if (!nodes.contains(fromNode) || !nodes.contains(toNode)) {
throw new IllegalArgumentException("Both nodes must be part of the graph");
}
}
}
56 changes: 56 additions & 0 deletions src/main/java/graph/Edge.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package graph;

/**
* Represents an edge in a graph connecting two nodes with a weight.
*
* @param <T> the type of the node data
*/
public class Edge<T> {
private final Node<T> fromNode;
private final Node<T> toNode;
private double weight;

/**
* Constructs an edge with a specified weight.
*
* @param fromNode the starting node
* @param toNode the ending node
* @param weight the weight of the edge
* @throws IllegalArgumentException if fromNode or toNode is null
*/
Edge(Node<T> fromNode, Node<T> toNode, double weight) {
if (fromNode == null || toNode == null) {
throw new IllegalArgumentException("fromNode and toNode cannot be null");
}

this.fromNode = fromNode;
this.toNode = toNode;
this.weight = weight;
}

/**
* Constructs an edge with a default weight of 1.0.
*
* @param fromNode the starting node
* @param toNode the ending node
*/
Edge(Node<T> fromNode, Node<T> toNode) {
this(fromNode, toNode, 1.0);
}

public double getWeight() {
return weight;
}

public void setWeight(double weight) {
this.weight = weight;
}

public Node<T> getFromNode() {
return fromNode;
}

public Node<T> getToNode() {
return toNode;
}
}
127 changes: 127 additions & 0 deletions src/main/java/graph/Graph.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
package graph;

import java.util.List;

/**
* Represents a generic graph.
*
* @param <T> the type of the node data
*/
public interface Graph<T> {

List<Node<T>> getNodes();

/**
* Adds a new node with the specified data to the graph.
*
* @param data the data of the new node
* @return the newly added node
*/
Node<T> addNode(T data);

/**
* Adds a new node with the specified data and name to the graph.
*
* @param data the data of the new node
* @param name the name of the new node
* @return the newly added node
*/
Node<T> addNode(T data, String name);

/**
* Connects two nodes in the graph with a specified weight.
*
* @param fromNode the starting node
* @param toNode the ending node
* @param weight the weight of the connection
* @throws IllegalArgumentException if either node is not part of the graph
*/
void connect(Node<T> fromNode, Node<T> toNode, double weight);

/**
* Connects two nodes in the graph with a default weight of 1.0.
*
* @param fromNode the starting node
* @param toNode the ending node
*/
default void connect(Node<T> fromNode, Node<T> toNode) {
this.connect(fromNode, toNode, 1.0);
}

/**
* Connects a node to multiple nodes with specified weights.
*
* @param fromNode the starting node
* @param toNodes the list of ending nodes
* @param weights the list of weights
* @throws IllegalArgumentException if fromNode is null, or if toNodes or weights are null or different sizes
*/
default void connect(Node<T> fromNode, List<Node<T>> toNodes, List<Double> weights) {
if (fromNode == null || toNodes == null || weights == null || toNodes.size() != weights.size()) {
throw new IllegalArgumentException("Invalid nodes or weights");
}
for (int i = 0; i < toNodes.size(); i++) {
this.connect(fromNode, toNodes.get(i), weights.get(i));
}
}

/**
* Connects a node to multiple nodes with a default weight of 1.0.
*
* @param fromNode the starting node
* @param toNodes the list of ending nodes
* @throws IllegalArgumentException if fromNode or toNodes is null
*/
default void connect(Node<T> fromNode, List<Node<T>> toNodes) {
if (fromNode == null || toNodes == null) {
throw new IllegalArgumentException("Invalid nodes");
}
for (Node<T> toNode : toNodes) {
this.connect(fromNode, toNode, 1.0);
}
}

/**
* Disconnects two nodes in the graph.
*
* @param fromNode the starting node
* @param toNode the ending node
* @throws IllegalArgumentException if fromNode or toNode is null
*/
void disconnect(Node<T> fromNode, Node<T> toNode);

/**
* Disconnects a node from multiple nodes.
*
* @param fromNode the starting node
* @param toNodes the list of ending nodes
* @throws IllegalArgumentException if fromNode or toNodes is null
*/
default void disconnect(Node<T> fromNode, List<Node<T>> toNodes) {
if (fromNode == null || toNodes == null) {
throw new IllegalArgumentException("Invalid nodes");
}
for (Node<T> toNode : toNodes) {
this.disconnect(fromNode, toNode);
}
}

/**
* Updates data of a node
*
* @param node the node whose data needs to be updated
* @param newData the updated new data
* @throws IllegalArgumentException if node or newData is null or node is not part of this graph
*/
void updateNodeData(Node<T> node, T newData);

/**
* Updates weight of an edge
*
* @param fromNode the starting node of the edge
* @param toNode the ending node of the edge
* @param newWeight the updated new weight
* @throws IllegalArgumentException if either start and end nodes are not part of the graph or the edge doesn't exist between the two nodes
*/
void updateEdgeWeight(Node<T> fromNode, Node<T> toNode, double newWeight);
}
Loading

0 comments on commit 003890b

Please sign in to comment.