6

I have a program in Java that generates a float value aggressiveness that can be from 0 to infinite. What I need to do is that the higher this float is, the higher there are chances the program fires a function attackPawn().

I already found out that I need the function Math.random(), which gives a random value between 0 and 1. If Math.random() is lower than aggressiveness transformed into a float between 0 and 1, I call the function attackPawn().

But now I am stuck, I can't figure out how I can transform aggressiveness from 0 to infinite to a float which is from 0 to 1, 1 meaning "infinite" aggressiveness and 0 meaning absence of anger.

Any ideas or math equation?

TylerH
  • 20,799
  • 66
  • 75
  • 101
turbodoom
  • 235
  • 1
  • 3
  • 14
  • 1
    As infinity is really finite (at least on hardware used nowadays) you could simply divide aggressiveness by Float.MAXVALUE. – Dirk Lachowski Apr 16 '14 at 09:53
  • 2
    @DirkLachowski This is a very limited approach since bijections for this problem exist, e.g. tan(x*pi/2) – Absurd-Mind Apr 16 '14 at 09:55
  • It would be really helpful if you post some code, whatever you have tried.. – TechSpellBound Apr 16 '14 at 09:55
  • @Absurd-Mind Sure, but im not sure if mathmatical correctness is needed for an aggressiveness metric in a game - and for a game it should be more fast than exact... – Dirk Lachowski Apr 16 '14 at 09:58
  • @DirkLachowski You are correct, correctness is not needed. But if the question is to fulfill a definition then correctness is needed. (Yet it would be better to change the definition) – Absurd-Mind Apr 16 '14 at 10:00
  • @Absurd-Mind I agree, but there is no evidence in the question that it has to be a linear transformation. But as you suggested changing the definition of aggressiveness should be the way to go. – Dirk Lachowski Apr 16 '14 at 10:03

5 Answers5

22

You want a monotonic function that maps [0...infinity] to [0..1]. There are many options:

    y=Math.atan(x)/(Math.PI/2);
    y=x/(1+x);
    y=1-Math.exp(-x);

There are more. And each of those functions can be scaled arbitrarily, given a positive constant k>0:

    y=Math.atan(k*x)/(Math.PI/2);
    y=x/(k+x);
    y=1-Math.exp(-k*x);

There is an infinite number of options. Just pick one that suits your needs.

andand
  • 17,134
  • 11
  • 53
  • 79
pentadecagon
  • 4,717
  • 2
  • 18
  • 26
2

It is possible to map [0,infinity) to [0,1), but this won't be linear. An example function would be:

y = tan(x * pi / 2);

The problem with this function is that you can't make a correct computer program from that since it is not possible (or easy) to first compute a real big number like 10^5000 and map it down to [0,1).

But a better solution would be to change your definition to something like that:

0 = no aggression
1 = maximum aggression

With this you don't have to map the numbers

Absurd-Mind
  • 7,884
  • 5
  • 35
  • 47
1

Try something like this:

// aggressiveness is a float with a value between 0 and Float.MAX_VALUE or a value of Float.POSITIVE_INFINITY
if (aggressiveness == Float.POSITIVE_INFINITY) {
    aggressiveness = 1f;
} else {
    aggressiveness = aggressiveness / Float.MAX_VALUE;
}
// aggressiveness is now between 0 and 1 (inclusive)
daiscog
  • 11,441
  • 6
  • 50
  • 62
0

Though Double class supports infinite value double d=Double.POSITIVE_INFINITY but i dont think you can use it for your arithmatic purpose. Better you define a maximum value and treat it as infinity.

double Min=0;
double Max= Double.MAX_VALUE;

double aggresiveness= Min + (Math.random() * ((Max - Min) + 1));

ps: you can also take aggresiveness as long or int if you don't want it be a double

maxx777
  • 1,320
  • 1
  • 20
  • 37
-1

Try to transform aggressiveness with a function like:

public float function(float aggressiveness) {
    if(aggressiveness > 0F) {
        return 1 - (1 / aggressiveness);
    }
    return 0F;
}

This will map your value to the range of [0, 1);

QBrute
  • 4,405
  • 6
  • 34
  • 40