A-M baby
This commit is contained in:
parent
764da6cbbb
commit
db842d013d
19005 changed files with 197040 additions and 7 deletions
118
Task/Closest-pair-problem/Fantom/closest-pair-problem.fantom
Normal file
118
Task/Closest-pair-problem/Fantom/closest-pair-problem.fantom
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
class Point
|
||||
{
|
||||
Float x
|
||||
Float y
|
||||
|
||||
// create a random point
|
||||
new make (Float x := Float.random * 10, Float y := Float.random * 10)
|
||||
{
|
||||
this.x = x
|
||||
this.y = y
|
||||
}
|
||||
|
||||
Float distance (Point p)
|
||||
{
|
||||
((x-p.x)*(x-p.x) + (y-p.y)*(y-p.y)).sqrt
|
||||
}
|
||||
|
||||
override Str toStr () { "($x, $y)" }
|
||||
}
|
||||
|
||||
class Main
|
||||
{
|
||||
// use brute force approach
|
||||
static Point[] findClosestPair1 (Point[] points)
|
||||
{
|
||||
if (points.size < 2) return points // list too small
|
||||
Point[] closestPair := [points[0], points[1]]
|
||||
Float closestDistance := points[0].distance(points[1])
|
||||
|
||||
(1..<points.size).each |Int i|
|
||||
{
|
||||
((i+1)..<points.size).each |Int j|
|
||||
{
|
||||
Float trydistance := points[i].distance(points[j])
|
||||
if (trydistance < closestDistance)
|
||||
{
|
||||
closestPair = [points[i], points[j]]
|
||||
closestDistance = trydistance
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return closestPair
|
||||
}
|
||||
|
||||
// use recursive divide-and-conquer approach
|
||||
static Point[] findClosestPair2 (Point[] points)
|
||||
{
|
||||
if (points.size <= 3) return findClosestPair1(points)
|
||||
points.sort |Point a, Point b -> Int| { a.x <=> b.x }
|
||||
bestLeft := findClosestPair2 (points[0..(points.size/2)])
|
||||
bestRight := findClosestPair2 (points[(points.size/2)..-1])
|
||||
|
||||
Float minDistance
|
||||
Point[] closePoints := [,]
|
||||
if (bestLeft[0].distance(bestLeft[1]) < bestRight[0].distance(bestRight[1]))
|
||||
{
|
||||
minDistance = bestLeft[0].distance(bestLeft[1])
|
||||
closePoints = bestLeft
|
||||
}
|
||||
else
|
||||
{
|
||||
minDistance = bestRight[0].distance(bestRight[1])
|
||||
closePoints = bestRight
|
||||
}
|
||||
yPoints := points.findAll |Point p -> Bool|
|
||||
{
|
||||
(points.last.x - p.x).abs < minDistance
|
||||
}.sort |Point a, Point b -> Int| { a.y <=> b.y }
|
||||
|
||||
closestPair := [,]
|
||||
closestDist := Float.posInf
|
||||
|
||||
for (Int i := 0; i < yPoints.size - 1; ++i)
|
||||
{
|
||||
for (Int j := (i+1); j < yPoints.size; ++j)
|
||||
{
|
||||
if ((yPoints[j].y - yPoints[i].y) >= minDistance)
|
||||
{
|
||||
break
|
||||
}
|
||||
else
|
||||
{
|
||||
dist := yPoints[i].distance (yPoints[j])
|
||||
if (dist < closestDist)
|
||||
{
|
||||
closestDist = dist
|
||||
closestPair = [yPoints[i], yPoints[j]]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (closestDist < minDistance)
|
||||
return closestPair
|
||||
else
|
||||
return closePoints
|
||||
}
|
||||
|
||||
public static Void main (Str[] args)
|
||||
{
|
||||
Int numPoints := 10 // default value, in case a number not given on command line
|
||||
if ((args.size > 0) && (args[0].toInt(10, false) != null))
|
||||
{
|
||||
numPoints = args[0].toInt(10, false)
|
||||
}
|
||||
|
||||
Point[] points := [,]
|
||||
numPoints.times { points.add (Point()) }
|
||||
|
||||
Int t1 := Duration.now.toMillis
|
||||
echo (findClosestPair1(points.dup))
|
||||
Int t2 := Duration.now.toMillis
|
||||
echo ("Time taken: ${(t2-t1)}ms")
|
||||
echo (findClosestPair2(points.dup))
|
||||
Int t3 := Duration.now.toMillis
|
||||
echo ("Time taken: ${(t3-t2)}ms")
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
class Point {
|
||||
final Number x, y
|
||||
Point(Number x = 0, Number y = 0) { this.x = x; this.y = y }
|
||||
Number distance(Point that) { ((this.x - that.x)**2 + (this.y - that.y)**2)**0.5 }
|
||||
String toString() { "{x:${x}, y:${y}}" }
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
def bruteClosest(Collection pointCol) {
|
||||
assert pointCol
|
||||
List l = pointCol
|
||||
int n = l.size()
|
||||
assert n > 1
|
||||
if (n == 2) return [distance:l[0].distance(l[1]), points:[l[0],l[1]]]
|
||||
def answer = [distance: Double.POSITIVE_INFINITY]
|
||||
(0..<(n-1)).each { i ->
|
||||
((i+1)..<n).findAll { j ->
|
||||
(l[i].x - l[j].x).abs() < answer.distance &&
|
||||
(l[i].y - l[j].y).abs() < answer.distance
|
||||
}.each { j ->
|
||||
if ((l[i].x - l[j].x).abs() < answer.distance &&
|
||||
(l[i].y - l[j].y).abs() < answer.distance) {
|
||||
def dist = l[i].distance(l[j])
|
||||
if (dist < answer.distance) {
|
||||
answer = [distance:dist, points:[l[i],l[j]]]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
answer
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
def elegantClosest(Collection pointCol) {
|
||||
assert pointCol
|
||||
List xList = (pointCol as List).sort { it.x }
|
||||
List yList = xList.clone().sort { it.y }
|
||||
reductionClosest(xList, xList)
|
||||
}
|
||||
|
||||
def reductionClosest(List xPoints, List yPoints) {
|
||||
// assert xPoints && yPoints
|
||||
// assert (xPoints as Set) == (yPoints as Set)
|
||||
int n = xPoints.size()
|
||||
if (n < 10) return bruteClosest(xPoints)
|
||||
|
||||
int nMid = Math.ceil(n/2)
|
||||
List xLeft = xPoints[0..<nMid]
|
||||
List xRight = xPoints[nMid..<n]
|
||||
Number xMid = xLeft[-1].x
|
||||
List yLeft = yPoints.findAll { it.x <= xMid }
|
||||
List yRight = yPoints.findAll { it.x > xMid }
|
||||
if (xRight[0].x == xMid) {
|
||||
yLeft = xLeft.collect{ it }.sort { it.y }
|
||||
yRight = xRight.collect{ it }.sort { it.y }
|
||||
}
|
||||
|
||||
Map aLeft = reductionClosest(xLeft, yLeft)
|
||||
Map aRight = reductionClosest(xRight, yRight)
|
||||
Map aMin = aRight.distance < aLeft.distance ? aRight : aLeft
|
||||
List yMid = yPoints.findAll { (xMid - it.x).abs() < aMin.distance }
|
||||
int nyMid = yMid.size()
|
||||
if (nyMid < 2) return aMin
|
||||
|
||||
Map answer = aMin
|
||||
(0..<(nyMid-1)).each { i ->
|
||||
((i+1)..<nyMid).findAll { j ->
|
||||
(yMid[j].x - yMid[i].x).abs() < aMin.distance &&
|
||||
(yMid[j].y - yMid[i].y).abs() < aMin.distance &&
|
||||
yMid[j].distance(yMid[i]) < aMin.distance
|
||||
}.each { k ->
|
||||
if ((yMid[k].x - yMid[i].x).abs() < answer.distance && (yMid[k].y - yMid[i].y).abs() < answer.distance) {
|
||||
def ikDist = yMid[i].distance(yMid[k])
|
||||
if ( ikDist < answer.distance) {
|
||||
answer = [distance:ikDist, points:[yMid[i],yMid[k]]]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
answer
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
def random = new Random()
|
||||
|
||||
(1..4).each {
|
||||
def point10 = (0..<(10**it)).collect { new Point(random.nextInt(1000001) - 500000,random.nextInt(1000001) - 500000) }
|
||||
|
||||
def startE = System.currentTimeMillis()
|
||||
def closestE = elegantClosest(point10)
|
||||
def elapsedE = System.currentTimeMillis() - startE
|
||||
println """
|
||||
${10**it} POINTS
|
||||
-----------------------------------------
|
||||
Elegant reduction:
|
||||
elapsed: ${elapsedE/1000} s
|
||||
closest: ${closestE}
|
||||
"""
|
||||
|
||||
|
||||
def startB = System.currentTimeMillis()
|
||||
def closestB = bruteClosest(point10)
|
||||
def elapsedB = System.currentTimeMillis() - startB
|
||||
println """Brute force:
|
||||
elapsed: ${elapsedB/1000} s
|
||||
closest: ${closestB}
|
||||
|
||||
Speedup ratio (B/E): ${elapsedB/elapsedE}
|
||||
=========================================
|
||||
"""
|
||||
}
|
||||
25
Task/Closest-pair-problem/Icon/closest-pair-problem.icon
Normal file
25
Task/Closest-pair-problem/Icon/closest-pair-problem.icon
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
record point(x,y)
|
||||
|
||||
procedure main()
|
||||
minDist := 0
|
||||
minPair := &null
|
||||
every (points := [],p1 := readPoint()) do {
|
||||
if *points == 1 then minDist := dSquared(p1,points[1])
|
||||
every minDist >=:= dSquared(p1,p2 := !points) do minPair := [p1,p2]
|
||||
push(points, p1)
|
||||
}
|
||||
|
||||
if \minPair then {
|
||||
write("(",minPair[1].x,",",minPair[1].y,") -> ",
|
||||
"(",minPair[2].x,",",minPair[2].y,")")
|
||||
}
|
||||
else write("One or fewer points!")
|
||||
end
|
||||
|
||||
procedure readPoint() # Skips lines that don't have two numbers on them
|
||||
suspend !&input ? point(numeric(tab(upto(', '))), numeric((move(1),tab(0))))
|
||||
end
|
||||
|
||||
procedure dSquared(p1,p2) # Compute the square of the distance
|
||||
return (p2.x-p1.x)^2 + (p2.y-p1.y)^2 # (sufficient for closeness)
|
||||
end
|
||||
4
Task/Closest-pair-problem/J/closest-pair-problem-1.j
Normal file
4
Task/Closest-pair-problem/J/closest-pair-problem-1.j
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
vecl =: +/"1&.:*: NB. length of each of vectors
|
||||
dist =: <@:vecl@:({: -"1 }:)\ NB. calculate all distances among vectors
|
||||
minpair=: ({~ > {.@($ #: I.@,)@:= <./@;)dist NB. find one pair of the closest points
|
||||
closestpairbf =: (; vecl@:-/)@minpair NB. the pair and their distance
|
||||
17
Task/Closest-pair-problem/J/closest-pair-problem-2.j
Normal file
17
Task/Closest-pair-problem/J/closest-pair-problem-2.j
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
]pts=:10 2 ?@$ 0
|
||||
0.654682 0.925557
|
||||
0.409382 0.619391
|
||||
0.891663 0.888594
|
||||
0.716629 0.9962
|
||||
0.477721 0.946355
|
||||
0.925092 0.81822
|
||||
0.624291 0.142924
|
||||
0.211332 0.221507
|
||||
0.293786 0.691701
|
||||
0.839186 0.72826
|
||||
|
||||
closestpairbf pts
|
||||
+-----------------+---------+
|
||||
|0.891663 0.888594|0.0779104|
|
||||
|0.925092 0.81822| |
|
||||
+-----------------+---------+
|
||||
17
Task/Closest-pair-problem/J/closest-pair-problem-3.j
Normal file
17
Task/Closest-pair-problem/J/closest-pair-problem-3.j
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
]pts=:10 4 ?@$ 0
|
||||
0.559164 0.482993 0.876 0.429769
|
||||
0.217911 0.729463 0.97227 0.132175
|
||||
0.479206 0.169165 0.495302 0.362738
|
||||
0.316673 0.797519 0.745821 0.0598321
|
||||
0.662585 0.726389 0.658895 0.653457
|
||||
0.965094 0.664519 0.084712 0.20671
|
||||
0.840877 0.591713 0.630206 0.99119
|
||||
0.221416 0.114238 0.0991282 0.174741
|
||||
0.946262 0.505672 0.776017 0.307362
|
||||
0.262482 0.540054 0.707342 0.465234
|
||||
|
||||
closestpairbf pts
|
||||
+------------------------------------+--------+
|
||||
|0.217911 0.729463 0.97227 0.132175|0.708555|
|
||||
|0.316673 0.797519 0.745821 0.0598321| |
|
||||
+------------------------------------+--------+
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
N =10
|
||||
|
||||
dim x( N), y( N)
|
||||
|
||||
firstPt =0
|
||||
secondPt =0
|
||||
|
||||
for i =1 to N
|
||||
read f: x( i) =f
|
||||
read f: y( i) =f
|
||||
next i
|
||||
|
||||
minDistance =1E6
|
||||
|
||||
for i =1 to N -1
|
||||
for j =i +1 to N
|
||||
dxSq =( x( i) -x( j))^2
|
||||
dySq =( y( i) -y( j))^2
|
||||
D =abs( ( dxSq +dySq)^0.5)
|
||||
if D <minDistance then
|
||||
minDistance =D
|
||||
firstPt =i
|
||||
secondPt =j
|
||||
end if
|
||||
next j
|
||||
next i
|
||||
|
||||
print "Distance ="; minDistance; " between ( "; x( firstPt); ", "; y( firstPt); ") and ( "; x( secondPt); ", "; y( secondPt); ")"
|
||||
|
||||
end
|
||||
|
||||
data 0.654682, 0.925557
|
||||
data 0.409382, 0.619391
|
||||
data 0.891663, 0.888594
|
||||
data 0.716629, 0.996200
|
||||
data 0.477721, 0.946355
|
||||
data 0.925092, 0.818220
|
||||
data 0.624291, 0.142924
|
||||
data 0.211332, 0.221507
|
||||
data 0.293786, 0.691701
|
||||
data 0.839186, 0.72826
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
nearestPair[data_] :=
|
||||
Block[{pos, dist = N[Outer[EuclideanDistance, data, data, 1]]},
|
||||
pos = Position[dist, Min[DeleteCases[Flatten[dist], 0.]]];
|
||||
data[[pos[[1]]]]]
|
||||
Loading…
Add table
Add a link
Reference in a new issue