nehtik / epgp

Automatically exported from code.google.com/p/epgp
0 stars 0 forks source link

Rounding of EP and GP substractor makes slightly different PR after decay #444

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
What steps will reproduce the problem?
1. set officer's note of Character 1 to "2156,357"
2. set officer's note of Character 2 to "2480,411"
3. set DECAY_P to "10"
4. run Decay

What is the expected output? What do you see instead?

I would expect PR not to be changed, which means there is the same order of 
characters as before the decay.

I see PR of Character 1 is 6.044 (was 6.039 which is more than Character 2)
I see PR of Character 2 is 6.049 (was 6.034)
I see Character 2 is now higher on priority

What version of the product are you using? What locale is your client (en,
ru, kr, ch, es, tw)? What other addons do you have installed and what
versions?

5.4.11 en (haven't tested 5.4.12 yet, but I bet it is same there)

Paste the text surrounded by -EPGP- in Guild Information here:

-EPGP-
@BASE_GP:200
@DECAY_P:10
@MIN_EP:1500
@EXTRAS_P:100
-EPGP-

If this is about http://epgpweb.appspot.com integration, what is the realm
and region of your guild?

nah

Please provide any additional information below.

As far as I can see from the source, I can make this formula
NEW_EP = Math.floor( 0.01 * (100 - DECAY_P) * EP )
NEW_GP = Math.floor( 0.01 * (100 - DECAY_P) * GP )

Wouldn't it be more precise if it was simply rounded and not floored?

Also I got some other idea of counting decay
NEW_EP = Mylib.round ( 0.01 * (100 - DECAY_P) * EP )
NEW_GP = Mylib.round ( NEW_EP / PR )

where Mylib.round() is something like this:
function round(num, p)
  return tonumber(string.format("%." .. (p or 0) .. "f", num))
end

It gives me better PR numbers - smaller differences between decays

Original issue reported on code.google.com by tomas.klapka on 25 Jun 2009 at 4:43

GoogleCodeExporter commented 8 years ago
If you round, a decay of 10% will never reduce the EP of anyone below 5. 
Similar problems with any value of 
decay. Both round and floor (and ceiling) have problems after decay when the PR 
of two members is similar. For 
some values one of the three is better than the other two. There is nothing you 
can do about that.

Original comment by evlogimenos on 25 Jun 2009 at 5:03

GoogleCodeExporter commented 8 years ago
You can add something like if new EP value is the same as the EP value before 
the
decay then reduce it by 1 (if EP is not 0)

I just made some math and decaying GP first and using old PR to find new EP with
rounding has the less PR differences on average and also has the lowest value 
of the
biggest PR difference.

Algorithm for decaying I've used:

# set new EP,GP values to old values for the case there is no change
NEW_EP = EP
NEW_GP = GP

PR = EP / GP

# we cannot decay GP if it equals to 0 but if it is more than 0 just decay it
if (GP > 0) {
  NEW_GP = round ( 0.01 * (100 - DECAY_P) * GP )    # decay GP by DECAY_P
  if (NEW_GP == GP) { NEW_GP = NEW_GP - 1 }         # if GP is too low to be affected
reduce it by 1
  NEW_EP = round ( NEW_GP * PR )                    # count new EP
}
# if GP cannot be decayed (GP equals to 0) we have to decay EP
else
{
# but only if EP can be decayed
  if (EP > 0) {
    NEW_EP = round ( 0.01 * (100 - DECAY_P) * EP    # decay EP by DECAY_P
    if (NEW_EP == EP) { NEW_EP = NEW_EP - 1 }       # if EP is too low to be affected
reduce it by 1
  }
}

I've also tried to just round the EP and GP. It is better then ceiling/flooring 
but
it's still jumping too much. Decaying EP first and then counting GP gives 
slightly
better results than just rounding but still it is too much if compared to 
"decay GP -
count EP" method

Here are some of my results. I tried to decay every combination of EP and GP 
from
given range. I used 4 methods of decay: original (current one), rounding method 
(just
use round instead of ceil/floor), "decay EP - count GP" method and finally 
"decay GP
- count EP" method described above. I counted average PR differences between 
new PR
and old PR and also I also recorded the the highest PR difference.

PR differences results for ranges:
EP 0 - 1000
GP 100 - 1000

Original ceiling method:
Average: 0.00222102752736
Highest: 0.0990099009901

Rounding method:
Average: 0.00163097027268
Highest: 0.0541353383459

Decay EP then count GP:
Average: 0.00138956294505
Highest: 0.0501253132832

Decay GP then count EP:
Average: 0.000711001015292
Highest: 0.00555555555556

PR differences results for ranges:
EP 1500 - 3000
GP 100 - 1200

Original ceiling method:
Average: 0.0087024413993
Highest: 0.29702970297

Rounding method:
Average: 0.00525866860783
Highest: 0.154385964912

Decay EP then count GP:
Average: 0.00520083678257
Highest: 0.150861195542

Decay GP then count EP:
Average: 0.00062810497526
Highest: 0.00555555555556

I've tested more ranges but IMHO these are enough to give a picture.

Original comment by tomas.klapka on 26 Jun 2009 at 4:04

GoogleCodeExporter commented 8 years ago
Obviously when you scale the smaller integer first and then interpolate to find 
the other is going to give you 
more accuracy. But in the end I do not understand the goal of this exercise. 
What are you trying to achieve?

Original comment by evlogimenos on 26 Jun 2009 at 4:21

GoogleCodeExporter commented 8 years ago
What about more accuracy? ;)

Actually it is not the smaller integer first but it seems to me that it is 
divider 
first which gives me more accuracy.

Original comment by tomas.klapka on 26 Jun 2009 at 5:39

GoogleCodeExporter commented 8 years ago
What you are doing is this:

function Decay(ep, gp)
  local min = math.min(ep, gp)
  local decayed_min = math.round(m * 0.01 (100 - DECAY_P))
  local factor = decayed_min / min
  return math.round(ep * factor), math.round(gp * factor) 

That is you find what actual decay you are applying instead of DECAY_P and then 
you decay both ep and gp 
with the same decay. While this might sound good to you because the numbers 
seem closer, the problem is 
that you are decaying each individual by a different decay*.

* The current algorithm does the same but the decay difference between yours is 
smaller. For your 
comparisons, after you come up with the final numbers, for each pair compute 
the actual decay: (ep / new_ep 
- 1). Then compare the actual decay between players for the different 
algorithms.

Original comment by evlogimenos on 26 Jun 2009 at 10:31

GoogleCodeExporter commented 8 years ago
If someones PR after decay means they lose one position on the PR list because 
of a
fraction of a number, and that is causing you a problem because they are upset 
they
have dropped one position on the loot table, then give them a slap and tell 
them to
grow up. IMHO. Also, if you want more accuracy, then do as Alkis has said 
elsewhere
many times before, use a  bigger EP award (1000EP every 15 minutes) and the PR
numbers will be more accurate. EPGP works fine.

Original comment by dingochavezz@gmail.com on 28 Jun 2009 at 11:50

GoogleCodeExporter commented 8 years ago
stubborn much?

Original comment by scappssk...@gmail.com on 25 Feb 2010 at 3:47