I started a little late and only covered week 1 materials for now. Week 1 problems cover quick-union algorithms. Even though the course is taught in Java, I decided to re-write the weighted quick-union algorithm in Ruby (it didn't look that much different from the original). I further applied it to the following proposed problem: Given a social network containing N members and a log file containing M timestamps at which times pairs of members formed friendships, design an algorithm to determine the earliest time at which all members are connected (i.e., every member is a friend of a friend of a friend ... of a friend). Assume that the log file is sorted by timestamp and that friendship is an equivalence relation.
I interpret this problem such that we should determine how many friend groups are in there. If there is only one friend group, this means all people are connected to each other, and we return the timestamp associated with the last node.
We start with the total number of nodes equal to the number of connections, and as we loop through friend pairs and merge them into groups, we reduce the number of nodes by 1. At the end, we should be left with one node only.
sample input:
20141001 0 2
20141002 0 4
20141003 2 3
....
class WeightedQuickUnionUF
attr_reader :total_roots
def initialize(n)
@id = (0...n).to_a
@sz = (0...n).to_a
@total_roots = n
end
def connected?(first, second)
find(first) == find(second)
end
def friends_connected?
@total_roots == 1
end
def union(first, second)
i = find(first)
j = find(second)
return if i == j
if @sz[i] < @sz[j]
@id[i] = j
@sz[j] += @sz[i]
else
@id[j] = i
@sz[i] += @sz[j]
end
@total_roots -= 1
end
def show
print "#{@id}\n"
end
def find(index)
while index != @id[index]
index = @id[index]
end
index
end
end
test = WeightedQuickUnionUF.new(13)
f = File.open("links.txt", "r")
f.each_line do |line|
l = line.split(' ')
test.union(l[1].to_i,l[2].to_i)
print "#{l[0]}: #{test.friends_connected?} #{test.total_roots}\n"
end
f.close
No comments :
Post a Comment