Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I don't agree with any of these solutions. In my opinion the circle should be positioned in an infinite plane, then random vectors should be drawn on the plane and ignored unless they intersect the circle. Then after making some large amount of intersecting vectors you calculate. I'm guessing that this essentially reduces to the random endpoints method.

The other two methods don't make sense at all to me. Random chords is just obviously not a random sampling of possible vectors-- it's essentially the same as sampling a gaussian(x) distribution using an equal sampling in x and ignoring the fact that a gaussian is a PDF and you can't sample that way, you need to invert it into a CDF and take an equal sampling in _y_. Very basic I think...

And random midpoint doesn't strike me as random either as it forces the orientations of the vectors to be non-random and systematically smaller than random because of the pi*r^2 area-dependence of concentric circles...

But, what do I know.



> In my opinion the circle should be positioned in an infinite plane, then random vectors should be drawn on the plane and ignored unless they intersect the circle.

After looking at the Wikipedia page, it seems that your method would be equivalent to the "random radius" aka "1/2" aka "ninja" method.

https://en.wikipedia.org/wiki/Bertrand_paradox_(probability)

This is a good demonstration of the paradox here. You phrase your method as "random vectors in an infinite plane", but even when it is equivalent to the "ninja" method, the ninja method doesn't seem right to you.


I don't think so, like say you had a point outside the circle, and from that point you equally selected angles to slice the space in. You would get systematically longer slices than if all your slices are cut parallel to each other (and you ended up with the same number slicing the pizza).

edit: I worked it out and you're right, I get the same answer as the ninja one.


>You would get systematically longer slices than if all your slices are cut parallel to each other (and you ended up with the same number slicing the pizza).

You're only cutting once per pizza, so there's no parallel slices, so no such effect.

And allowing a dense set of possible parallel vectors from every angle is equivalent to rotating the pizza. Which obviously doesn't affect the sizes.


I tried to script that together after the same idea occurred to me. What's interesting is the selection plane affects the outcome quite heavily. As the plane of random line selection increases in size, the probability of a random chord having length>sqrt3 seems to approach about 0.13

My math might be wrong; doesn't seem to be a floating point precision issue.

        from math import sqrt
        from random import random

        def randomPoints(width):
            return [
                    [random()*width-width/2, random()*width-width/2],
                    [random()*width-width/2, random()*width-width/2]
                ]

        def chordCalc(points):
            def quadraticEquation(a,b,c):
                descriminant=(b**2 - 4*a*c)
                if descriminant <= 0:
                    return None
                x1 = (-b+sqrt(descriminant))/(2*a)
                x2 = (-b-sqrt(descriminant))/(2*a)
                y1 = sqrt(1-x1**2)
                y2 = sqrt(1-x2**2)
                return [[x1, y1],[x2,y2]]

            m = (points[0][1] - points[1][1]) / (points[0][0] - points[1][0])
            b = points[0][1] - m*points[0][0]

            qa = 1+m**2
            qb = 2*b*m
            qc = b**2-1

            return quadraticEquation(qa, qb, qc)

        def distance(points):
            return sqrt((points[0][1] - points[1][1])**2
                      + (points[0][0] - points[1][0])**2)

        chords=0
        largeChords=0
        sqrt3=sqrt(3)
        while True:
            if random() > 0.9999:
                print float(largeChords)/chords
            points = randomPoints(500) #adjust me down to 0.5 and see probability go to ~0.33
            intersections=chordCalc(points)
            if intersections is None:
                continue
            chords += 1
            if distance(intersections) > sqrt3:
                largeChords += 1


I was wrong. My initial approach appears to be the ninja approach like sampo said above. I got 50% -_-

    import numpy as np
    import random as rnd
    import math as m

    chords = []
    samp = 10000
    for c in range(samp):
        #random point on infinite plane is described by a  single coordinate
        dist = rnd.uniform(1., 1000.)
        #DO NOT KNOW HOW TO DO INTERNAL SLICES

        #ignore all possible lines that do not intesect circle
        xsec_half = m.atan(1./dist)
        angle = rnd.uniform(-xsec_half, xsec_half)

        #make 2 points on the randomly chosen line
        x1, y1 = -dist, 0
        x2, y2 = dist, 2*dist*m.tan(angle)

        #copy and paste some shit from wolfram alpha
        dx = x2-x1
        dy = y2-y1
        dr = (dx**2 + dy**2)**0.5
        D = x1*y2 - x2*y1
        
        sqr = (dr**2 - D**2)**0.5

        xa = (D*dy + np.sign(dy)*dx*sqr) / (dr**2)
        xb = (D*dy - np.sign(dy)*dx*sqr) / (dr**2)

        ya = (-D*dx + np.abs(dy)*sqr) / (dr**2)
        yb = (-D*dx - np.abs(dy)*sqr) / (dr**2)

        chords.append(((xa-xb)**2 + (ya-yb)**2)**0.5)

    print len([a for a in chords if a > 3**0.5])/float(samp)

Basically make the unit circle at 0,0. Pick any radius up to infinity (infinite plane). By symmetry, we don't need 2 coordinates, just a distance from the circle.

Choose any angle from that point which will draw a vector that intersects the circle (to not waste CPU). Calculate the length of the intersecting chord.

I was really surprised by the distribution of chord lengths, it peaks at chord lengths of 2.0, which is the maximum chord length, and falls exponentially with smaller chord lengths. I don't know what I expected, but not that.


You might have a bug in the code.

    >>> horizontal = chordCalc([[-1,0],[1,0]])
    >>> distance(horizontal)
    2.0
All good so far, but

    >>> diagonal = chordCalc([[-1,-1],[1,1]])
    >>> distance(diagonal)
    1.4142135623730951
shouldn't this give 2.0 as well?


i think that any probability measure you can define on your proposed solution assigns a probability of zero to actually hitting the circle, which might complicate things somewhat :)


It would assign a probability approaching zero as the plane approached infinity, yeah, I agree.

But I think I have a way around that.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: