Permalink
Show file tree
Hide file tree
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
4 changed files
with
133 additions
and
0 deletions.
There are no files selected for viewing
BIN
+1.07 KB
(170%)
Solutions/solutions.zip
Binary file not shown.
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,42 @@ | ||
import math | ||
|
||
from pyinclude.draw import * | ||
from pyinclude.point import * | ||
|
||
K = 3 | ||
POINTS = 100 | ||
RANGE = 640 | ||
|
||
|
||
if __name__ == "__main__": | ||
points = [ Point() for i in range(POINTS) ] | ||
centroids = [ Centroid() for i in range(K) ] | ||
|
||
maxIterations = 10 | ||
|
||
# set random point positions | ||
# generate K initial points and then position the rest of the | ||
# points around the initial K | ||
assert( len(points) >= len(centroids) ) | ||
for p in points[:len(centroids)]: | ||
p.randomise( RANGE ) | ||
|
||
for i in range( len(centroids), len(points) ): | ||
points[i].randomise( RANGE, points[i%len(centroids)] ) | ||
|
||
# set random starting positions for the centroids | ||
for c in centroids: | ||
c.randomise( RANGE ) | ||
print( c ) | ||
|
||
# clustering iterations | ||
for i in range( maxIterations ): | ||
# kmeans | ||
|
||
# display centroid positions | ||
print( f"Iteration {i}" ) | ||
for c in centroids: | ||
print( c ) | ||
|
||
draw( points, centroids, RANGE, RANGE, f"{i:0{int(math.log(maxIterations,10)+1)}d}_clusters.bmp" ) | ||
|
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,50 @@ | ||
from PIL import Image, ImageColor, ImageDraw | ||
|
||
__colormap = ( | ||
(255, 0, 0), (255, 31, 0), (255, 63, 0), (255, 95, 0), (255, 127, 0), | ||
(255, 159, 0), (255, 191, 0), (255, 223, 0), (255, 255, 0), (223, 255, 0), | ||
(191, 255, 0), (159, 255, 0), (127, 255, 0), ( 95, 255, 0), ( 63, 255, 0), | ||
( 31, 255, 0), ( 0, 255, 0), ( 0, 255, 31), ( 0, 255, 63), ( 0, 255, 95), | ||
( 0, 255, 127), ( 0, 255, 159), ( 0, 255, 191), ( 0, 255, 223), ( 0, 255, 255), | ||
( 0, 223, 255), ( 0, 191, 255), ( 0, 159, 255), ( 0, 127, 255), ( 0, 95, 255), | ||
( 0, 63, 255), ( 0, 31, 255), ( 0, 0, 255), ( 31, 0, 255), ( 63, 0, 255), | ||
( 95, 0, 255), (127, 0, 255), (159, 0, 255), (191, 0, 255), (223, 0, 255), | ||
(255, 0, 255), (255, 0, 223), (255, 0, 191), (255, 0, 159), (255, 0, 127), | ||
(255, 0, 95), (255, 0, 63), (255, 0, 31), (255, 255, 255), ( 0, 0, 0) | ||
) | ||
|
||
def draw( points, centroids, width=0, height=0, filename="temp.bmp" ): | ||
_width = 0 | ||
_height = 0 | ||
clusters = 0 | ||
|
||
# find width, heigth based on max x, y of points, centroids | ||
for p in points + centroids: | ||
if p.cluster > clusters: clusters = p.cluster | ||
if p.x > _width: _width = p.x | ||
if p.y > _height: _height = p.y | ||
|
||
clusters += 1 | ||
_width += 1 | ||
_height += 1 | ||
|
||
# use out values if user hasn't specified any dimensions | ||
if width==0 or height==0: | ||
width = _width | ||
height = _height | ||
|
||
# create the image | ||
image = Image.new( "RGB", (width,height), (255,255,255) ) | ||
draw = ImageDraw.Draw( image ) | ||
|
||
colors = [ __colormap[i] for i in range( 0, len(__colormap), int(len(__colormap)/clusters)) ] | ||
|
||
# draw the points | ||
for p in points: | ||
draw.ellipse( (p.x-2, p.y-2, p.x+2, p.y+2), fill=colors[p.cluster] ) | ||
|
||
# draw the clusters | ||
for c in centroids: | ||
draw.ellipse( (c.x-5, c.y-5, c.x+5, c.y+5), outline=colors[c.cluster] ) | ||
|
||
image.save( filename ) |
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,41 @@ | ||
import random | ||
|
||
class Coord: | ||
def __init__( self, x=0, y=0 ): | ||
self.x = int(x) | ||
self.y = int(y) | ||
|
||
def __eq__( self, other ): | ||
return self.x == other.x and self.y == other.y | ||
|
||
def randomise( self, range, coord=None ): | ||
if coord is None: | ||
self.x = random.randint( 0, range ) | ||
self.y = random.randint( 0, range ) | ||
return | ||
|
||
x = random.gauss( coord.x, range/10 ) | ||
y = random.gauss( coord.y, range/10 ) | ||
|
||
if x < 0 : x = 0 | ||
if y < 0 : y = 0 | ||
if x > range : x = range | ||
if y > range : y = range | ||
|
||
self.x = int(x) | ||
self.y = int(y) | ||
|
||
class Point( Coord ): | ||
def __init__( self, x=0, y=0, cluster=0 ): | ||
Coord.__init__( self, x, y ) | ||
self.cluster = cluster | ||
|
||
class Centroid( Coord ): | ||
__counter = 0 | ||
|
||
def __init__( self, x=0, y=0 ): | ||
self.cluster = Centroid.__counter | ||
Centroid.__counter += 1 | ||
|
||
def __repr__( self ): | ||
return f"Centroid[{self.cluster}] @ ({self.x},{self.y})" |