0% found this document useful (0 votes)
16 views13 pages

Lps 9

Uploaded by

Dhrrishith Vikal
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
16 views13 pages

Lps 9

Uploaded by

Dhrrishith Vikal
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 13

DESIGN AND ANALYSIS OF ALGORITHMS

LAB PRACTICE SHEET 9

ASWATH S
22BPS1009

3. Given the coordinates of n points in a 2-dimensional plane, design an


algorithm to identify the set of points which are collinear. There may be more
than one set of points which are collinear. Your algorithm should print all the
sets of points which are collinear. Analyse your algorithm with the time
complexity.

Problem Statement:
Given the coordinates of nn points in a 2-dimensional plane, design an
algorithm to identify and print all sets of points that are collinear. A set of
points is considered collinear if all the points in that set lie on the same straight
line. There may be more than one such set of collinear points.

Input and Output:


• Input: A list of points P={(x1,y1),(x2,y2),…,(xn,yn)}P={(x1,y1),(x2,y2),…,(xn
,yn)}, where each point (xi,yi)(xi,yi) is a pair of integers representing its
coordinates in the 2-dimensional plane.
• Output: A list of lists, where each sublist represents a set of collinear
points. Each set contains points that lie on the same straight line. If no
sets of collinear points with more than two points exist, output an empty
list.

Pseudocode:
function find_collinear_sets(points):
collinear_sets = []
n = len(points)

for i in range(n):
slope_map = empty dictionary
for j in range(i + 1, n):
slope = calculate_slope(points[i], points[j])

if slope is not in slope_map:


slope_map[slope] = {points[i], points[j]}
else:
slope_map[slope].add(points[j])

for slope in slope_map:


if length of slope_map[slope] > 2:
add slope_map[slope] to collinear_sets

return collinear_sets

function calculate_slope(point1, point2):


dx = point2.x - point1.x
dy = point2.y - point1.y

if dx == 0:
return 'vertical' // Return a unique value for vertical lines
else:
return dy / dx

Logic and Illustration of Pseudocode:


The core idea is to leverage the concept of slopes between pairs of points:
1. For each point P[i]P[i], calculate the slope it makes with every other
point P[j]P[j] (where j>ij>i).
2. Store each unique slope as a key in a dictionary (slope_map), where the
value associated with each slope is a set of points that share that slope
with P[i]P[i]. This set effectively captures points that are collinear
with P[i]P[i] for that slope.
3. If a slope has more than two points associated with it in slope_map, this
group of points forms a collinear set, which we add to collinear_sets.
4. Repeat this process for every point P[i]P[i] as a base point to find all
possible collinear sets.
Example
Consider points: [(1,2),(2,3),(3,4),(0,0),(1,1)][(1,2),(2,3),(3,4),(0,0),(1,1)].
1. Start with point (1,2)(1,2):
• Calculate slopes with each subsequent point.
2. For each unique slope, check if there are more than two points sharing
that slope.
3. Continue for all other points as the base point.

Time Complexity:
The time complexity of this approach is O(n2)O(n2):
• For each point, we check slopes with n−1n−1 other points,
yielding O(n2)O(n2) comparisons.
• Inserting into and accessing elements in a dictionary is on
average O(1)O(1), so operations on the slope_map are manageable
within O(n)O(n) per base point.

Space Complexity:
The space complexity is O(n2)O(n2):
• We maintain a dictionary (slope_map) to store the slopes between each
pair, which can contain up to O(n2)O(n2) slope entries in the worst case.
• The output collinear_sets will store groups of points, requiring additional
space depending on the number of collinear sets found.

Proof of Correctness:
1. Completeness: This approach captures all sets of collinear points by
using slopes. If three or more points are collinear, they will have the
same slope with respect to any base point.
2. Uniqueness: Using a set for each slope in slope_map ensures that we
don't duplicate points within the same collinear set.

Conclusion:
This algorithm efficiently identifies all sets of collinear points among a set
of nn points in O(n2)O(n2) time. It leverages the property of slopes between
pairs of points to group collinear points together.
8. Given the coordinates of the end points of n line segments, design an
algorithm to retrun the line segments which intersect. If more than one pair of
line-segments intersect, your algorithm should return all such pairs. Analyse
your algorithm with the time complexity.

Problem Statement:
Given the coordinates of the endpoints of nn line segments in a 2-dimensional
plane, design an algorithm to identify and return all pairs of line segments that
intersect. Each line segment is defined by its two endpoints. If more than one
pair of line segments intersects, the algorithm should return all such pairs.

Input and Output:


• Input: A list of line
segments S={[(x1a,y1a),(x1b,y1b)],[(x2a,y2a),(x2b,y2b)],…,[(xna,yna),(xn
b,ynb)]}S={[(x1a,y1a),(x1b,y1b)],[(x2a,y2a),(x2b,y2b)],…,[(xna,yna),(xnb
,ynb)]}, where each line segment is represented by two endpoints.
• Output: A list of tuples, where each tuple contains the indices of two line
segments that intersect.

Pseudocode:
function find_intersections(segments):
events = []
for i in range(len(segments)):
segment = segments[i]
# Add enter and exit events for each segment
events.append((segment[0], 'enter', i))
events.append((segment[1], 'exit', i))
# Sort events by x-coordinates, with ties broken by y-coordinates
events.sort()

active_segments = BalancedBST() # A balanced BST to store active segments


by y-coordinate
intersecting_pairs = []

for event in events:


point, event_type, segment_index = event
segment = segments[segment_index]

if event_type == 'enter':
# Add segment to active list and check for intersections
active_segments.insert(segment)
above, below = active_segments.find_neighbors(segment)

if above and do_intersect(above, segment):


