PROJECT 7 Shortest and Longest Paths
PROJECT 7 Shortest and Longest Paths
莫海
ID:228801136
Introduction
Dijkstra's algorithm stands as a prominent solution for graph traversal, specifically addressing
the single source shortest path problem. In this implementation, we extend Dijkstra's
algorithm to not only calculate the shortest distances between vertices but also to track the
longest path within a grid. By utilizing a priority queue to manage vertices, the algorithm
efficiently explores the graph, updating distances when shorter paths are found. This
comprehensive approach allows us to uncover both the shortest and longest paths within the
grid
1. Graph Representation
In our code, the grid is a graphical representation of a connected network. The structured
arrangement of vertices within the two-dimensional array mirrors the spatial relationships
between elements in various scenarios.
2. Vertex-Cell Mapping
Every cell in the grid uniquely represents a vertex. The association between vertex numbers
and grid cells establishes a direct correspondence, facilitating the translation of abstract graph
concepts into tangible grid structures.
3. Edge Definition
Connections between adjacent cells delineate the graph's edges. These edges define the
pathways and relationships between vertices, crucial for understanding the connectivity and
pathways within the represented scenario.
1. Algorithmic Adaptation
Dijkstra's algorithm, a renowned graph traversal technique, is extended to accommodate grid-
based scenarios. The algorithm maintains a priority queue of vertices, prioritizing minimum
distances, and iteratively explores the grid, updating distances and tracking the longest path.
2. Efficiency in Computation
The adaptation of Dijkstra's algorithm to grid-based graphs enhances computational
efficiency. By leveraging the grid structure, the algorithm minimizes redundant calculations,
optimizing the determination of both shortest paths and the longest route.
2. Applications in Decision-Making
Identifying the longest path in a grid aligns with broader objectives related to urban planning,
transportation network analysis, and infrastructure optimization. The dual functionality of
computing shortest distances and longest paths equips users with valuable insights for
informed decision-making.
3. Optimization and Resource Allocation
The primary objective is to offer a reliable and efficient solution that not only calculates
shortest distances but also reveals the longest path within the grid. This dual capability
empowers users to optimize transportation routes, identify critical paths, and allocate
resources judiciously.
Grid-based graphs, as represented in our code, provide a versatile framework for modeling
real-world scenarios. The extended Dijkstra's algorithm, tailored to exploit the grid structure,
emerges as a powerful tool for simultaneously calculating shortest distances and identifying
the longest path. This comprehensive approach contributes to a myriad of applications,
ranging from urban planning to infrastructure optimization, enriching decision-making
..processes and resource allocation strategies
Chapter 3: Problem Solution
In the context of Dijkstra's algorithm implementation, the grid plays a pivotal role, serving as
the foundation for the graph representation. This section provides an extensive explanation
of the grid creation process, detailing how a two-dimensional array is generated with unique
vertex numbers assigned to each cell. The dimensions of the grid are determined by
predefined constants ROWS and COL
The grid creation process is executed through the `create_grid` function within the
`DijkstraGrid` class. This function initializes the two-dimensional array, ensuring that each cell
corresponds to a unique vertex. The steps involved in this process are as follows:
A blank two-dimensional array is created to store the vertices, with the dimensions specified
by the constants ROWS and COLS. The array is initially empty, and each element is initialized
to zero
python```
grid = [[0 for j in range(COLS)] for i in range(ROWS)]
```
The function then iterates over each cell in the array, assigning a unique vertex
number to it. The vertex numbers are determined based on the row and column
indices, ensuring a systematic assignment
python```
vertex = 0
:for i in range(ROWS)
:for j in range(COLS)
grid[i][j] = vertex
vertex += 1
```
Once all cells have been assigned unique vertex numbers, the grid creation process is
complete. The resulting two-dimensional array now serves as the graphical
representation of the vertices within the algorithm
The grid creation process is a crucial step in preparing the data structure for Dijkstra's
algorithm. By systematically assigning unique vertex numbers to each cell, the
algorithm gains the necessary foundation to explore the connectivity of the graph.
This grid, represented as a two-dimensional array, facilitates efficient traversal and
computation of shortest distances and the longest path. The subsequent application
of Dijkstra's algorithm on this grid ensures a comprehensive analysis of the graph's
..topology
Chapter 4: Implementation and Pseudo Code
Two-dimensional Array
The grid is represented as a two-dimensional array. This array stores the vertices and
their corresponding indexes in the grid. Each cell in the array corresponds to a unique
vertex, forming the basis for the graph representation
Priority Queue
A priority queue is utilized to efficiently retrieve the vertex with the minimum distance
during each iteration of Dijkstra's algorithm. This priority queue is implemented using
a binary heap, ensuring that the vertex with the smallest distance is always at the
front of the queue. The PriorityQueue is essential for optimizing the selection of
vertices during the traversal
2. Creating the Grid
The `create_grid` function initializes the grid based on the specified number of rows
and columns. It iterates over each position in the grid, assigns a unique vertex value to
it, and increments the vertex value for the next position. This ensures that each cell in
the grid corresponds to a unique vertex, creating a structured representation of the
graph
Initialization
The `calculate_distances` function initializes an array called `distances` with
`Integer.MAX_VALUE` for all vertices except the start vertex, which is set to 0. This
array stores the shortest distances from the start vertex to each vertex in the grid
It initializes a variable called `longestPath` to keep track of the longest path found
during the algorithm
A priority queue called `pq` is created to store vertices along with their distances. The
start vertex is added to the priority queue with a distance of 0
Iterative Process
The algorithm continues until the priority queue becomes empty
In each iteration, the vertex with the minimum distance is extracted from the priority
queue
The algorithm checks the neighboring vertices (right and below) of the current vertex
and calculates the distance to reach those vertices from the start vertex
If the newly calculated distance is smaller than the current distance stored in the
`distances` array, the distance is updated, and the vertex is added to the priority
.queue with the new distance
The algorithm also keeps track of the longest path found so far by updating the
`longestPath` variable if a longer path is discovered
Result
Once all vertices have been processed, the function returns an instance of the `Result`
class, which contains the `distances` array and the `longestPath` value
The `pq` priority queue stores objects of the `VertexDistance` class, representing a
vertex along with its distance from the start vertex.
The `VertexDistance` class implements the `Comparable` interface, allowing the
.priority queue to prioritize vertices based on their distances
The `distance` variable in the `VertexDistance` class represents the distance of a vertex
.from the start vertex
During each iteration of the algorithm, the vertex with the minimum distance is
extracted from the priority queue (`pq.poll()`), and its neighboring vertices are
.processed to update their distances if necessary
The `display_grid` function prints the grid to the console, displaying the vertex values
.in a formatted manner
The `display_schedule` function prints a schedule that shows the starting vertex, the
directed vertices, and their corresponding distances. It iterates over the grid and
prints the schedule for each vertex. Additionally, it displays the longest path found
during the algorithm
Pseudocode
The `main` function initializes the grid, specifies the starting vertex, and calls the
`calculate_distances` function to obtain the distances and the longest path. It then
displays the grid, the distances, and the longest path using the `display_grid` and
.`display_schedule` functions, respectively
Expected Output:
The distances from the starting vertex to all other vertices
A schedule showing the starting vertex, directed vertices, and corresponding
distances.
The longest path within the grid.
Expected Output:
Similar to Test 1, but for the larger grid.
Expected Output:
Similar to Test 1, but for the random grid.
Test 4: Edge Case - Single Vertex
Input:
A grid with only one vertex
Expected Output:
The distances should show that the only vertex has a distance of 0
The longest path is 0
Expected Output:
The program should gracefully handle this case, possibly with an appropriate message.
Test Execution
Test 1
python
Copy code
DijkstraGrid.ROWS = 4
DijkstraGrid.COLS = 5
)(DijkstraGrid.main
Test 2
python
Copy code
DijkstraGrid.ROWS = 6
DijkstraGrid.COLS = 6
)(DijkstraGrid.main
Test 3
python
Copy code
DijkstraGrid.ROWS = 5
DijkstraGrid.COLS = 4
)(DijkstraGrid.main
Test 4
python
Copy code
DijkstraGrid.ROWS = 1
DijkstraGrid.COLS = 1
)(DijkstraGrid.main
Test 5
python
Copy code
DijkstraGrid.ROWS = 0
DijkstraGrid.COLS = 0
)(DijkstraGrid.main
Results Analysis
Observations
Review the distances from the starting vertex to other vertices.
Analyze the schedule to ensure correctness in directed vertices and distances.
Verify that the longest path is accurately identified.
The algorithm is expected to perform consistently across various grid sizes and
configurations.
The schedule should provide insights into how the algorithm navigates the grid.
Summary
The testing and analysis will provide a comprehensive understanding of the algorithm's
behavior in different scenarios, ensuring its reliability and adaptability. It will also highlight any
potential edge cases that need to be addressed for a robust implementation.
Chapter 6: Project Experience
2. Grid Specifics
Navigating the intricacies of translating abstract graph concepts into grid structures
deepens the understanding of graph representation. Each cell as a vertex and the
connections between cells as edges adds a layer of complexity and practicality to the
algorithm.
- Visualization Skills
1. Grid Visualization
The inclusion of functions to visualize grid structures is pivotal. The ability to witness
the grid dynamically fosters a deeper understanding of graph connectivity. Visual cues
aid in grasping the relationships between vertices and comprehending the algorithm's
execution.
2. Iterative Exploration
Observing the step-by-step exploration of the grid during the algorithm's execution
enhances visualization skills. The iterative nature of Dijkstra's algorithm becomes
tangible, providing a visual narrative of how distances are updated and the longest
path is tracked.
1. Algorithmic Flexibility
The project extends the conventional Dijkstra's algorithm by incorporating longest path
tracking. This showcases the algorithm's flexibility, highlighting its adaptability to different
analytical needs beyond the standard shortest path determination.
2. Comprehensive Analysis
The ability to track the longest path adds depth to the algorithm's analytical capabilities. It
opens avenues for comprehensive graph analysis, especially in scenarios where understanding
the connectivity beyond the immediate shortest paths is crucial.
Hands-On Learning
1. Real-World Applications
Interacting with the code in practical scenarios bridges the gap between theoretical
knowledge and real-world applications. The project's hands-on nature allows for a holistic
understanding of algorithmic processes and their relevance in solving complex problems.
Engaging with the code fosters iterative problem-solving skills. Tackling challenges
related to grid-based graphs, algorithmic adaptations, and visualization instills a
The project experience goes beyond mere code implementation, offering a journey of
discovery and learning. From algorithmic intricacies to practical visualization and
hands-on priority queue manipulation, the project provides a comprehensive
exploration of Dijkstra's algorithm in the context of grid-based graphs. This newfound
understanding lays a solid foundation for future algorithmic endeavors and real-world
problem-solving
CHAPTER 7: THE CODE
import heapq
:class DijkstraGrid
ROWS = 4
COLS = 5
staticmethod@
:)(def main
grid = DijkstraGrid.create_grid(DijkstraGrid.ROWS, DijkstraGrid.COLS)
start_vertex = 0
result = DijkstraGrid.calculate_distances(grid, start_vertex)
staticmethod@
:def create_grid(rows, cols)
grid = [[i * cols + j for j in range(cols)] for i in range(rows)]
return grid
staticmethod@
:def calculate_distances(grid, start_vertex)
total_vertices = len(grid) * len(grid[0])
distances = [float('inf')] * total_vertices
distances[start_vertex] = 0
longest_path = 0
pq = [(0, start_vertex)]
:while pq
distance, vertex = heapq.heappop(pq)
:if distance > longest_path
longest_path = distance
staticmethod@
:def display_grid(grid)
:for row in grid
:for vertex in row
print(f"{vertex:<4}", end="")
)(print
)(print
staticmethod@
:def display_schedule(grid, distances, longest_path)
)"+--------------+--------------+--------------+"(print
print("| Starting Vtx | Directed Vtx | Distance |")
)"+--------------+--------------+--------------+"(print
:for i in range(len(grid))
:for j in range(len(grid[0]))
start_vertex = 0
directed_vertex = 0
distance = 0
)"+--------------+--------------+--------------+"(print
print("Longest path:", longest_path)
:class VertexDistance
:def __init__(self, vertex, distance)
self.vertex = vertex
self.distance = distance
:class Result
:def __init__(self, distances, longest_path)
self.distances = distances
self.longest_path = longest_path