# 6.7. Generating BA Graphs¶

In the previous sections we used a NetworkX function to generate BA graphs; now let’s see how it works. Here is a version of `barabasi_albert_graph`, with some changes that were made to make it easier to read:

```def barabasi_albert_graph(n, k):

G = nx.empty_graph(k)
targets = list(range(k))
repeated_nodes = []

for source in range(k, n):

repeated_nodes.extend(targets)
repeated_nodes.extend([source] * k)

targets = _random_subset(repeated_nodes, k)

return G
```

The parameters are `n`, the number of nodes we want, and `k`, the number of edges each new node gets (which will turn out to be the average number of edges per node).

We start with a graph that has `k` nodes and no edges. Then we initialize two variables:

• `targets`: The list of `k` nodes that will be connected to the next node. Initially `targets` contains the original `k` nodes; later it will contain a random subset of nodes.

• `repeated_nodes`: A list of existing nodes where each node appears once for every edge it is connected to. When we select from `repeated_nodes`, the probability of selecting any node is proportional to the number of edges it has.

Each time through the loop, we add edges from the source to each node in `targets`. Then we update `repeated_nodes` by adding each target once and the new node `k` times.

Finally, we choose a subset of the nodes to be targets for the next iteration. Here’s the definition of `_random_subset`:

```def _random_subset(repeated_nodes, k):
targets = set()
while len(targets) < k:
x = random.choice(repeated_nodes)
Each time through the loop, `_random_subset` chooses from `repeated_nodes` and adds the chosen node to `targets`. Because `targets` is a set, it automatically discards duplicates, so the loop only exits when we have selected `k` different nodes.