intersecting_pairs.append((above, segment))
if below and do_intersect(below, segment):
intersecting_pairs.append((below, segment))

elif event_type == 'exit':


# Remove segment from active list and check neighbors for intersections
above, below = active_segments.find_neighbors(segment)
active_segments.remove(segment)
if above and below and do_intersect(above, below):
intersecting_pairs.append((above, below))

return intersecting_pairs

function do_intersect(segment1, segment2):


# Check if two segments intersect using orientation tests
p1, q1 = segment1
p2, q2 = segment2
o1 = orientation(p1, q1, p2)
o2 = orientation(p1, q1, q2)
o3 = orientation(p2, q2, p1)
o4 = orientation(p2, q2, q1)

# General case
if o1 != o2 and o3 != o4:
return True
# Special cases for collinearity
if o1 == 0 and on_segment(p1, p2, q1): return True
if o2 == 0 and on_segment(p1, q2, q1): return True
if o3 == 0 and on_segment(p2, p1, q2): return True
if o4 == 0 and on_segment(p2, q1, q2): return True

return False
Explanation of Functions:
1. orientation(p, q, r): Determines the orientation of the
triplet (p,q,r)(p,q,r) using the cross product:
• 0 if the points are collinear
• 1 for clockwise
• 2 for counterclockwise
2. on_segment(p, q, r): Checks if the point qq lies on the
segment prpr when the points are collinear.

Time Complexity:
• Sorting the events takes O(nlog⁡n)O(nlogn).
• Each event is processed in O(log⁡n)O(logn) time using the
balanced BST, so processing all events takes O(nlog⁡n)O(nlogn).
• Checking for intersections with neighbors is an O(1)O(1) operation
in the average case, given that we only check the immediate
neighbors.
Overall, the time complexity is O(nlog⁡n)O(nlogn).

Space Complexity:
• The space complexity is O(n)O(n) to store the events and the
active segments in the BST.

Proof of Correctness:
1. Completeness: By processing each segment entry and exit, we ensure
that all potential intersections are considered.
2. Correctness: The orientation tests correctly capture the intersection
conditions for any two line segments, including edge cases like
collinearity.

Conclusion:
This sweep-line algorithm efficiently detects intersecting pairs among nn line
segments in O(nlog⁡n)O(nlogn) time, leveraging event processing and
orientation checks to limit unnecessary comparisons. This approach is optimal
for this type of geometric intersection problem.

9. Given the coordinates of n points, design an algorithm to decide whether the


given n points form a simple polygon or not. Analyse your algorithm with the
time complexity.

Problem Statement:
Given the coordinates of nn points in a 2-dimensional plane, design an
algorithm to determine whether these points can form a simple polygon. A
polygon is simple if its edges do not intersect or touch each other, except at
their endpoints.

Input and Output:


• Input: A list of nn points P={(x1,y1),(x2,y2),…,(xn,yn)}P={(x1,y1),(x2,y2
),…,(xn,yn)}, where each point (xi,yi)(xi,yi) represents a vertex of the
polygon.
• Output: A boolean value:
• True if the points form a simple polygon.
• False if they do not form a simple polygon (i.e., there are
intersections between non-adjacent edges).

Pseudocode:
function is_simple_polygon(points):
n = len(points)
edges = []

# Create edges of the polygon


for i in range(n):
edges.append((points[i], points[(i + 1) % n])) # Connect last to first

# Check for intersection between non-adjacent edges


for i in range(n):
for j in range(i + 2, n):
# Ensure edges are non-adjacent and not sharing endpoints
if i == 0 and j == n - 1:
continue
if do_intersect(edges[i][0], edges[i][1], edges[j][0], edges[j][1]):
return False
return True

function do_intersect(p1, q1, p2, q2):


# Find the four orientations needed for general and special cases
o1 = orientation(p1, q1, p2)
o2 = orientation(p1, q1, q2)
o3 = orientation(p2, q2, p1)
o4 = orientation(p2, q2, q1)

# General case
if o1 != o2 and o3 != o4:
return True

# Special cases
if o1 == 0 and on_segment(p1, p2, q1): return True
if o2 == 0 and on_segment(p1, q2, q1): return True
if o3 == 0 and on_segment(p2, p1, q2): return True
if o4 == 0 and on_segment(p2, q1, q2): return True

return False

function orientation(p, q, r):


val = (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y)
if val == 0: return 0 # Collinear
return 1 if val > 0 else 2 # Clockwise or counterclockwise
function on_segment(p, q, r):
return min(p.x, r.x) <= q.x <= max(p.x, r.x) and min(p.y, r.y) <= q.y <= max(p.y,
r.y)

Explanation of the Pseudocode:


• do_intersect(): Checks if two given line segments intersect.
• orientation(): Finds the orientation of an ordered triplet.
• on_segment(): Checks if a point lies on a line segment when the points
are collinear.

Time Complexity:
• Constructing the edges: O(n)O(n)
• Checking for intersections involves checking O(n2)O(n2) pairs of
edges, so the overall time complexity is O(n2)O(n2).

Space Complexity:
• The space required is O(n)O(n) to store the edges, so the space
complexity is O(n)O(n).

Proof of Correctness:
• Completeness: The algorithm checks all pairs of non-adjacent edges for
intersection. If any intersection is detected, it correctly returns False.
• Correctness: The orientation method correctly identifies whether two
line segments intersect, including special cases such as collinear points.

Conclusion:
The algorithm efficiently determines if nn points form a simple polygon by
checking all non-adjacent edges for intersections. The O(n2)O(n2) time
complexity is feasible for moderate values of nn, and the algorithm ensures
correctness through comprehensive geometric checks.

You might also like