0

I need to create a business logic or php function to compute the following: given some input $rank (which is the alexa ranking) I need to compute some $points in such a way that $points will be high for the top ranking website and will decrease with increasing $rank value.

I imagine something like this:

function($rank)
{
    $points = x*$rank;
    return $points;
}

How do I get $points in such a way that

  • if the rank is 1 then the points returned is maximum (e.g. 10000).
  • if rank is 2 then $points returned will be 9500 or nearby.
  • if rank is 4 then $points returned will be 6000 or nearby.
  • if rank is 200 $points returned will be 2 or whatever the function will return.

Rule: if $rank is less then $points should be more. Maximal value of $points is 10000 which is for $rank=1.

Now as the $rank increases the $points value should decrease accordingly.

MvG
  • 57,380
  • 22
  • 148
  • 276
Vaibs
  • 2,018
  • 22
  • 29
  • Do you require `$points` to be positive, or non-negative? Do you neet it to be integral? – MvG Nov 14 '12 at 18:23

2 Answers2

0

There are many formulas which might satisfy your requiremements.

Nested powers

One possibility:

$points = 10000 * pow(0.993575964272119, pow($rank, 3.16332422407427) - 1)

This gives you the following results:

f(1) = 10000
f(2) = 9500
f(4) = 6000
f(9) = 12.065
f(10) = 0.84341
f(200) = 0

So the three values you fixed (1, 2 and 4) are all satisfied, but the result for 200 indicates that this might not be exactly what you're looking for. The curve looks like this:

function graph

By the way, I found this using python and mpmath, by fixing the form of the formula and determining the numbers with the many digits numerically:

>>> import mpmath
>>> print(mpmath.findroot((lambda a,b: 10000*a**(2**b - 1) - 9500,
...                        lambda a,b: 10000*a**(4**b - 1) - 6000),
...                       (0.995, 2.7)))
[0.993575964272119]
[ 3.16332422407427]

If you decide on a different form of the function, this approach might be adapted.

Exp of a polynomial

A possible different form with the desired properties would be this:

$points = exp(9.14265175282929 + $rank*(0.127179575914116 - $rank*0.0594909567672230))

This does not decrease quite as quickly as the one above:

f(  1) = 10000
f(  2) =  9500
f(  4) =  6000
f( 13) =     2.1002
f( 14) =     0.47852
f(200) =     0

It was obtained by solving this system of equations:

a +  b +   c = log(10000)
a + 2b +  4c = log( 9500)
a + 4b + 16c = log( 6000)

to obtain the coefficients a through c for the polynomial. One can add another degree to match f(200)=2 as well, but in that case, the last coefficient will become positive, which means that points will start to increase with rank for very large ranks.

If you want to match that f(200)=2 as well, you can do so using

$points = exp(max(8.86291000469285 - $rank*0.0408488141206645,
    9.14265175282929 + $rank*(0.127179575914116 - $rank*0.0594909567672230)))

although this will result in a bend in your curve.

To compare these alternatives to the above:

Comparison of functions

MvG
  • 57,380
  • 22
  • 148
  • 276
0
    function getPoints($rank)
{
    $returnValue =  -0.005 * $rank * $rank - 0.035 * $rank + 100.040;
    if ($returnValue < 0) $returnValue = 0;
    return $returnValue;
} 

This was my thinking.

Function is not forking for large values: it should atleast give some small value for large ranks... like if rank is 2000000 then points will be 2. Thnx btw

Vaibs
  • 2,018
  • 22
  • 29