-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
KMeans 중심값 생성 함수 추가 (BallCut) #37
Merged
Merged
Changes from all commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
2169959
[feat] random coordinate 생성 함수 추가
Seungeon-Kim 95d47d1
[chore] 테스트 파일 위치 이동
Seungeon-Kim 49c64c4
[refactor] 함수 이름 변경
Seungeon-Kim 0aa4c97
[feat] 중심값 생성 함수 추가 (ball cut)
Seungeon-Kim bd7e272
[chore] 프로젝트 정리
Seungeon-Kim 725b8a8
[refactor] 함수명 변경으로인한 수정
Seungeon-Kim d1879f9
[refactor] 변수명 변경
Seungeon-Kim aeb1cd7
[refactor] 코드리뷰 반영
Seungeon-Kim 83a72c7
[style] 탭 추가
Seungeon-Kim 3cb67f0
[chore] 프로젝트 그룹변경
Seungeon-Kim 822d0bf
[refactor] Kmeans 구조 변경
Seungeon-Kim 7897efb
[feat] 화면 기준 분할 중심값 생성 클래스 추가
Seungeon-Kim 6ce21bb
[feat] 랜덤 중심값 생성 클래스 추가
Seungeon-Kim 745938f
[feat] 거리 보정 중심값 생성 클래스 추가
Seungeon-Kim 09bc2c8
[chore] 프로젝트 정리
Seungeon-Kim 733cd09
Merge branch 'feature/kmeans/initialize-centroids' of https://github.…
Seungeon-Kim 15fd1b4
[refactor] : 코드 리뷰 반영
Seungeon-Kim File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
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
79 changes: 79 additions & 0 deletions
79
...C-Map/InteractiveClusteringMap/Clustering/KMeans/Centroids/BallCutCentroidGenerator.swift
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,79 @@ | ||
// | ||
// BallCutCentroidGenerator.swift | ||
// InteractiveClusteringMap | ||
// | ||
// Created by Seungeon Kim on 2020/11/28. | ||
// | ||
|
||
import Foundation | ||
|
||
final class BallCutCentroidGenerator: CentroidCreatable { | ||
|
||
private let coverage: Double | ||
private let k: Int | ||
private let points: [Coordinate] | ||
private let mutiplier: Int = 5 | ||
|
||
init(k: Int, coverage: Double, coordinates: [Coordinate]) { | ||
self.k = k | ||
self.coverage = coverage | ||
self.points = coordinates | ||
} | ||
|
||
func centroids() -> [Coordinate] { | ||
return recursiveClassify(k: k, coordinates: points) | ||
} | ||
|
||
private func recursiveClassify(k: Int, coordinates: [Coordinate]) -> [Coordinate] { | ||
var coordinates = coordinates | ||
let container = createContainer(k: k, coordinates: coordinates) | ||
var centroids: [Coordinate] = pickCentroids(k: k, distance: coverage, container: container) | ||
|
||
guard centroids.count == k else { return centroids } | ||
|
||
for coordinate in container { | ||
guard let index = coordinates.firstIndex(of: coordinate) else { | ||
return [] | ||
} | ||
coordinates.remove(at: index) | ||
} | ||
|
||
centroids += recursiveClassify(k: k - centroids.count + 1, coordinates: coordinates) | ||
return centroids | ||
} | ||
|
||
private func createContainer(k: Int, coordinates: [Coordinate]) -> [Coordinate] { | ||
var coordinates = coordinates | ||
var container: [Coordinate] = [] | ||
let count = k * mutiplier | ||
|
||
for _ in 0..<count { | ||
guard let coordinate = coordinates.randomElement(), | ||
let index = coordinates.firstIndex(of: coordinate) | ||
else { | ||
return [] | ||
} | ||
container.append(coordinate) | ||
coordinates.remove(at: index) | ||
} | ||
|
||
return container | ||
} | ||
|
||
private func pickCentroids(k: Int, distance: Double, container: [Coordinate]) -> [Coordinate] { | ||
var centroids: [Coordinate] = [] | ||
var container = container | ||
|
||
for _ in 0..<k { | ||
guard let centroid = container.randomElement() else { | ||
return centroids | ||
} | ||
|
||
container = container.filter { centroid.distanceTo($0) >= distance } | ||
centroids.append(centroid) | ||
} | ||
|
||
return centroids | ||
} | ||
|
||
} |
32 changes: 32 additions & 0 deletions
32
...-C-Map/InteractiveClusteringMap/Clustering/KMeans/Centroids/RandomCentroidGenerator.swift
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,32 @@ | ||
// | ||
// RandomCetroidGenerator.swift | ||
// InteractiveClusteringMap | ||
// | ||
// Created by Seungeon Kim on 2020/11/28. | ||
// | ||
|
||
import Foundation | ||
|
||
final class RandomCentroidGenerator: CentroidCreatable { | ||
|
||
private let k: Int | ||
private let lats: ClosedRange<Double> | ||
private let lngs: ClosedRange<Double> | ||
|
||
init(k: Int, rangeOfLat: ClosedRange<Double>, rangeOfLng: ClosedRange<Double>) { | ||
self.k = k | ||
self.lats = rangeOfLat | ||
self.lngs = rangeOfLng | ||
} | ||
|
||
func centroids() -> [Coordinate] { | ||
var centroids: [Coordinate] = [] | ||
for _ in 0..<k { | ||
let cluster = Coordinate.randomGenerate(rangeOfLat: lats, rangeOfLng: lngs) | ||
centroids.append(cluster) | ||
} | ||
|
||
return centroids | ||
} | ||
|
||
} |
62 changes: 62 additions & 0 deletions
62
...-C-Map/InteractiveClusteringMap/Clustering/KMeans/Centroids/ScreenCentroidGenerator.swift
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,62 @@ | ||
// | ||
// ScreenCentroidGenerator.swift | ||
// InteractiveClusteringMap | ||
// | ||
// Created by Seungeon Kim on 2020/11/28. | ||
// | ||
|
||
import Foundation | ||
|
||
final class ScreenCentroidGenerator: CentroidCreatable { | ||
|
||
private let topLeft: Coordinate | ||
private let bottomRight: Coordinate | ||
private let k: Int | ||
|
||
init(k: Int, topLeft: Coordinate, bottomRight: Coordinate) { | ||
self.k = k | ||
self.topLeft = topLeft | ||
self.bottomRight = bottomRight | ||
} | ||
|
||
func centroids() -> [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(k) | ||
var angle = increase | ||
var coords: [Coordinate] = [] | ||
|
||
for _ in 0..<k { | ||
let quadrant = Quadrant.findQuadrant(angle: angle) | ||
let modulus = angle.truncatingRemainder(dividingBy: Degree.right) | ||
|
||
if modulus == 0 { | ||
let distance = boundary / 2 | ||
let coord = quadrant.degree(center: center, boundary: distance) | ||
coords.append(coord) | ||
} else { | ||
let theta = quadrant.theta(angle: modulus) | ||
let radian = theta * .pi / Degree.straight | ||
var x: Double | ||
var y: Double | ||
|
||
if theta > 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 | ||
} | ||
|
||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
제가 보기엔 모두 순수함수로 작성하셔서 struct도 괜찮을거같은데 어떠신가요??
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이부분은 의논을 해보죠. 매니저 클래스 만들고 결정해봐야할 것 같아요!