2

I am using DEAP toolbox in Python for Genetic Algorithm.

toolbox.register("attr_bool", random.randint, 0, 1) is a function randomly chooses 0 and 1 for populations in GA. I want to force GA to choose 0 and 1 randomly but with for example 80% one and the rest zero.

I think srng.binomial(X.shape, p=retain_prob) is a choice, but I want to use random.randint function. Wondering how we can do that?

Amn Kh
  • 531
  • 3
  • 7
  • 19
  • 1
    You could do something like `0 if random.randint(0, 4) == 0 else 1` or `0 if random.random() < 0.2 else 1`. – jamesdlin Jun 15 '16 at 01:53
  • The problem is that when I use `0 if random.randint(0, 4) == 0 else 1` instead of `random.randint` in `toolbox.register("attr_bool", random.randint, 0, 1)`, it gives me the following error `TypeError: the first argument must be callable` – Amn Kh Jun 15 '16 at 02:02

3 Answers3

2

A natural way is to use the expression

1 if random.random() <= 0.8 else 0

You can abstract this into a function:

def bernoulli(p): return 1 if random.random() <= p else 0

Then bernoulli(0.8) will give 1 or 0 with the requisite probabilities. I am not familiar with the GA library you are using, but bernoulli() is callable hence it should work.

John Coleman
  • 51,337
  • 7
  • 54
  • 119
2

The arguments to toolbox.register must be a function and the arguments that you want to pass to that function when you run it

Since 0 if random.randint(0, 4) == 0 else 1 is not a function (its a random number) you got an error. The fix is to package this expression inside a function that you can pass to toolbox.register:

# returns 1 with probability p and 0 with probability 1-p
def bernoulli(p):
    if random.random() < p:
        return 1
    else:
        return 0

toolbox.register("attr_bool", bernoulli, 0.8)
hugomg
  • 68,213
  • 24
  • 160
  • 246
1

random.randint does not provide such functionality, but if you wanted to stay in the random package, you could use random.choice([0] * 1 + [1] * 4).

numpy.random also provides this functionality with np.random.choice([0, 1], p=[0.2, 0.8]).

Steve Kern
  • 586
  • 3
  • 6
  • If I stick on `np.random.choice`, how we can get a list of 100 elements? For example, I need a list with 100 size which has a probability of [0.2 0.8]. I do not want to use loop. – Amn Kh Jun 15 '16 at 01:56
  • `np.random.choice([0, 1], size=100, p=[0.2, 0.8])` – Steve Kern Jun 15 '16 at 02:00
  • If you need it to be a list and not a numpy array, you should look at the `tolist` method. And of course if you want to generate random sample reproducibly, you should generate a `RandomState` object with a seed that you have set and use that to produce the samples. – Steve Kern Jun 15 '16 at 02:11
  • Again the same problem, when I use `np.random.choice([0, 1], size=100, p=[0.2, 0.8])` instead of `random.randint` in `toolbox.register("attr_bool", random.randint, 0, 1)`, the following error coming up: ` TypeError: the first argument must be callable` – Amn Kh Jun 15 '16 at 02:13
  • As @hugomg answered, the invocation of your random sampling function with `Toolbox.register` should be the function and then the args that would be passed to that function, so if you wanted to use `np.random.choice` to produce an array of sample, something akin to `toolbox.register('attr_bool', np.random.choice, [0, 1], size=100, p=[0.2, 0.8])` would probably be appropriate. – Steve Kern Jun 15 '16 at 03:55