Solve K Centers problem in Python
Hi everyone, in this tutorial we are going to discuss the K Centers problem in Python and see how we can solve it.
In brief, we can be called K Centers as Metric k Center problem which is an NP-Hard Problem.
Given p dots, we need to choose k (k<=p) centers, such that the maximum distance of a dot to the center is minimized. In layman terms, say we need to build k warehouses given a map of p connected dots. The best way to build a warehouse is by keeping in mind that, it must be closest to the dots. In other words, the maximum distance of a dot to the warehouse must be minimal.
First of all, take a look at an example of the K Center image.

Now we will be looking at a greedy approach towards this problem
- Pick an arbitrary center, p1.
- For every remaining dots P1, P2,… PN-, compute the minimum distance from the centers chosen already.
- Pick the new center with the highest distance from already chosen centers, that is max((dist(p1, P1), dist(p1,P2), … dist(p1, pN-1)).
- Continue this procedure until all the k centers are found.
Here is one of the important factors that we need to understand that this greedy approach has an approximate factor 2.
Code in Python for K Center problem
Below is our Python program:
import networkx as pt
import matplotlib.pyplot as pst
import operator
def k_centers_prob(V, n):
centers = []
cities = V.nodes()
centers.append((V.nodes())[0])
cities.remove(centers[0])
n = n-1
while n!= 0:
city_dict = {}
for cty in cities:
min_dist = float("inf")
for c in centers:
min_dist = min(min_dist,V[cty][c]['length'])
city_dict[cty] = min_dist
new_center = max(city_dict, key = lambda i: city_dict[i])
centers.append(new_center)
cities.remove(new_center)
n = n-1
return centers
def cGraph():
V = pt.Graph()
f = open('input.txt')
n = int(f.readline())
wtMatrix = []
for i in range(n):
list1 = map(int, (f.readline()).split())
wtMatrix.append(list1)
for i in range(n) :
for j in range(n)[i:] :
V.add_edge(i, j, length = wtMatrix[i][j])
noc = int(f.readline())
return V, noc
def dGraph(V, centers):
pos = pt.spring_layout(V)
color_map = ['blue'] * len(V.nodes())
for c in centers:
color_map[c] = 'red'
pt.draw(V, pos, node_color = color_map, with_labels = True)
edge_labels = pt.get_edge_attributes(V, 'length')
pt.draw_networkx_edge_labels(V, pos, edge_labels = edge_labels, font_size = 11)
#main function
if __name__ == "__main__":
V,n = cGraph()
c = k_centers_prob(V, n)
dGraph(V, centers)
pst.show()Input: 4 0 10 7 6 10 0 8 5 7 8 0 2 6 5 12 0 3
You can also be referred to:
Leave a Reply