Skip to content

Commit

Permalink
refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
arnauddri committed Feb 2, 2015
1 parent ea220d9 commit 13ccdf9
Show file tree
Hide file tree
Showing 20 changed files with 223 additions and 256 deletions.
10 changes: 0 additions & 10 deletions algorithms/maths/closest-pair/benchmark/output.txt

This file was deleted.

28 changes: 0 additions & 28 deletions algorithms/maths/closest-pair/brute_force.go

This file was deleted.

36 changes: 0 additions & 36 deletions algorithms/maths/closest-pair/brute_force_test.go

This file was deleted.

167 changes: 167 additions & 0 deletions algorithms/maths/closest-pair/closest_pair.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
package closest_pair

import (
"math"
"strconv"
)

type point struct {
x float64
y float64
}

type Point interface {
toString() string
}

func makePoint(x float64, y float64) *point {
A := new(point)
A.x = x
A.y = y

return A
}

func (A *point) toString() string {
return "(" + strconv.FormatFloat(A.x, 'f', -1, 64) + "," + strconv.FormatFloat(A.y, 'f', -1, 64) + ")"
}

type pair struct {
point1 point
point2 point
distance float64
}

type Pair interface {
calcDistance() float64
toString() string
}

func makePair(A point, B point) *pair {
P := new(pair)
P.point1 = A
P.point2 = B
P.distance = calcDistance(A, B)

return P
}

func calcDistance(A point, B point) float64 {
xdist := A.x - B.x
ydist := A.y - B.y

return math.Sqrt(float64(xdist*xdist + ydist*ydist))
}

func (P *pair) toString() string {
return P.point1.toString() + "-" + P.point2.toString() + "-" + strconv.FormatFloat(P.distance, 'f', -1, 64)
}

func DivideAndConquer(P []point) *pair {
n := len(P)

if n == 2 {
return makePair(P[0], P[1])
}

xP := make([]point, n)
yP := make([]point, n)

for i := 0; i < n; i++ {
xP[i] = P[i]
yP[i] = P[i]
}

_, pair := divideAndConquer(xP, yP)

return pair
}

func divideAndConquer(xP, yP []point) (float64, *pair) {
n := len(xP)

if n <= 3 {
p := BruteForce(xP)
return p.distance, p
}

xL := xP[:n>>1]
xR := xP[n>>1:]

var yL, yR []point
xMiddle := xL[0].x

// yL ← { p ∈ yP : px ≤ xMiddle }
// yR ← { p ∈ yP : px > xMiddle }
for _, p := range yP {
if p.x <= xMiddle {
yL = append(yL, p)
} else {
yR = append(yL, p)
}
}

// (dL, pairL) ← closestPair of (xL, yL)
// (dR, pairR) ← closestPair of (xR, yR)
dL, pairL := divideAndConquer(xL, yL)
dR, pairR := divideAndConquer(xR, yR)

dMin, pairMin := dR, pairR

if dL < dR {
dMin, pairMin = dL, pairL
}

var yS []point

// yS ← { p ∈ yP : |xMiddle - px| < dMin }
for i := 0; i < len(yP); i++ {
if math.Abs(yP[i].x-xMiddle) < dMin {
yS = append(yS, yP[i])
}
}

nS := len(yS)

if nS > 1 {
closestPair := pairMin
for i := 1; i < nS-1; i++ {
k := i + 1
for k <= nS && math.Abs(yS[k].y-yS[i].y) < dMin {
tempPair := makePair(yS[k], yS[i])
if tempPair.distance < closestPair.distance {
closestPair = tempPair
}
k++
}
}
return closestPair.distance, closestPair
} else {
return dMin, pairMin
}
}

func BruteForce(P []point) *pair {
n := len(P)

if n < 2 {
return nil
}

minPair := makePair(P[0], P[1])
tempPair := makePair(P[0], P[1])

min := minPair.distance
for i := 0; i < n-1; i++ {
tempPair.point1 = P[i]
for j := 0; j < n; j++ {
tempPair.point2 = P[j]
if min > tempPair.distance {
minPair = tempPair
min = tempPair.distance
}
}
}

return minPair
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,42 @@ func TestDivideAndConquer(t *testing.T) {

A := makePoint(float64(0), float64(0))
B := makePoint(float64(1), float64(1))
P := divideAndConquer(Points)
P := DivideAndConquer(Points)
if P.point1 != *A || P.point2 != *B {
fmt.Println(Points)
fmt.Println(P)
t.Error()
}
}
func TestBruteForce(t *testing.T) {
Points := make([]point, 10)
for i := 0; i < 10; i++ {
a := makePoint(float64(i), float64(i*i))

Points[i] = *a
}

A := makePoint(float64(0), float64(0))
B := makePoint(float64(1), float64(1))
P := BruteForce(Points)
if P.point1 != *A || P.point2 != *B {
fmt.Println(P.point1, *A, *B)
t.Error()
}
}

func BenchmarkBruteForce(b *testing.B) {
Points := make([]point, 10)
for i := 0; i < 10; i++ {
a := makePoint(float64(i), float64(i*i))

Points[i] = *a
}

for i := 0; i < b.N; i++ {
BruteForce(Points)
}
}

func benchmarkDivideAndConquer(n int, b *testing.B) {
Points := make([]point, n)
Expand All @@ -32,7 +61,7 @@ func benchmarkDivideAndConquer(n int, b *testing.B) {
}

for i := 0; i < b.N; i++ {
divideAndConquer(Points)
DivideAndConquer(Points)
}
}

Expand Down
89 changes: 0 additions & 89 deletions algorithms/maths/closest-pair/divide_and_conquer.go

This file was deleted.

Loading

0 comments on commit 13ccdf9

Please sign in to comment.