-
-
Notifications
You must be signed in to change notification settings - Fork 43
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
added Union Find progression basic, path_compression, quickfind, quic…
…kunion, optimized
- Loading branch information
1 parent
586da8c
commit 4520d84
Showing
6 changed files
with
205 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
# The vey basics of union find and disjoint sets | ||
# Basically an array and within that array lies a disjoint set | ||
|
||
|
||
# There are two functions when discussing disjoint sets | ||
|
||
# find(a) which takes in a single argument and returns the root of | ||
# that particular node | ||
|
||
# union(a,b) which takes in two arguments and combines them together | ||
# let's watch a quick video on how this works and then implement from there | ||
|
||
# First lets implement UnionFind as an object and instantiate it with an array | ||
|
||
class UnionFind: | ||
def __init__(self, size): | ||
self.root = [i for i in range(size)] | ||
|
||
# union connects two nodes with a left bias meaning that b will always | ||
# connect to a | ||
def union(self, x, y): | ||
rootX = self.find(x) | ||
rootY = self.find(y) | ||
if rootX != rootY: | ||
for i in range(len(self.root)): | ||
if self.root[i] == rootY: | ||
self.root[i] = rootX | ||
|
||
# takes in a node a and returns the root node of such | ||
def find(self, a): | ||
while a != self.root[a]: | ||
a = self.root[a] | ||
return a | ||
|
||
uu = UnionFind(10) | ||
|
||
print(uu.root) | ||
uu.union(0,1) | ||
uu.union(0,2) | ||
uu.union(1,3) | ||
uu.union(4,8) | ||
uu.union(5,6) | ||
uu.union(5,7) | ||
print(uu.root) | ||
print([i for i in range(10)]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
|
||
class UnionFind: | ||
def __init__(self,size): | ||
self.root = [i for i in range(size)] | ||
|
||
def find(self, n): | ||
if self.root[n] == n: | ||
return n | ||
|
||
self.root[n] = self.find(self.root[n]) | ||
return self.root[n] | ||
# quick union | ||
def union(self, a, b): | ||
fa = self.find(a) | ||
fb = self.find(b) | ||
if fa != fb: | ||
self.root[fa] = fb | ||
|
||
def connected(self, x, y): | ||
return self.find(x) == self.find(y) | ||
# Test Case | ||
uf = UnionFind(10) | ||
# 1-2-5-6-7 3-8-9 4 | ||
uf.union(1, 2) | ||
uf.union(2, 5) | ||
uf.union(5, 6) | ||
uf.union(6, 7) | ||
uf.union(3, 8) | ||
uf.union(8, 9) | ||
print(uf.connected(1, 5)) # true | ||
print(uf.connected(5, 7)) # true | ||
print(uf.connected(4, 9)) # false | ||
# 1-2-5-6-7 3-8-9-4 | ||
uf.union(9, 4) | ||
print(uf.connected(4, 9)) # true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
class UnionFind: | ||
def __init__(self, size): | ||
self.root = [i for i in range(size)] | ||
# changing quickfind to have the parent node be stored in the array | ||
# effectively making it an O(1) operation to find the root of a given node | ||
# however, union will take a hit in performance | ||
|
||
def find(self, n): | ||
return self.root[n] | ||
|
||
def union(self, a, b): | ||
fa = self.find(a) | ||
fb = self.find(b) | ||
if fa != fb: | ||
for i, v in enumerate(self.root): | ||
if fa == v: | ||
self.root[i] = fb | ||
|
||
def connected(self, x, y): | ||
return self.find(x) == self.find(y) | ||
|
||
|
||
# Test Case | ||
uf = UnionFind(10) | ||
# 1-2-5-6-7 3-8-9 4 | ||
uf.union(1, 2) | ||
uf.union(2, 5) | ||
uf.union(5, 6) | ||
uf.union(6, 7) | ||
uf.union(3, 8) | ||
uf.union(8, 9) | ||
print(uf.connected(1, 5)) # true | ||
print(uf.connected(5, 7)) # true | ||
print(uf.connected(4, 9)) # false | ||
# 1-2-5-6-7 3-8-9-4 | ||
uf.union(9, 4) | ||
print(uf.connected(4, 9)) # true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
# The vey basics of union find and disjoint sets | ||
# Basically an array and within that array lies a disjoint set | ||
|
||
|
||
# There are two functions when discussing disjoint sets | ||
|
||
# find(a) which takes in a single argument and returns the root of | ||
# that particular node | ||
|
||
# union(a,b) which takes in two arguments and combines them together | ||
# let's watch a quick video on how this works and then implement from there | ||
|
||
# First lets implement UnionFind as an object and instantiate it with an array | ||
|
||
class UnionFind: | ||
def __init__(self, size): | ||
self.root = [i for i in range(size)] | ||
|
||
# union connects two nodes with a left bias meaning that b will always | ||
# connect to a | ||
def union(self,a,b): | ||
# Basically we want to take the parent node of the given thing | ||
fa = self.find(a) | ||
fb = self.find(b) | ||
if fa != fb: | ||
self.root[fa] = fb | ||
|
||
# takes in a node a and returns the root node of such | ||
def find(self, a): | ||
while a != self.root[a]: | ||
a = self.root[a] | ||
return a | ||
|
||
uu = UnionFind(10) | ||
|
||
print(uu.root) | ||
uu.union(0,1) | ||
uu.union(0,2) | ||
uu.union(1,3) | ||
uu.union(4,8) | ||
uu.union(5,6) | ||
uu.union(5,7) | ||
print(uu.root) | ||
print([i for i in range(10)]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
# Optimized union find program that implements union by rank | ||
|
||
class UnionFind: | ||
def __init__(self, size): | ||
self.root = [i for i in range(size)] | ||
self.rank = [1] * size | ||
|
||
# Recurrsively update root | ||
def find(self, n): | ||
if self.root[n] != n: | ||
self.root[n] = self.find(self.root[n]) | ||
return self.root[n] | ||
|
||
def union(self, a, b): | ||
fa = self.find(a) | ||
fb = self.find(b) | ||
|
||
if fa != fb: | ||
if self.rank[fa] > self.rank[fb]: | ||
self.root[fb] = fa | ||
elif self.rank[fa] < self.rank[fb]: | ||
self.root[fa] = fb | ||
else: | ||
self.root[fa] = fb | ||
self.rank[fb] += 1 | ||
|
||
def connected(self, x, y): | ||
return self.find(x) == self.find(y) | ||
|
||
# Test Case | ||
uf = UnionFind(10) | ||
# 1-2-5-6-7 3-8-9 4 | ||
uf.union(1, 2) | ||
uf.union(2, 5) | ||
uf.union(5, 6) | ||
uf.union(6, 7) | ||
uf.union(3, 8) | ||
uf.union(8, 9) | ||
print(uf.connected(1, 5)) # true | ||
print(uf.connected(5, 7)) # true | ||
print(uf.connected(4, 9)) # false | ||
# 1-2-5-6-7 3-8-9-4 | ||
uf.union(9, 4) | ||
print(uf.connected(4, 9)) # true |
Empty file.