The latest instance of the course can be found at: O1: 2024
Luet oppimateriaalin englanninkielistä versiota. Mainitsit kuitenkin taustakyselyssä osaavasi suomea. Siksi suosittelemme, että käytät suomenkielistä versiota, joka on testatumpi ja hieman laajempi ja muutenkin mukava.
Suomenkielinen materiaali kyllä esittelee englanninkielisetkin termit.
Kieli vaihtuu A+:n sivujen yläreunan painikkeesta. Tai tästä: Vaihda suomeksi.
Chapter 8.2: City Simulator
About This Page
Questions Answered: How about some more practice? How about an example of modeling real-world phenomena in a program?
Topics: The main themes are (still) collection methods and traits. Algorithm-writing practice.
What Will I Do? Study given code and program.
Rough Estimate of Workload:? Three or four hours? Many students find this chapter’s assignment, which is in Category C, to be the most difficult part of Week 8. You could choose to do the other chapters first and return here afterwards.
Points Available: C70.
Related Modules: CitySim (new).
Citizens in a Simulator
One of the most powerful things about programming is that you can create dynamic models of phenomena and processes in the real world. In this assignment, we’ll form a computational model of a social phenomenon. You’ll take control of an application that simulates people’s movements on a city map; in particular, this simulation will explore how demographics may impact on the social layout of a city.
In this context, a demographic is any subset of the city’s population that the citizens may perceive to be relevant as they assess their own neighborhood. For instance, we can split the citizens in demographics on the basis of their financial status, political views, ethnic background, or age. In this chapter, our simulator will have only two demographics, red and blue. In Chapter 10.1, we’ll extend the simulator to support more demographics.
At the start of each simulation run, we place red and blue citizens at random addresses on the city map. The simulation then advances in steps: at each step, the citizens assess how satisfied they are with their current neighborhood and may decide to move to a vacant address instead of remaining where they are. A citizen is satisfied in case a sufficiently large proportion of their neighbors belongs in the same demographic.
This model is based on the work of Thomas Schelling, a winner of the Nobel Prize in Economics. Naturally, it is a simplification of the real world; models are.
Let me remind you of the particular characteristics of all of these behavior systems. It is that people are impinging on other people and adapting to other people. What people do affects what other people do.
—Thomas Schelling
CitySim
The CitySim module contains two packages. The simulation model itself is in package
o1.city
, whose main contents are these:
Simulator
(partial implementation given). You can ask a simulator object to launch a new simulation run (startNew
) or advance the most recently launched simulation by one step (moveResidents
). The simulator delegates some of its work to another object that represents the map of the city and is of the type:CityMap
(ready as given). A city map is a grid, andCityMap
extendsGrid
much likeGameBoard
did in the Chapter 8.1’s Viinaharava assignment. Each of the elements in this grid is of the type:Demographic
(missing entirely). This simple sealed trait serves as a supertype for anOccupied
class and a singletonVacant
, which represent occupied and vacant addresses, respectively.
The classes in o1.city.gui
define the user interface, which you can safely ignore
apart from the fact that SimulatorApp
is an app object: it creates an instance of
Simulator
and calls its methods when the user presses the buttons in the GUI and
slides the sliders.
Here’s a diagram of these components:
Task description
Add a sealed Demographic
trait and its subordinate concepts Occupied
and Vacant
.
Add the methods findDemographic
, dissatisfiedResidents
, and moveResidents
in class
Simulator
. (The residents
method is also missing but we’ll leave that for later.)
Run the program, experiment with different settings in the UI, and consider how they affect the results.
Instructions and hints
On the Demographic
trait:
This is an exceedingly simple trait: it doesn’t have any methods at all.
Occupied
andVacant
just need anextends
, and that’s about it.Seal the trait with
sealed
(Chapter 7.4). Once you do, anyDemographic
is guaranteed to be either anOccupied
object orVacant
.The outcome resembles the
Option
class and its derivativesSome
andNone
. And indeed we could have usedOption
here instead. However,Demographic
and its subtypes communicate our model better.
On the findDemographic
method:
The
cityMap
instance variable inSimulator
gives you a reference to currently active map, which is aCityMap
object that containsDemographic
objects in a grid pattern.This method is pretty simple to implement once you find the right tools in the documentation of
Simulator
and/orCityMap
.
On the dissatisfiedResidents
method:
A citizen’s satisfaction depends on whether the percentage of similar citizens among the citizen’s neighbors is high enough. The desired percentage, which the end user sets with a slider in the GUI, is available to you as a number between 0 and 100 in the variable
similarityDesired
.Every address does not have the same number of neighbors. Note the details in the Scaladocs.
Again, make use of what the
CityMap
object gives you. Keep in mind that aCityMap
is a sort ofGrid
and has all the methods it gets from its supertype. For instance, there is a way to check which demographic currently occupies a particularGridPos
.Try to split the method’s overall task in subtasks.
For instance, one subtask could be to examine whether a given address’s neighborhood is unsatisfactory.
Consider writing auxiliary functions for the subtasks. You can define them either as private methods or as local functions within
dissatisfiedResidents
.
If your method computes incorrect results, here are some things you could check:
Did you notice that
similarityDesired
is an integer between 0 and 100, not aDouble
between 0 and 1?In case you used division, did you remember that any and all decimals are discarded when you divide an
Int
by anInt
?Did you make sure to ignore vacant neigbors while checking if a resident is satisfied?
Did you make sure to leave out vacant addresses from the results? (A vacant address cannot be dissatisfied.)
On the moveResidents
method:
Make use of the two other methods you implemented.
You may find
Random.shuffle
useful again (see Chapter 8.1), as well as other methods in classRandom
(see Chapter 3.6).
Additional hint for moveResidents
Here’s an outline of a solution:
Form a buffer that contains the addresses of all vacant homes.
Form a collection that contains the locations of all the unsatisfied residents, in random order.
Repeat for each unsatisfied resident: Pick a random address from the buffer of vacant homes. Move the resident to that address on the
CityMap
. In the buffer, replace that destination address with the vacated address.
Use the app
Run the simulator on the default settings. Press Single Step repeatedly to advance the simulation. Try Run, too. Notice that the satisfaction threshold is set at 70%, meaning that the citizens are very easily dissatisfied with their neighborhood.
Try higher and lower values for the threshold.
It seems obvious that if the citizens demand a great number of neighbors similar to themselves, they end up living among their own demographic. Something that’s not equally obvious is how demanding the citizens need to be for the phenomenon to occur. Explore and find out.
Could we use a similar model to explain the “echo chambers” on social media?
What real-world factors are ignored by this model?
What would happen if one demographic cares about what their neighbors are like but the other is always or almost always satisfied? Or what if the citizens didn’t just set a minimum but also a maximum for the degree of similarity between themselves and their neighbors?
A+ presents the exercise submission form here.
In case this assignment piqued your interest
The book Networks, Crowds, and Markets: Reasoning About a Highly Connected World, which is available as a free online edition, will tell you more about computational modeling of social, economic, and medical phenomena, among other things. The Schelling model we just used features in Chapter Four of the book.
Feedback
Please note that this section must be completed individually. Even if you worked on this chapter with a pair, each of you should submit the form separately.
Credits
Thousands of students have given feedback and so contributed to this ebook’s design. Thank you!
The ebook’s chapters, programming assignments, and weekly bulletins have been written in Finnish and translated into English by Juha Sorva.
The appendices (glossary, Scala reference, FAQ, etc.) are by Juha Sorva unless otherwise specified on the page.
The automatic assessment of the assignments has been developed by: (in alphabetical order) Riku Autio, Nikolas Drosdek, Joonatan Honkamaa, Antti Immonen, Jaakko Kantojärvi, Niklas Kröger, Kalle Laitinen, Teemu Lehtinen, Jaakko Nakaza, Strasdosky Otewa, Timi Seppälä, Teemu Sirkiä, Anna Valldeoriola Cardó, and Aleksi Vartiainen.
The illustrations at the top of each chapter, and the similar drawings elsewhere in the ebook, are the work of Christina Lassheikki.
The animations that detail the execution Scala programs have been designed by Juha Sorva and Teemu Sirkiä. Teemu Sirkiä and Riku Autio did the technical implementation, relying on Teemu’s Jsvee and Kelmu toolkits.
The other diagrams and interactive presentations in the ebook are by Juha Sorva.
The O1Library software has been developed by Aleksi Lukkarinen and Juha Sorva. Several of its key components are built upon Aleksi’s SMCL library.
The pedagogy of using O1Library for simple graphical programming (such as Pic
) is
inspired by the textbooks How to Design Programs by Flatt, Felleisen, Findler, and
Krishnamurthi and Picturing Programs by Stephen Bloch.
The course platform A+ was originally created at Aalto’s LeTech research group as a student project. The open-source project is now shepherded by the Computer Science department’s edu-tech team and hosted by the department’s IT services. Markku Riekkinen is the current lead developer; dozens of Aalto students and others have also contributed.
The A+ Courses plugin, which supports A+ and O1 in IntelliJ IDEA, is another open-source project. It has been designed and implemented by various students in collaboration with O1’s teachers.
For O1’s current teaching staff, please see Chapter 1.1.
Additional credits for this page
The assignment on Schelling’s model of emergent social segregation has been adapted from a programming exercise by Frank McCown.