Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
|
|
@ -0,0 +1,6 @@
|
|||
let closest_pairs (xys: Point []) =
|
||||
let n = xys.Length
|
||||
seq { for i in 0..n-2 do
|
||||
for j in i+1..n-1 do
|
||||
yield xys.[i], xys.[j] }
|
||||
|> Seq.minBy (fun (p0, p1) -> (p1 - p0).LengthSquared)
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
closest_pairs
|
||||
[|Point(0.0, 0.0); Point(1.0, 0.0); Point (2.0, 2.0)|]
|
||||
|
|
@ -0,0 +1 @@
|
|||
(0,0, 1,0)
|
||||
89
Task/Closest-pair-problem/F-Sharp/closest-pair-problem-4.fs
Normal file
89
Task/Closest-pair-problem/F-Sharp/closest-pair-problem-4.fs
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
open System;
|
||||
open System.Drawing;
|
||||
open System.Diagnostics;
|
||||
|
||||
let Length (seg : (PointF * PointF) option) =
|
||||
match seg with
|
||||
| None -> System.Single.MaxValue
|
||||
| Some(line) ->
|
||||
let f = fst line
|
||||
let t = snd line
|
||||
|
||||
let dx = f.X - t.X
|
||||
let dy = f.Y - t.Y
|
||||
sqrt (dx*dx + dy*dy)
|
||||
|
||||
|
||||
let Shortest a b =
|
||||
if Length(a) < Length(b) then
|
||||
a
|
||||
else
|
||||
b
|
||||
|
||||
|
||||
let rec ClosestBoundY from maxY (ptsByY : PointF list) =
|
||||
match ptsByY with
|
||||
| [] -> None
|
||||
| hd :: tl ->
|
||||
if hd.Y > maxY then
|
||||
None
|
||||
else
|
||||
let toHd = Some(from, hd)
|
||||
let bestToRest = ClosestBoundY from maxY tl
|
||||
Shortest toHd bestToRest
|
||||
|
||||
|
||||
let rec ClosestWithinRange ptsByY maxDy =
|
||||
match ptsByY with
|
||||
| [] -> None
|
||||
| hd :: tl ->
|
||||
let fromHd = ClosestBoundY hd (hd.Y + maxDy) tl
|
||||
let fromRest = ClosestWithinRange tl maxDy
|
||||
Shortest fromHd fromRest
|
||||
|
||||
|
||||
// Cuts pts half way through it's length
|
||||
// Order is not maintained in result lists however
|
||||
let Halve pts =
|
||||
let rec ShiftToFirst first second n =
|
||||
match (n, second) with
|
||||
| 0, _ -> (first, second) // finished the split, so return current state
|
||||
| _, [] -> (first, []) // not enough items, so first takes the whole original list
|
||||
| n, hd::tl -> ShiftToFirst (hd :: first) tl (n-1) // shift 1st item from second to first, then recurse with n-1
|
||||
|
||||
let n = (List.length pts) / 2
|
||||
ShiftToFirst [] pts n
|
||||
|
||||
|
||||
let rec ClosestPair (pts : PointF list) =
|
||||
if List.length pts < 2 then
|
||||
None
|
||||
else
|
||||
let ptsByX = pts |> List.sortBy(fun(p) -> p.X)
|
||||
|
||||
let (left, right) = Halve ptsByX
|
||||
let leftResult = ClosestPair left
|
||||
let rightResult = ClosestPair right
|
||||
|
||||
let bestInHalf = Shortest leftResult rightResult
|
||||
let bestLength = Length bestInHalf
|
||||
|
||||
let divideX = List.head(right).X
|
||||
let inBand = pts |> List.filter(fun(p) -> Math.Abs(p.X - divideX) < bestLength)
|
||||
|
||||
let byY = inBand |> List.sortBy(fun(p) -> p.Y)
|
||||
let bestCross = ClosestWithinRange byY bestLength
|
||||
Shortest bestInHalf bestCross
|
||||
|
||||
|
||||
let GeneratePoints n =
|
||||
let rand = new Random()
|
||||
[1..n] |> List.map(fun(i) -> new PointF(float32(rand.NextDouble()), float32(rand.NextDouble())))
|
||||
|
||||
let timer = Stopwatch.StartNew()
|
||||
let pts = GeneratePoints (50 * 1000)
|
||||
let closest = ClosestPair pts
|
||||
let takenMs = timer.ElapsedMilliseconds
|
||||
|
||||
printfn "Closest Pair '%A'. Distance %f" closest (Length closest)
|
||||
printfn "Took %d [ms]" takenMs
|
||||
Loading…
Add table
Add a link
Reference in a new issue