You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
114 lines
2.9 KiB
114 lines
2.9 KiB
import getopt |
|
import random |
|
import sys |
|
from typing import List |
|
|
|
import numpy as np |
|
import matplotlib.pyplot as plt |
|
from scipy.spatial import ConvexHull |
|
from scipy.spatial.qhull import QhullError |
|
|
|
from kmeans.algorithms import k_means |
|
from kmeans.clustering.cluster import Cluster |
|
from kmeans.clustering.point import Point |
|
|
|
|
|
def generate_points(x_bound: int, y_bound: int, count: int) -> List: |
|
""" |
|
Generates random points without replacement bounded by (x_bound, y_bound) |
|
|
|
@param x_bound The x direction boundary. |
|
@param y_bound The y direction boundary. |
|
@param count The count of points. |
|
""" |
|
xs = random.sample(range(0, x_bound), count) |
|
|
|
ys = random.sample(range(0, y_bound), count) |
|
|
|
points = list(zip(xs, ys)) |
|
|
|
result = [] |
|
for p in points: |
|
result.append(Point(p[0], p[1])) |
|
|
|
return result |
|
|
|
|
|
def main(): |
|
try: |
|
opts, args = getopt.getopt(sys.argv[1:], "x:y:r:", |
|
['x=', 'y=', 'random=']) |
|
except getopt.GetoptError as err: |
|
print('Option not recognized') |
|
sys.exit(-1) |
|
|
|
x = None |
|
y = None |
|
random = None |
|
|
|
for o, a in opts: |
|
if o in ('-x', '--x'): |
|
x = int(a) |
|
elif o in ('-y', '--y'): |
|
y = int(a) |
|
elif o in ('-r', '--random'): |
|
random = int(a) |
|
else: |
|
print(f'Unknown option {o}\n') |
|
sys.exit(-1) |
|
|
|
if x is None or y is None or random is None: |
|
print('x, y, and r must be specified\n') |
|
sys.exit(-1) |
|
|
|
points = generate_points(x, y, random) |
|
|
|
print('--- INITIAL POINT PLOT ---') |
|
xs = [p.x for p in points] |
|
ys = [p.y for p in points] |
|
plt.plot(xs, ys, 'o') |
|
plt.show() |
|
|
|
clusters = k_means(points, 4, 0.001) |
|
|
|
# Color clusters |
|
assigned_colors = plt.cm.gist_ncar(np.linspace(0, 1, 4)) |
|
|
|
for i, cluster in enumerate(clusters): |
|
cluster.color = assigned_colors[i] |
|
|
|
print('--- CLUSTER PLOT ---') |
|
for cluster in clusters: |
|
xs = [p.x for p in cluster.points] |
|
ys = [p.y for p in cluster.points] |
|
plt.plot(xs, ys, 'o', cluster.color) |
|
|
|
plt.show() |
|
|
|
print('--- CLUSTER PLOT WITH CONVEX HULL BOUNDARIES ---') |
|
for cluster in clusters: |
|
xs = [p.x for p in cluster.points] |
|
ys = [p.y for p in cluster.points] |
|
plt.plot(xs, ys, 'o', cluster.color) |
|
|
|
# Convex hull plot |
|
if len(cluster.points) >= 4: |
|
points = np.array([p.array() for p in cluster.points]) |
|
|
|
try: |
|
hull = ConvexHull(points) |
|
except QhullError as e: |
|
print(str(e)) |
|
continue |
|
|
|
plt.plot(points[hull.vertices, 0], |
|
points[hull.vertices, 1], 'r--', lw=2) |
|
|
|
plt.plot(points[hull.vertices[0], 0], |
|
points[hull.vertices[0], 1], 'ro') |
|
|
|
plt.show() |
|
|
|
|
|
if __name__ == '__main__': |
|
main()
|
|
|