Just another update
This commit is contained in:
parent
a25938f123
commit
00a190b0a6
6591 changed files with 94363 additions and 23227 deletions
|
|
@ -1,24 +1,133 @@
|
|||
import scala.util._
|
||||
import scala.collection.mutable.ListBuffer
|
||||
import scala.util.Random
|
||||
|
||||
object ClosestPair{
|
||||
class Point(x:Double, y:Double) extends Pair(x,y){
|
||||
def distance(p:Point)=math.hypot(_1-p._1, _2-p._2)
|
||||
}
|
||||
object ClosestPair {
|
||||
case class Point(x: Double, y: Double){
|
||||
def distance(p: Point) = math.hypot(x-p.x, y-p.y)
|
||||
|
||||
def closestPairBF(a:Array[Point])={
|
||||
var minDist=a(0) distance a(1)
|
||||
var minPoints=(a(0), a(1))
|
||||
override def toString = "(" + x + ", " + y + ")"
|
||||
}
|
||||
|
||||
for(p1<-a; p2<-a if p1.ne(p2); dist=p1 distance p2 if(dist<minDist)){
|
||||
minDist=dist;
|
||||
minPoints=(p1, p2)
|
||||
case class Pair(point1: Point, point2: Point) {
|
||||
val distance: Double = point1 distance point2
|
||||
|
||||
override def toString = {
|
||||
point1 + "-" + point2 + " : " + distance
|
||||
}
|
||||
}
|
||||
|
||||
def sortByX(points: List[Point]) = {
|
||||
points.sortBy(point => point.x)
|
||||
}
|
||||
|
||||
def sortByY(points: List[Point]) = {
|
||||
points.sortBy(point => point.y)
|
||||
}
|
||||
|
||||
def divideAndConquer(points: List[Point]): Pair = {
|
||||
val pointsSortedByX = sortByX(points)
|
||||
val pointsSortedByY = sortByY(points)
|
||||
|
||||
divideAndConquer(pointsSortedByX, pointsSortedByY)
|
||||
}
|
||||
|
||||
def bruteForce(points: List[Point]): Pair = {
|
||||
val numPoints = points.size
|
||||
if (numPoints < 2)
|
||||
return null
|
||||
var pair = Pair(points(0), points(1))
|
||||
if (numPoints > 2) {
|
||||
for (i <- 0 until numPoints - 1) {
|
||||
val point1 = points(i)
|
||||
for (j <- i + 1 until numPoints) {
|
||||
val point2 = points(j)
|
||||
val distance = point1 distance point2
|
||||
if (distance < pair.distance)
|
||||
pair = Pair(point1, point2)
|
||||
}
|
||||
}
|
||||
(minPoints, minDist)
|
||||
}
|
||||
}
|
||||
return pair
|
||||
}
|
||||
|
||||
def main(args: Array[String]): Unit = {
|
||||
val a=Array.fill(1000)(new Point(Random.nextDouble, Random.nextDouble))
|
||||
val (points, dist)=closestPairBF(a)
|
||||
println("min: "+points._1+" - "+points._2+" ->"+dist)
|
||||
}
|
||||
|
||||
private def divideAndConquer(pointsSortedByX: List[Point], pointsSortedByY: List[Point]): Pair = {
|
||||
val numPoints = pointsSortedByX.size
|
||||
if(numPoints <= 3) {
|
||||
return bruteForce(pointsSortedByX)
|
||||
}
|
||||
|
||||
val dividingIndex = numPoints >>> 1
|
||||
val leftOfCenter = pointsSortedByX.slice(0, dividingIndex)
|
||||
val rightOfCenter = pointsSortedByX.slice(dividingIndex, numPoints)
|
||||
|
||||
var tempList = leftOfCenter.map(x => x)
|
||||
//println(tempList)
|
||||
tempList = sortByY(tempList)
|
||||
var closestPair = divideAndConquer(leftOfCenter, tempList)
|
||||
|
||||
tempList = rightOfCenter.map(x => x)
|
||||
tempList = sortByY(tempList)
|
||||
|
||||
val closestPairRight = divideAndConquer(rightOfCenter, tempList)
|
||||
|
||||
if (closestPairRight.distance < closestPair.distance)
|
||||
closestPair = closestPairRight
|
||||
|
||||
tempList = List[Point]()
|
||||
val shortestDistance = closestPair.distance
|
||||
val centerX = rightOfCenter(0).x
|
||||
|
||||
for (point <- pointsSortedByY) {
|
||||
if (Math.abs(centerX - point.x) < shortestDistance)
|
||||
tempList = tempList :+ point
|
||||
}
|
||||
|
||||
closestPair = shortestDistanceF(tempList, shortestDistance, closestPair)
|
||||
closestPair
|
||||
}
|
||||
|
||||
private def shortestDistanceF(tempList: List[Point], shortestDistance: Double, closestPair: Pair ): Pair = {
|
||||
var shortest = shortestDistance
|
||||
var bestResult = closestPair
|
||||
for (i <- 0 until tempList.size) {
|
||||
val point1 = tempList(i)
|
||||
for (j <- i + 1 until tempList.size) {
|
||||
val point2 = tempList(j)
|
||||
if ((point2.y - point1.y) >= shortestDistance)
|
||||
return closestPair
|
||||
val distance = point1 distance point2
|
||||
if (distance < closestPair.distance)
|
||||
{
|
||||
bestResult = Pair(point1, point2)
|
||||
shortest = distance
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
closestPair
|
||||
}
|
||||
|
||||
def main(args: Array[String]) {
|
||||
val numPoints = if(args.length == 0) 1000 else args(0).toInt
|
||||
|
||||
val points = ListBuffer[Point]()
|
||||
val r = new Random()
|
||||
for (i <- 0 until numPoints) {
|
||||
points.+=:(new Point(r.nextDouble(), r.nextDouble()))
|
||||
}
|
||||
println("Generated " + numPoints + " random points")
|
||||
|
||||
var startTime = System.currentTimeMillis()
|
||||
val bruteForceClosestPair = bruteForce(points.toList)
|
||||
var elapsedTime = System.currentTimeMillis() - startTime
|
||||
println("Brute force (" + elapsedTime + " ms): " + bruteForceClosestPair)
|
||||
|
||||
startTime = System.currentTimeMillis()
|
||||
val dqClosestPair = divideAndConquer(points.toList)
|
||||
elapsedTime = System.currentTimeMillis() - startTime
|
||||
println("Divide and conquer (" + elapsedTime + " ms): " + dqClosestPair)
|
||||
if (bruteForceClosestPair.distance != dqClosestPair.distance)
|
||||
println("MISMATCH")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue