I'm developing a procedurally-generated game world in Python. The structure of the world will be similar to the MUD/MUSH paradigm of rooms and exits arranged as a directed graph (rooms are nodes, exits are edges). (Note that this is *not* necessarily an acyclic graph, though I'm willing to consider acyclic solutions.) 

To the world generation algorithm, rooms of different sorts will be distinguished by each room's "tags" attribute (a set of strings). Once they have been instantiated, rooms can be queried and selected by tags (single-tag, tag intersection, tag union, best-candidate).

I'll be creating specific sorts of rooms using a glorified system of template objects and factory methods--I don't think the details are important here, as the current implementation will probably change to match the chosen strategy. (For instance, it would be possible to add tags and tag-queries to the room template system.)

For an example, I will have rooms of these sorts: 
```
side_street, main_street, plaza, bar, hotel, restaurant, shop, office
```

Finally, the question: what is a good strategy for instantiating and arranging these rooms to create a graph that might correspond to given rules? 

Some rules might include: one plaza per 10,000 population; `main_street` connects to `plaza`; `side_street` connects to `main_street` or `side_street`; `hotel` favors `main_street` or `plaza` connections, and receives further tags accordingly; etc.

Bonus points if a suggested strategy would enable a data-driven implementation.