0

We have a Dictionary with the following structure:

_availableCharacterClasses = [[NSMutableDictionary alloc] init];
[_availableCharacterClasses setObject:[NSNumber numberWithFloat:[DefaultNova characterSpawnProbability]] forKey:NSStringFromClass([DefaultNova class])];

where probability has a value between 0 (low) and 100 (height)

now i want to pick a random key (weighted) from the _availableCharacterClasses-Dictionary.
How can i archive this using objective c?

Sascha Held
  • 306
  • 2
  • 16
  • possible duplicate of [Generating Random Numbers in Objective-C](http://stackoverflow.com/questions/160890/generating-random-numbers-in-objective-c) – rishi Jul 02 '14 at 11:04
  • http://stackoverflow.com/questions/1761626/weighted-random-numbers – DareDevil Jul 02 '14 at 11:22

3 Answers3

1

Ah I think now I've got your question correct. I assume the probabilities sum up to 100?

int random = arc4random%100;

NSArray *probabilities = [_availableCharacterClasses allObjects];
NSArray *keys = [_availableCharacterClasses allKeys];
CGFloat currentValue = 0;
int index=0;
for(NSNumber *p in probabilities){
    currentValue+=[p floatValue];
    if(random<currentValue){
        //found now get the key
        return keys[index];
    }
    index++;
}
robert
  • 2,822
  • 1
  • 16
  • 19
0

@Robert i have modified your solution slightly and came up with the following result

- (NSUInteger)randomIndexByProbability:(NSArray *)probabilities
{
  CGFloat randomNumber= arc4random_uniform(100) + (float)arc4random_uniform(101)/100;
  NSUInteger weightedIndex = 0;
  CGFloat totalProbability = 0.0;

  for(NSUInteger i=0; i<probabilities.count; i++)
  {
    totalProbability += [probabilities[i] floatValue];

    if(totalProbability >= randomNumber)
    {
      break;
    }
    weightedIndex++;
  }
  return weightedIndex;
}
Sascha Held
  • 306
  • 2
  • 16
  • yeah nice, looks like we did it in the same time, after I fully understood your question ;) – robert Jul 02 '14 at 11:31
0

If you want to pick random key for given value you can do something like:

float value = 3;    
NSArray * keys = [_availableCharacterClasses.allKeys filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"%@[self].floatValue == %f", _availableCharacterClasses, value]];
NSString *anykey = keys[arc4random_uniform(keys.count)];
Artemiy Sobolev
  • 324
  • 3
  • 7