From 33333dc06d529c09b749562aab54af1335586978 Mon Sep 17 00:00:00 2001 From: seungeon Date: Fri, 27 Nov 2020 02:13:25 +0900 Subject: [PATCH 01/14] =?UTF-8?q?[style]=20=ED=94=84=EB=A1=9C=EC=A0=9D?= =?UTF-8?q?=ED=8A=B8=20=EA=B7=B8=EB=A3=B9=20=EA=B5=AC=EC=A1=B0=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../project.pbxproj | 31 ++++++++++++++++--- .../KMeans}/KCoefficient.swift | 0 .../KMeans}/KMeansClustering.swift | 0 3 files changed, 26 insertions(+), 5 deletions(-) rename Project17-C-Map/InteractiveClusteringMap/{ => Clustering/KMeans}/KCoefficient.swift (100%) rename Project17-C-Map/InteractiveClusteringMap/{VO => Clustering/KMeans}/KMeansClustering.swift (100%) diff --git a/Project17-C-Map/InteractiveClusteringMap.xcodeproj/project.pbxproj b/Project17-C-Map/InteractiveClusteringMap.xcodeproj/project.pbxproj index 38aeb38..1ad5c95 100644 --- a/Project17-C-Map/InteractiveClusteringMap.xcodeproj/project.pbxproj +++ b/Project17-C-Map/InteractiveClusteringMap.xcodeproj/project.pbxproj @@ -22,7 +22,6 @@ 372216C12569325600231245 /* DataManagable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 372216C02569325600231245 /* DataManagable.swift */; }; 372216CD256943D300231245 /* POI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 372216CC256943D300231245 /* POI.swift */; }; 37279B03256EBC5200EA689A /* KMeansTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37279B02256EBC5200EA689A /* KMeansTests.swift */; }; - 37279B07256EBC6300EA689A /* BoundingBox.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46A12E22256CD4DB007BDF3E /* BoundingBox.swift */; }; 37279B0B256EBC6E00EA689A /* KMeansClustering.swift in Sources */ = {isa = PBXBuildFile; fileRef = 379DC4C5256E1EC60044DA6C /* KMeansClustering.swift */; }; 37311088256F641400350D55 /* MockPOIService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37311087256F641400350D55 /* MockPOIService.swift */; }; 3731108C256F641F00350D55 /* POIService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3753DCEF256B4C5B006D26A9 /* POIService.swift */; }; @@ -52,10 +51,11 @@ 46B444582568F095001B79D4 /* InteractiveMapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46B444572568F095001B79D4 /* InteractiveMapView.swift */; }; C9FF187A077822AA8BD00410 /* Pods_InteractiveClusteringMap.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A551109FA7E11823B10D084F /* Pods_InteractiveClusteringMap.framework */; }; FA81D67825690F360023E123 /* CoreDataStack.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA81D67725690F360023E123 /* CoreDataStack.swift */; }; - FA84D560256F796700ECDD44 /* BoundingBox.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46A12E22256CD4DB007BDF3E /* BoundingBox.swift */; }; FAC9FD05256E2107009FBB41 /* KCoefficient.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAC9FD04256E2107009FBB41 /* KCoefficient.swift */; }; FAC9FD0A256E23B1009FBB41 /* KDefineTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAC9FD09256E23B1009FBB41 /* KDefineTests.swift */; }; FAC9FD0E256E2495009FBB41 /* KCoefficient.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAC9FD04256E2107009FBB41 /* KCoefficient.swift */; }; + FCE422B02570194B0017416F /* Coordinate.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCE422AF2570194B0017416F /* Coordinate.swift */; }; + FCE422B8257019650017416F /* Cluster.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCE422B7257019650017416F /* Cluster.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -116,6 +116,8 @@ FA81D67725690F360023E123 /* CoreDataStack.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoreDataStack.swift; sourceTree = ""; }; FAC9FD04256E2107009FBB41 /* KCoefficient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KCoefficient.swift; sourceTree = ""; }; FAC9FD09256E23B1009FBB41 /* KDefineTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KDefineTests.swift; sourceTree = ""; }; + FCE422AF2570194B0017416F /* Coordinate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Coordinate.swift; sourceTree = ""; }; + FCE422B7257019650017416F /* Cluster.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Cluster.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -149,7 +151,8 @@ children = ( 37352CDF25695EE000CAFDFD /* Place.swift */, 372216CC256943D300231245 /* POI.swift */, - 379DC4C5256E1EC60044DA6C /* KMeansClustering.swift */, + FCE422AF2570194B0017416F /* Coordinate.swift */, + FCE422B7257019650017416F /* Cluster.swift */, ); path = VO; sourceTree = ""; @@ -196,13 +199,13 @@ 37EB73272562592700AC44D6 /* InteractiveClusteringMap */ = { isa = PBXGroup; children = ( + FCE422AD257018E30017416F /* Clustering */, 37352CD925695E4D00CAFDFD /* Util */, 37352CCF25695AA500CAFDFD /* Resource */, 372216CB256943C800231245 /* VO */, FA81D66E2568FEC50023E123 /* CoreData */, 37EB73282562592700AC44D6 /* AppDelegate.swift */, 37EB732A2562592700AC44D6 /* SceneDelegate.swift */, - FAC9FD04256E2107009FBB41 /* KCoefficient.swift */, 37EB732C2562592700AC44D6 /* MapViewController.swift */, 4623BD1225694A1400940B12 /* MapController.swift */, 46153145256BDDD700BAE674 /* QuadTree */, @@ -294,6 +297,23 @@ path = POI; sourceTree = ""; }; + FCE422AD257018E30017416F /* Clustering */ = { + isa = PBXGroup; + children = ( + FCE422AE257018EA0017416F /* KMeans */, + ); + path = Clustering; + sourceTree = ""; + }; + FCE422AE257018EA0017416F /* KMeans */ = { + isa = PBXGroup; + children = ( + FAC9FD04256E2107009FBB41 /* KCoefficient.swift */, + 379DC4C5256E1EC60044DA6C /* KMeansClustering.swift */, + ); + path = KMeans; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -498,8 +518,10 @@ 379DC4C6256E1EC60044DA6C /* KMeansClustering.swift in Sources */, 3753DCF0256B4C5B006D26A9 /* POIService.swift in Sources */, FA81D67825690F360023E123 /* CoreDataStack.swift in Sources */, + FCE422B02570194B0017416F /* Coordinate.swift in Sources */, 37EB732D2562592700AC44D6 /* MapViewController.swift in Sources */, 37EB73332562592700AC44D6 /* Model.xcdatamodeld in Sources */, + FCE422B8257019650017416F /* Cluster.swift in Sources */, 192D34AD256E355500861703 /* QuadTree.swift in Sources */, 46A12E1B256CD099007BDF3E /* Extension.swift in Sources */, 37352CDB25695E7400CAFDFD /* JSONReader.swift in Sources */, @@ -531,7 +553,6 @@ 37EB73432562592900AC44D6 /* InteractiveClusteringMapTests.swift in Sources */, 37311088256F641400350D55 /* MockPOIService.swift in Sources */, 46A12E3A256CED57007BDF3E /* JSONReader.swift in Sources */, - 192D34BA256E36A200861703 /* BoundingBox.swift in Sources */, 192D34B2256E368D00861703 /* QuadTreeTests.swift in Sources */, 199DDFF6256B9C8E0065B94E /* Place.swift in Sources */, diff --git a/Project17-C-Map/InteractiveClusteringMap/KCoefficient.swift b/Project17-C-Map/InteractiveClusteringMap/Clustering/KMeans/KCoefficient.swift similarity index 100% rename from Project17-C-Map/InteractiveClusteringMap/KCoefficient.swift rename to Project17-C-Map/InteractiveClusteringMap/Clustering/KMeans/KCoefficient.swift diff --git a/Project17-C-Map/InteractiveClusteringMap/VO/KMeansClustering.swift b/Project17-C-Map/InteractiveClusteringMap/Clustering/KMeans/KMeansClustering.swift similarity index 100% rename from Project17-C-Map/InteractiveClusteringMap/VO/KMeansClustering.swift rename to Project17-C-Map/InteractiveClusteringMap/Clustering/KMeans/KMeansClustering.swift From 3deea04f2919c5a7148d5b9d450d24deeec896fe Mon Sep 17 00:00:00 2001 From: seungeon Date: Fri, 27 Nov 2020 02:14:03 +0900 Subject: [PATCH 02/14] =?UTF-8?q?[refactor]=20=ED=8C=8C=EC=9D=BC=20?= =?UTF-8?q?=EB=B6=84=ED=95=A0=EB=A1=9C=20=EC=9D=B8=ED=95=9C=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../QuadTree/BoundingBox.swift | 71 ------------------- 1 file changed, 71 deletions(-) diff --git a/Project17-C-Map/InteractiveClusteringMap/QuadTree/BoundingBox.swift b/Project17-C-Map/InteractiveClusteringMap/QuadTree/BoundingBox.swift index e64faed..473d06c 100644 --- a/Project17-C-Map/InteractiveClusteringMap/QuadTree/BoundingBox.swift +++ b/Project17-C-Map/InteractiveClusteringMap/QuadTree/BoundingBox.swift @@ -39,74 +39,3 @@ struct BoundingBox { extension BoundingBox: Equatable {} -struct Coordinate { - - let x: Double - let y: Double - - func distanceTo(_ other: Coordinate) -> Double { - let powX = pow(self.x - other.x, 2.0) - let powY = pow(self.y - other.y, 2.0) - - return sqrt(powX + powY) - } - - func center(other: Coordinate) -> Coordinate { - let centerX: Double = (self.x + other.x) / 2.0 - let centerY: Double = (self.y + other.y) / 2.0 - - return Coordinate(x: centerX, y: centerY) - } - -} - -extension Coordinate: Hashable { - - static let zero = Coordinate(x: 0, y: 0) - - static func + (left: Coordinate, right: Coordinate) -> Coordinate { - let x = left.x + right.x - let y = left.y + right.y - - return Coordinate(x: x, y: y) - } - - static func - (left: Coordinate, right: Coordinate) -> Coordinate { - let x = left.x - right.x - let y = left.y - right.y - - return Coordinate(x: x, y: y) - } - - static func / (left: Coordinate, right: Double) -> Coordinate { - let x = left.x / right - let y = left.y / right - - return Coordinate(x: x, y: y) - } - - static func <= (left: Coordinate, right: Coordinate) -> Bool { - left.x <= right.x && left.y <= right.y - } - -} - -struct Cluster { - var coordinates: [Coordinate] - var center: Coordinate { - coordinates.reduce(.zero, +) / Double(coordinates.count) - } -} - -extension Cluster: Hashable { - - static func == (lhs: Cluster, rhs: Cluster) -> Bool { - return lhs.center == rhs.center && - lhs.coordinates == rhs.coordinates - } - - func hash(into hasher: inout Hasher) { - hasher.combine(coordinates) - } - -} From 04a07d6fc500faf2b8917f214e96272373724e47 Mon Sep 17 00:00:00 2001 From: seungeon Date: Fri, 27 Nov 2020 02:14:19 +0900 Subject: [PATCH 03/14] =?UTF-8?q?[feat]=20coordinate=20=EB=AA=A8=EB=8D=B8?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../InteractiveClusteringMap/VO/Cluster.swift | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 Project17-C-Map/InteractiveClusteringMap/VO/Cluster.swift diff --git a/Project17-C-Map/InteractiveClusteringMap/VO/Cluster.swift b/Project17-C-Map/InteractiveClusteringMap/VO/Cluster.swift new file mode 100644 index 0000000..d66f050 --- /dev/null +++ b/Project17-C-Map/InteractiveClusteringMap/VO/Cluster.swift @@ -0,0 +1,28 @@ +// +// Cluster.swift +// InteractiveClusteringMap +// +// Created by Seungeon Kim on 2020/11/27. +// + +import Foundation + +struct Cluster { + var coordinates: [Coordinate] + var center: Coordinate { + coordinates.reduce(.zero, +) / Double(coordinates.count) + } +} + +extension Cluster: Hashable { + + static func == (lhs: Cluster, rhs: Cluster) -> Bool { + return lhs.center == rhs.center && + lhs.coordinates == rhs.coordinates + } + + func hash(into hasher: inout Hasher) { + hasher.combine(coordinates) + } + +} From 4eaa676954015ca1fe9a28a0db06e286f4ca6de2 Mon Sep 17 00:00:00 2001 From: seungeon Date: Fri, 27 Nov 2020 02:14:32 +0900 Subject: [PATCH 04/14] =?UTF-8?q?[feat]=20cluster=20=EB=AA=A8=EB=8D=B8=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../VO/Coordinate.swift | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 Project17-C-Map/InteractiveClusteringMap/VO/Coordinate.swift diff --git a/Project17-C-Map/InteractiveClusteringMap/VO/Coordinate.swift b/Project17-C-Map/InteractiveClusteringMap/VO/Coordinate.swift new file mode 100644 index 0000000..cd8dab4 --- /dev/null +++ b/Project17-C-Map/InteractiveClusteringMap/VO/Coordinate.swift @@ -0,0 +1,60 @@ +// +// Coordinate.swift +// InteractiveClusteringMap +// +// Created by Seungeon Kim on 2020/11/27. +// + +import Foundation + +struct Coordinate { + + let x: Double + let y: Double + + func distanceTo(_ other: Coordinate) -> Double { + let powX = pow(self.x - other.x, 2.0) + let powY = pow(self.y - other.y, 2.0) + + return sqrt(powX + powY) + } + + func center(other: Coordinate) -> Coordinate { + let centerX: Double = (self.x + other.x) / 2.0 + let centerY: Double = (self.y + other.y) / 2.0 + + return Coordinate(x: centerX, y: centerY) + } + +} + +extension Coordinate: Hashable { + + static let zero = Coordinate(x: 0, y: 0) + + static func + (left: Coordinate, right: Coordinate) -> Coordinate { + let x = left.x + right.x + let y = left.y + right.y + + return Coordinate(x: x, y: y) + } + + static func - (left: Coordinate, right: Coordinate) -> Coordinate { + let x = left.x - right.x + let y = left.y - right.y + + return Coordinate(x: x, y: y) + } + + static func / (left: Coordinate, right: Double) -> Coordinate { + let x = left.x / right + let y = left.y / right + + return Coordinate(x: x, y: y) + } + + static func <= (left: Coordinate, right: Coordinate) -> Bool { + left.x <= right.x && left.y <= right.y + } + +} From 89606b227cde20fdae4349823445d3a5562fc57e Mon Sep 17 00:00:00 2001 From: seungeon Date: Fri, 27 Nov 2020 02:15:58 +0900 Subject: [PATCH 05/14] =?UTF-8?q?[feat]=20Degree=20=EC=97=B4=EA=B1=B0=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Clustering/KMeans/Degree.swift | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 Project17-C-Map/InteractiveClusteringMap/Clustering/KMeans/Degree.swift diff --git a/Project17-C-Map/InteractiveClusteringMap/Clustering/KMeans/Degree.swift b/Project17-C-Map/InteractiveClusteringMap/Clustering/KMeans/Degree.swift new file mode 100644 index 0000000..42f5470 --- /dev/null +++ b/Project17-C-Map/InteractiveClusteringMap/Clustering/KMeans/Degree.swift @@ -0,0 +1,14 @@ +// +// Degree.swift +// InteractiveClusteringMap +// +// Created by Seungeon Kim on 2020/11/27. +// + +import Foundation + +enum Degree { + static let right = 90.0 + static let straight = 180.0 + static let turn = 360.0 +} From df55513ddd28fbe63b153f064bfdc1084588458d Mon Sep 17 00:00:00 2001 From: seungeon Date: Fri, 27 Nov 2020 02:16:10 +0900 Subject: [PATCH 06/14] =?UTF-8?q?[feat]=20quadrant=20=EC=97=B4=EA=B1=B0=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Clustering/KMeans/Quadrant.swift | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 Project17-C-Map/InteractiveClusteringMap/Clustering/KMeans/Quadrant.swift diff --git a/Project17-C-Map/InteractiveClusteringMap/Clustering/KMeans/Quadrant.swift b/Project17-C-Map/InteractiveClusteringMap/Clustering/KMeans/Quadrant.swift new file mode 100644 index 0000000..eb27185 --- /dev/null +++ b/Project17-C-Map/InteractiveClusteringMap/Clustering/KMeans/Quadrant.swift @@ -0,0 +1,57 @@ +// +// Quadrant.swift +// InteractiveClusteringMap +// +// Created by Seungeon Kim on 2020/11/27. +// + +import Foundation + +enum Quadrant: Int { + case first = 0, second = 1, third = 2, fourth = 3 + + static func findQuadrant(angle: Double) -> Quadrant { + guard angle != .zero else { return Quadrant.first } + + let number = Int(angle / Degree.right) + if angle.truncatingRemainder(dividingBy: Degree.right) == 0 { + return Quadrant(rawValue: number - 1) ?? Quadrant.first + } else { + return Quadrant(rawValue: number) ?? Quadrant.first + } + } + + func theta(angle: Double) -> Double { + if self == .first || self == .third { + return Degree.right - angle + } else { + return angle + } + } + + func degree(center: Coordinate, boundary: Coordinate) -> Coordinate { + switch self { + case .first: + return Coordinate(x: center.x + boundary.x, y: center.y) + case .second: + return Coordinate(x: center.x, y: center.y - boundary.y) + case .third: + return Coordinate(x: center.x - boundary.x, y: center.y) + case .fourth: + return Coordinate(x: center.x, y: center.y + boundary.y) + } + } + + func convertToCoordinate(center: Coordinate, distance: Coordinate) -> Coordinate { + switch self { + case .first: + return Coordinate(x: center.x + distance.x, y: center.y + distance.y) + case .second: + return Coordinate(x: center.x + distance.x, y: center.y - distance.y) + case .third: + return Coordinate(x: center.x - distance.x, y: center.y - distance.y) + case .fourth: + return Coordinate(x: center.x - distance.x, y: center.y + distance.y) + } + } +} From d105ec59d9fcb58e4399dc5ac8d8bf7dcd3792e8 Mon Sep 17 00:00:00 2001 From: seungeon Date: Fri, 27 Nov 2020 02:18:59 +0900 Subject: [PATCH 07/14] =?UTF-8?q?[feat]=20=EB=9E=9C=EB=8D=A4=20=EC=A4=91?= =?UTF-8?q?=EC=8B=AC=EA=B0=92=20=EC=83=9D=EC=84=B1=20=ED=95=A8=EC=88=98=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Clustering/KMeans/KMeansClustering.swift | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Project17-C-Map/InteractiveClusteringMap/Clustering/KMeans/KMeansClustering.swift b/Project17-C-Map/InteractiveClusteringMap/Clustering/KMeans/KMeansClustering.swift index 28fd86f..ab4b6bf 100644 --- a/Project17-C-Map/InteractiveClusteringMap/Clustering/KMeans/KMeansClustering.swift +++ b/Project17-C-Map/InteractiveClusteringMap/Clustering/KMeans/KMeansClustering.swift @@ -15,6 +15,19 @@ class KMeansClustering { self.k = k } + func randomCentroids(rangeOfLat lats: ClosedRange, + rangeOfLng lngs: ClosedRange) -> [Coordinate] { + var centroids: [Coordinate] = [] + for _ in 0.. Date: Fri, 27 Nov 2020 02:20:09 +0900 Subject: [PATCH 08/14] =?UTF-8?q?[feat]=20=ED=99=94=EB=A9=B4=EC=9D=84=20?= =?UTF-8?q?=EB=B6=84=ED=95=A0=ED=95=98=EC=97=AC=20=EC=A4=91=EC=8B=AC?= =?UTF-8?q?=EA=B0=92=20=EC=83=9D=EC=84=B1=20=ED=95=A8=EC=88=98=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Clustering/KMeans/KMeansClustering.swift | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/Project17-C-Map/InteractiveClusteringMap/Clustering/KMeans/KMeansClustering.swift b/Project17-C-Map/InteractiveClusteringMap/Clustering/KMeans/KMeansClustering.swift index ab4b6bf..f55624c 100644 --- a/Project17-C-Map/InteractiveClusteringMap/Clustering/KMeans/KMeansClustering.swift +++ b/Project17-C-Map/InteractiveClusteringMap/Clustering/KMeans/KMeansClustering.swift @@ -28,6 +28,46 @@ class KMeansClustering { return centroids } + func screenCentroids(topLeft: Coordinate, bottomRight: Coordinate) -> [Coordinate] { + let center = (topLeft + bottomRight) / 2.0 + let boundary = Coordinate(x: bottomRight.x - center.x, y: topLeft.y - center.y) + let pivot = center.findTheta(vertex: Coordinate(x: bottomRight.x, y: topLeft.y)) + + let increase = Degree.turn / Double(number) + var angle = increase + var coords: [Coordinate] = [] + + for _ in 0.. pivot { + y = boundary.y + x = y / tan(radian) + } else { + x = boundary.x + y = tan(radian) * x + } + let distance = Coordinate(x: x, y: y) / 2 + let coord = quadrant.convertToCoordinate(center: center, distance: distance) + coords.append(coord) + } + angle += increase + } + + return coords + } + /// points에 대한 centroid를 계속 계산하여 centroid가 이동한 총 거리가 /// convergeDistance 이하로 움직일 경우 cluster를 반환합니다. /// From 0e9e57ae42b16e5e51950f9ee7dec7f2051f9c5f Mon Sep 17 00:00:00 2001 From: seungeon Date: Fri, 27 Nov 2020 02:20:19 +0900 Subject: [PATCH 09/14] =?UTF-8?q?[chore]=20=ED=94=84=EB=A1=9C=EC=A0=9D?= =?UTF-8?q?=ED=8A=B8=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../project.pbxproj | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/Project17-C-Map/InteractiveClusteringMap.xcodeproj/project.pbxproj b/Project17-C-Map/InteractiveClusteringMap.xcodeproj/project.pbxproj index 1ad5c95..4126f1a 100644 --- a/Project17-C-Map/InteractiveClusteringMap.xcodeproj/project.pbxproj +++ b/Project17-C-Map/InteractiveClusteringMap.xcodeproj/project.pbxproj @@ -23,13 +23,11 @@ 372216CD256943D300231245 /* POI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 372216CC256943D300231245 /* POI.swift */; }; 37279B03256EBC5200EA689A /* KMeansTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37279B02256EBC5200EA689A /* KMeansTests.swift */; }; 37279B0B256EBC6E00EA689A /* KMeansClustering.swift in Sources */ = {isa = PBXBuildFile; fileRef = 379DC4C5256E1EC60044DA6C /* KMeansClustering.swift */; }; - 37311088256F641400350D55 /* MockPOIService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37311087256F641400350D55 /* MockPOIService.swift */; }; 3731108C256F641F00350D55 /* POIService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3753DCEF256B4C5B006D26A9 /* POIService.swift */; }; 37352CD125695B8A00CAFDFD /* restuarant-list-for-test.json in Resources */ = {isa = PBXBuildFile; fileRef = 37352CD025695B8A00CAFDFD /* restuarant-list-for-test.json */; }; 37352CDB25695E7400CAFDFD /* JSONReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37352CDA25695E7400CAFDFD /* JSONReader.swift */; }; 37352CE025695EE000CAFDFD /* Place.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37352CDF25695EE000CAFDFD /* Place.swift */; }; 3753DCF0256B4C5B006D26A9 /* POIService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3753DCEF256B4C5B006D26A9 /* POIService.swift */; }; - 376E43BA256F9811002D3EE9 /* MockPOIService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37311087256F641400350D55 /* MockPOIService.swift */; }; 379DC4C6256E1EC60044DA6C /* KMeansClustering.swift in Sources */ = {isa = PBXBuildFile; fileRef = 379DC4C5256E1EC60044DA6C /* KMeansClustering.swift */; }; 37EB73292562592700AC44D6 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37EB73282562592700AC44D6 /* AppDelegate.swift */; }; 37EB732B2562592700AC44D6 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37EB732A2562592700AC44D6 /* SceneDelegate.swift */; }; @@ -56,6 +54,8 @@ FAC9FD0E256E2495009FBB41 /* KCoefficient.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAC9FD04256E2107009FBB41 /* KCoefficient.swift */; }; FCE422B02570194B0017416F /* Coordinate.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCE422AF2570194B0017416F /* Coordinate.swift */; }; FCE422B8257019650017416F /* Cluster.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCE422B7257019650017416F /* Cluster.swift */; }; + FCE422BD25701A200017416F /* Quadrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCE422BC25701A200017416F /* Quadrant.swift */; }; + FCE422C225701A390017416F /* Degree.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCE422C125701A390017416F /* Degree.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -84,7 +84,6 @@ 372216C02569325600231245 /* DataManagable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataManagable.swift; sourceTree = ""; }; 372216CC256943D300231245 /* POI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = POI.swift; sourceTree = ""; }; 37279B02256EBC5200EA689A /* KMeansTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMeansTests.swift; sourceTree = ""; }; - 37311087256F641400350D55 /* MockPOIService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockPOIService.swift; sourceTree = ""; }; 37352CD025695B8A00CAFDFD /* restuarant-list-for-test.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "restuarant-list-for-test.json"; sourceTree = ""; }; 37352CDA25695E7400CAFDFD /* JSONReader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JSONReader.swift; sourceTree = ""; }; 37352CDF25695EE000CAFDFD /* Place.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Place.swift; sourceTree = ""; }; @@ -118,6 +117,8 @@ FAC9FD09256E23B1009FBB41 /* KDefineTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KDefineTests.swift; sourceTree = ""; }; FCE422AF2570194B0017416F /* Coordinate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Coordinate.swift; sourceTree = ""; }; FCE422B7257019650017416F /* Cluster.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Cluster.swift; sourceTree = ""; }; + FCE422BC25701A200017416F /* Quadrant.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Quadrant.swift; sourceTree = ""; }; + FCE422C125701A390017416F /* Degree.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Degree.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -225,7 +226,6 @@ 46A12E3E256CEDD3007BDF3E /* QuadTreeTests */, 37EB73422562592900AC44D6 /* InteractiveClusteringMapTests.swift */, 37279B02256EBC5200EA689A /* KMeansTests.swift */, - 37311087256F641400350D55 /* MockPOIService.swift */, 3713D3DB25694C3E00E703EC /* CoreDataStackTests.swift */, FAC9FD09256E23B1009FBB41 /* KDefineTests.swift */, 37EB73442562592900AC44D6 /* Info.plist */, @@ -310,6 +310,8 @@ children = ( FAC9FD04256E2107009FBB41 /* KCoefficient.swift */, 379DC4C5256E1EC60044DA6C /* KMeansClustering.swift */, + FCE422BC25701A200017416F /* Quadrant.swift */, + FCE422C125701A390017416F /* Degree.swift */, ); path = KMeans; sourceTree = ""; @@ -524,11 +526,12 @@ FCE422B8257019650017416F /* Cluster.swift in Sources */, 192D34AD256E355500861703 /* QuadTree.swift in Sources */, 46A12E1B256CD099007BDF3E /* Extension.swift in Sources */, + FCE422BD25701A200017416F /* Quadrant.swift in Sources */, 37352CDB25695E7400CAFDFD /* JSONReader.swift in Sources */, 46A12E23256CD4DB007BDF3E /* BoundingBox.swift in Sources */, FAC9FD05256E2107009FBB41 /* KCoefficient.swift in Sources */, 37EB73292562592700AC44D6 /* AppDelegate.swift in Sources */, - 376E43BA256F9811002D3EE9 /* MockPOIService.swift in Sources */, + FCE422C225701A390017416F /* Degree.swift in Sources */, 372216C12569325600231245 /* DataManagable.swift in Sources */, 37352CE025695EE000CAFDFD /* Place.swift in Sources */, 37EB732B2562592700AC44D6 /* SceneDelegate.swift in Sources */, @@ -551,7 +554,6 @@ 46A12E2F256CED3A007BDF3E /* AppDelegate.swift in Sources */, 46A12E27256CED18007BDF3E /* POIEntity+CoreDataClass.swift in Sources */, 37EB73432562592900AC44D6 /* InteractiveClusteringMapTests.swift in Sources */, - 37311088256F641400350D55 /* MockPOIService.swift in Sources */, 46A12E3A256CED57007BDF3E /* JSONReader.swift in Sources */, 192D34BA256E36A200861703 /* BoundingBox.swift in Sources */, 192D34B2256E368D00861703 /* QuadTreeTests.swift in Sources */, From 98060d41272386ca22f9259f6fed52f112c31245 Mon Sep 17 00:00:00 2001 From: seungeon Date: Fri, 27 Nov 2020 02:25:48 +0900 Subject: [PATCH 10/14] =?UTF-8?q?[feat]=20=ED=98=84=EC=9E=AC=20=EC=9C=84?= =?UTF-8?q?=EC=B9=98=20=EA=B8=B0=EC=A4=80=EC=97=90=20=EB=8C=80=ED=95=9C=20?= =?UTF-8?q?=EA=B0=81=EB=8F=84=20=EA=B3=84=EC=82=B0=20=ED=95=A8=EC=88=98=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../InteractiveClusteringMap/VO/Coordinate.swift | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Project17-C-Map/InteractiveClusteringMap/VO/Coordinate.swift b/Project17-C-Map/InteractiveClusteringMap/VO/Coordinate.swift index cd8dab4..b7935d6 100644 --- a/Project17-C-Map/InteractiveClusteringMap/VO/Coordinate.swift +++ b/Project17-C-Map/InteractiveClusteringMap/VO/Coordinate.swift @@ -26,6 +26,12 @@ struct Coordinate { return Coordinate(x: centerX, y: centerY) } + func findTheta(vertex: Coordinate) -> Double { + let gradient = (vertex.y - self.y) / (vertex.x - self.x) + + return atan(gradient) * 180 / .pi + } + } extension Coordinate: Hashable { From 938affaa95df100c6b49ea6b0dd77535094c5c82 Mon Sep 17 00:00:00 2001 From: seungeon Date: Fri, 27 Nov 2020 02:26:12 +0900 Subject: [PATCH 11/14] =?UTF-8?q?[refactor]=20k=20=EA=B3=84=EC=88=98=20?= =?UTF-8?q?=EB=84=A4=EC=9D=B4=EB=B0=8D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Clustering/KMeans/KMeansClustering.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Project17-C-Map/InteractiveClusteringMap/Clustering/KMeans/KMeansClustering.swift b/Project17-C-Map/InteractiveClusteringMap/Clustering/KMeans/KMeansClustering.swift index f55624c..0247b3e 100644 --- a/Project17-C-Map/InteractiveClusteringMap/Clustering/KMeans/KMeansClustering.swift +++ b/Project17-C-Map/InteractiveClusteringMap/Clustering/KMeans/KMeansClustering.swift @@ -18,7 +18,7 @@ class KMeansClustering { func randomCentroids(rangeOfLat lats: ClosedRange, rangeOfLng lngs: ClosedRange) -> [Coordinate] { var centroids: [Coordinate] = [] - for _ in 0.. Date: Fri, 27 Nov 2020 02:31:35 +0900 Subject: [PATCH 12/14] =?UTF-8?q?[refactor]=20KMeansClusterting=20?= =?UTF-8?q?=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=9D=B4=EB=A6=84=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - KMeansClustering -> KMeans --- .../project.pbxproj | 24 ++++++++++++++----- .../{KMeansClustering.swift => KMeans.swift} | 4 ++-- 2 files changed, 20 insertions(+), 8 deletions(-) rename Project17-C-Map/InteractiveClusteringMap/Clustering/KMeans/{KMeansClustering.swift => KMeans.swift} (99%) diff --git a/Project17-C-Map/InteractiveClusteringMap.xcodeproj/project.pbxproj b/Project17-C-Map/InteractiveClusteringMap.xcodeproj/project.pbxproj index 4126f1a..d0faf96 100644 --- a/Project17-C-Map/InteractiveClusteringMap.xcodeproj/project.pbxproj +++ b/Project17-C-Map/InteractiveClusteringMap.xcodeproj/project.pbxproj @@ -22,13 +22,13 @@ 372216C12569325600231245 /* DataManagable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 372216C02569325600231245 /* DataManagable.swift */; }; 372216CD256943D300231245 /* POI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 372216CC256943D300231245 /* POI.swift */; }; 37279B03256EBC5200EA689A /* KMeansTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37279B02256EBC5200EA689A /* KMeansTests.swift */; }; - 37279B0B256EBC6E00EA689A /* KMeansClustering.swift in Sources */ = {isa = PBXBuildFile; fileRef = 379DC4C5256E1EC60044DA6C /* KMeansClustering.swift */; }; + 37279B0B256EBC6E00EA689A /* KMeans.swift in Sources */ = {isa = PBXBuildFile; fileRef = 379DC4C5256E1EC60044DA6C /* KMeans.swift */; }; 3731108C256F641F00350D55 /* POIService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3753DCEF256B4C5B006D26A9 /* POIService.swift */; }; 37352CD125695B8A00CAFDFD /* restuarant-list-for-test.json in Resources */ = {isa = PBXBuildFile; fileRef = 37352CD025695B8A00CAFDFD /* restuarant-list-for-test.json */; }; 37352CDB25695E7400CAFDFD /* JSONReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37352CDA25695E7400CAFDFD /* JSONReader.swift */; }; 37352CE025695EE000CAFDFD /* Place.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37352CDF25695EE000CAFDFD /* Place.swift */; }; 3753DCF0256B4C5B006D26A9 /* POIService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3753DCEF256B4C5B006D26A9 /* POIService.swift */; }; - 379DC4C6256E1EC60044DA6C /* KMeansClustering.swift in Sources */ = {isa = PBXBuildFile; fileRef = 379DC4C5256E1EC60044DA6C /* KMeansClustering.swift */; }; + 379DC4C6256E1EC60044DA6C /* KMeans.swift in Sources */ = {isa = PBXBuildFile; fileRef = 379DC4C5256E1EC60044DA6C /* KMeans.swift */; }; 37EB73292562592700AC44D6 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37EB73282562592700AC44D6 /* AppDelegate.swift */; }; 37EB732B2562592700AC44D6 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37EB732A2562592700AC44D6 /* SceneDelegate.swift */; }; 37EB732D2562592700AC44D6 /* MapViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37EB732C2562592700AC44D6 /* MapViewController.swift */; }; @@ -56,6 +56,11 @@ FCE422B8257019650017416F /* Cluster.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCE422B7257019650017416F /* Cluster.swift */; }; FCE422BD25701A200017416F /* Quadrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCE422BC25701A200017416F /* Quadrant.swift */; }; FCE422C225701A390017416F /* Degree.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCE422C125701A390017416F /* Degree.swift */; }; + FCE422C725701B8A0017416F /* KMeansCentroidsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCE422C625701B8A0017416F /* KMeansCentroidsTest.swift */; }; + FCE422CE25701C760017416F /* Coordinate.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCE422AF2570194B0017416F /* Coordinate.swift */; }; + FCE422D225701C790017416F /* Cluster.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCE422B7257019650017416F /* Cluster.swift */; }; + FCE422D625701CBD0017416F /* Quadrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCE422BC25701A200017416F /* Quadrant.swift */; }; + FCE422DA25701CC00017416F /* Degree.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCE422C125701A390017416F /* Degree.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -88,7 +93,7 @@ 37352CDA25695E7400CAFDFD /* JSONReader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JSONReader.swift; sourceTree = ""; }; 37352CDF25695EE000CAFDFD /* Place.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Place.swift; sourceTree = ""; }; 3753DCEF256B4C5B006D26A9 /* POIService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = POIService.swift; sourceTree = ""; }; - 379DC4C5256E1EC60044DA6C /* KMeansClustering.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMeansClustering.swift; sourceTree = ""; }; + 379DC4C5256E1EC60044DA6C /* KMeans.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMeans.swift; sourceTree = ""; }; 37EB73252562592700AC44D6 /* InteractiveClusteringMap.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = InteractiveClusteringMap.app; sourceTree = BUILT_PRODUCTS_DIR; }; 37EB73282562592700AC44D6 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 37EB732A2562592700AC44D6 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; @@ -119,6 +124,7 @@ FCE422B7257019650017416F /* Cluster.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Cluster.swift; sourceTree = ""; }; FCE422BC25701A200017416F /* Quadrant.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Quadrant.swift; sourceTree = ""; }; FCE422C125701A390017416F /* Degree.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Degree.swift; sourceTree = ""; }; + FCE422C625701B8A0017416F /* KMeansCentroidsTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMeansCentroidsTest.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -229,6 +235,7 @@ 3713D3DB25694C3E00E703EC /* CoreDataStackTests.swift */, FAC9FD09256E23B1009FBB41 /* KDefineTests.swift */, 37EB73442562592900AC44D6 /* Info.plist */, + FCE422C625701B8A0017416F /* KMeansCentroidsTest.swift */, ); path = InteractiveClusteringMapTests; sourceTree = ""; @@ -309,7 +316,7 @@ isa = PBXGroup; children = ( FAC9FD04256E2107009FBB41 /* KCoefficient.swift */, - 379DC4C5256E1EC60044DA6C /* KMeansClustering.swift */, + 379DC4C5256E1EC60044DA6C /* KMeans.swift */, FCE422BC25701A200017416F /* Quadrant.swift */, FCE422C125701A390017416F /* Degree.swift */, ); @@ -517,7 +524,7 @@ 37EB73292562592700AC44D6 /* AppDelegate.swift in Sources */, 4623BD1325694A1400940B12 /* MapController.swift in Sources */, 372216CD256943D300231245 /* POI.swift in Sources */, - 379DC4C6256E1EC60044DA6C /* KMeansClustering.swift in Sources */, + 379DC4C6256E1EC60044DA6C /* KMeans.swift in Sources */, 3753DCF0256B4C5B006D26A9 /* POIService.swift in Sources */, FA81D67825690F360023E123 /* CoreDataStack.swift in Sources */, FCE422B02570194B0017416F /* Coordinate.swift in Sources */, @@ -542,13 +549,17 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + FCE422D225701C790017416F /* Cluster.swift in Sources */, FAC9FD0E256E2495009FBB41 /* KCoefficient.swift in Sources */, 192D34BE256E36B900861703 /* Extension.swift in Sources */, 3713D3E425694CD300E703EC /* POI.swift in Sources */, 46A12E2B256CED1B007BDF3E /* POIEntity+CoreDataProperties.swift in Sources */, - 37279B0B256EBC6E00EA689A /* KMeansClustering.swift in Sources */, + 37279B0B256EBC6E00EA689A /* KMeans.swift in Sources */, + FCE422DA25701CC00017416F /* Degree.swift in Sources */, + FCE422CE25701C760017416F /* Coordinate.swift in Sources */, 3713D3E025694C6B00E703EC /* CoreDataStack.swift in Sources */, 3731108C256F641F00350D55 /* POIService.swift in Sources */, + FCE422D625701CBD0017416F /* Quadrant.swift in Sources */, 46A12E40256CEDF2007BDF3E /* BoundingBoxTests.swift in Sources */, 192D34B6256E36A000861703 /* QuadTree.swift in Sources */, 46A12E2F256CED3A007BDF3E /* AppDelegate.swift in Sources */, @@ -558,6 +569,7 @@ 192D34BA256E36A200861703 /* BoundingBox.swift in Sources */, 192D34B2256E368D00861703 /* QuadTreeTests.swift in Sources */, 199DDFF6256B9C8E0065B94E /* Place.swift in Sources */, + FCE422C725701B8A0017416F /* KMeansCentroidsTest.swift in Sources */, 3713D3FA25694D9C00E703EC /* DataManagable.swift in Sources */, 37279B03256EBC5200EA689A /* KMeansTests.swift in Sources */, FAC9FD0A256E23B1009FBB41 /* KDefineTests.swift in Sources */, diff --git a/Project17-C-Map/InteractiveClusteringMap/Clustering/KMeans/KMeansClustering.swift b/Project17-C-Map/InteractiveClusteringMap/Clustering/KMeans/KMeans.swift similarity index 99% rename from Project17-C-Map/InteractiveClusteringMap/Clustering/KMeans/KMeansClustering.swift rename to Project17-C-Map/InteractiveClusteringMap/Clustering/KMeans/KMeans.swift index 0247b3e..ca0ff7e 100644 --- a/Project17-C-Map/InteractiveClusteringMap/Clustering/KMeans/KMeansClustering.swift +++ b/Project17-C-Map/InteractiveClusteringMap/Clustering/KMeans/KMeans.swift @@ -1,5 +1,5 @@ // -// KMeansClustering.swift +// KMeans.swift // InteractiveClusteringMap // // Created by Oh Donggeon on 2020/11/25. @@ -7,7 +7,7 @@ import Foundation -class KMeansClustering { +class KMeans { private let k: Int From 147b1c6f94ef3e6c6ec6ba568155215001f745b1 Mon Sep 17 00:00:00 2001 From: seungeon Date: Fri, 27 Nov 2020 02:32:05 +0900 Subject: [PATCH 13/14] =?UTF-8?q?[refactor]=20=ED=81=B4=EB=9E=98=EC=8A=A4?= =?UTF-8?q?=EB=AA=85=20=EB=B3=80=EA=B2=BD=EC=9C=BC=EB=A1=9C=20=EC=9D=B8?= =?UTF-8?q?=ED=95=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Project17-C-Map/InteractiveClusteringMapTests/KMeansTests.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project17-C-Map/InteractiveClusteringMapTests/KMeansTests.swift b/Project17-C-Map/InteractiveClusteringMapTests/KMeansTests.swift index d0b708a..a19195c 100644 --- a/Project17-C-Map/InteractiveClusteringMapTests/KMeansTests.swift +++ b/Project17-C-Map/InteractiveClusteringMapTests/KMeansTests.swift @@ -66,7 +66,7 @@ class KMeansTests: XCTestCase { } func test_kmeans_clustering() throws { - let kmeans = KMeansClustering(k: 4) + let kmeans = KMeans(k: 4) let clusters = kmeans.trainCenters(points, initialCentroids: coordinates) let expectPoints: [[Coordinate]] = [[Coordinate(x: 1, y: 1), Coordinate(x: 2, y: 2)], [Coordinate(x: 8, y: 2), Coordinate(x: 9, y: 1)], From 378237987230e983906b9af0fdff0fe116c13c58 Mon Sep 17 00:00:00 2001 From: seungeon Date: Fri, 27 Nov 2020 02:32:47 +0900 Subject: [PATCH 14/14] =?UTF-8?q?[test]=20KMeans=20=EC=A4=91=EC=8B=AC?= =?UTF-8?q?=EA=B0=92=20=EC=83=9D=EC=84=B1=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../KMeansCentroidsTest.swift | 99 +++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 Project17-C-Map/InteractiveClusteringMapTests/KMeansCentroidsTest.swift diff --git a/Project17-C-Map/InteractiveClusteringMapTests/KMeansCentroidsTest.swift b/Project17-C-Map/InteractiveClusteringMapTests/KMeansCentroidsTest.swift new file mode 100644 index 0000000..b0fce60 --- /dev/null +++ b/Project17-C-Map/InteractiveClusteringMapTests/KMeansCentroidsTest.swift @@ -0,0 +1,99 @@ +// +// KMeansCentroidsTest.swift +// InteractiveClusteringMapTests +// +// Created by Seungeon Kim on 2020/11/27. +// + +import XCTest + +class KMeansCentroidsTest: XCTestCase { + + func test_2split_coordinates_by_screen() throws { + let centroids = mockCentoidsByScreen(number: 2) + let expected = [ + Coordinate(x: 128.0000, y: 35.5000), + Coordinate(x: 128.0000, y: 40.5000) + ] + + validateCendroids(centroids: centroids, expected: expected) + } + + func test_4split_coordinates_by_screen() throws { + let centroids = mockCentoidsByScreen(number: 4) + let expected = [ + Coordinate(x: 130.0000, y: 38.0000), + Coordinate(x: 128.0000, y: 35.5000), + Coordinate(x: 126.0000, y: 38.0000), + Coordinate(x: 128.0000, y: 40.5000) + ] + + validateCendroids(centroids: centroids, expected: expected) + } + + func test_6split_coordinates_by_screen() throws { + let centroids = mockCentoidsByScreen(number: 6) + let expected = [ + Coordinate(x: 130.0000, y: 39.1547), + Coordinate(x: 130.0000, y: 36.8452), + Coordinate(x: 128.0000, y: 35.5000), + Coordinate(x: 126.0000, y: 36.8452), + Coordinate(x: 126.0000, y: 39.1547), + Coordinate(x: 128.0000, y: 40.5000) + ] + + validateCendroids(centroids: centroids, expected: expected) + } + + func test_7split_coordinates_by_screen() throws { + let centroids = mockCentoidsByScreen(number: 7) + let expected = [ + Coordinate(x: 130.0000, y: 39.5949), + Coordinate(x: 130.0000, y: 37.5435), + Coordinate(x: 129.2039, y: 35.5000), + Coordinate(x: 126.7960, y: 35.5000), + Coordinate(x: 126.0000, y: 37.5435), + Coordinate(x: 126.0000, y: 39.5949), + Coordinate(x: 128.0000, y: 40.5000) + ] + + validateCendroids(centroids: centroids, expected: expected) + } + + func test_coordinates_by_random() throws { + let cendroids = mockCentoidsByRandom(number: 1000) + + cendroids.forEach { cendroid in + validateCendtoid(cendroid: cendroid) + } + } + + private func validateCendroids(centroids: [Coordinate], expected: [Coordinate]) { + XCTAssertEqual(centroids.count, expected.count) + + let count = centroids.count + for i in 0.. [Coordinate] { + let kmm = KMeans(k: number) + let topLeft = Coordinate(x: 124.0, y: 43.0) + let bottomRight = Coordinate(x: 132.0, y: 33.0) + return kmm.screenCentroids(topLeft: topLeft, bottomRight: bottomRight) + } + + private func mockCentoidsByRandom(number: Int) -> [Coordinate] { + let kmm = KMeans(k: number) + + return kmm.randomCentroids(rangeOfLat: 33.0...43.0, rangeOfLng: 123.0...132.0) + } + +}