Skip to content

Commit b305e8c

Browse files
Implement partial random move
1 parent 844f131 commit b305e8c

File tree

2 files changed

+45
-33
lines changed

2 files changed

+45
-33
lines changed

src/main/scala/eighties/h24/dynamic.scala

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ object dynamic {
185185
db.close()
186186
}
187187

188-
def load(file: java.io.File) = {
188+
def load(file: java.io.File) =
189189
import org.mapdb._
190190

191191
val thread = Thread.currentThread()
@@ -203,7 +203,6 @@ object dynamic {
203203

204204
db.hashMap("moves").createOrOpen.asInstanceOf[HTreeMap[(Location, TimeSlice), Cell]]
205205
} finally thread.setContextClassLoader(cl)
206-
}
207206

208207
// val os = new FileOutputStream((file / timeSlicesFileName).toJava)
209208
// try os.getChannel.write(Pickle.intoBytes(moves.map(_._1)))
@@ -302,33 +301,40 @@ object dynamic {
302301

303302
Focus[World[I]](_.individuals).set(newIndividuals)(world)
304303

305-
def assignRandomDayLocation[I: ClassTag](world: World[I], locatedCell: LocatedCell, stableDestination: Lens[I, Map[TimeSlice, Location]], location: I => Location, home: I => Location, socialCategory: I => AggregatedSocialCategory, rng: Random) =
304+
def assignFixedLocationFromMoveMatrix[I: ClassTag](
305+
world: World[I],
306+
moveMatrixCell: LocatedCell,
307+
stableDestination: Lens[I, Map[TimeSlice, Location]],
308+
timeSlice: TimeSlice,
309+
location: I => Location,
310+
home: I => Location,
311+
socialCategory: I => AggregatedSocialCategory, rng: Random) =
306312
val newIndividuals = Array.ofDim[I](world.individuals.length)
307313
var index = 0
308314

309315
for
310316
(line, i) <- Focus[Index[I]](_.cells).get(Index.indexIndividuals(world, location)).zipWithIndex
311317
(individuals, j) <- line.zipWithIndex
312318
do
313-
val workTimeMovesFromCell = locatedCell(dayTimeSlice, i, j)
319+
val workTimeMovesFromCell = moveMatrixCell(timeSlice, i, j)
314320

315321
assert(workTimeMovesFromCell != null)
316322

317323
for
318324
individual <- individuals
319325
do
320326
def newIndividual =
321-
dynamic.sampleDestinationInMoveMatrix(workTimeMovesFromCell, individual, socialCategory, rng) match {
322-
case Some(d) => stableDestination.modify(_ + (dayTimeSlice -> d))(individual)
323-
case None => stableDestination.modify(_ + (dayTimeSlice -> home(individual)))(individual)
324-
}
327+
dynamic.sampleDestinationInMoveMatrix(workTimeMovesFromCell, individual, socialCategory, rng) match
328+
case Some(d) => stableDestination.modify(_ + (timeSlice -> d))(individual)
329+
case None => stableDestination.modify(_ + (timeSlice -> home(individual)))(individual)
330+
325331
newIndividuals(index) = newIndividual
326332
index += 1
327333

328334
Focus[World[I]](_.individuals).set(newIndividuals)(world)
329335

330-
def assignFixNightLocation[I: ClassTag](world: World[I], stableDestination: Lens[I, Map[TimeSlice, Location]], home: I => Location) =
331-
World.allIndividuals[I].modify { individual => stableDestination.modify(_ + (nightTimeSlice -> home(individual)))(individual) } (world)
336+
def assignFixedLocation[I: ClassTag](world: World[I], stableDestination: Lens[I, Map[TimeSlice, Location]], timeSlice: TimeSlice, home: I => Location) =
337+
World.allIndividuals[I].modify { individual => stableDestination.modify(_ + (timeSlice -> home(individual)))(individual) } (world)
332338

333339
def randomiseLocation[I: ClassTag](world: World[I], location: I => Location, home: Lens[I, Location], random: Random) =
334340
val reach = reachable(Index[I](world.individuals.iterator, location, world.sideI, world.sideJ))

src/main/scala/eighties/h24/simulation.scala

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ package eighties.h24
1818
*/
1919

2020
import eighties.h24.dynamic.MoveMatrix.{LocatedCell, TimeSlice}
21-
import eighties.h24.dynamic.{MoveMatrix, assignFixNightLocation, assignRandomDayLocation}
22-
import eighties.h24.generation.{IndividualFeature, WorldFeature, timeSlices}
21+
import eighties.h24.dynamic.{MoveMatrix, assignFixedLocation, assignFixedLocationFromMoveMatrix, stableDestinationOrMoveInMoveMatrix}
22+
import eighties.h24.generation.{IndividualFeature, WorldFeature, dayTimeSlice, nightTimeSlice, timeSlices}
2323
import eighties.h24.social.AggregatedSocialCategory
2424
import eighties.h24.space.{BoundingBox, Location, World, generateWorld}
2525
import monocle.Lens
@@ -39,7 +39,7 @@ object simulation:
3939
world: () => space.World[I],
4040
bbox: BoundingBox,
4141
gridSize: Int,
42-
locatedCell: LocatedCell,
42+
moveMatrixCell: LocatedCell,
4343
moveType: MoveType,
4444
exchange: (World[I], Int, Int, Random) => World[I],
4545
stableDestinations: I => Map[TimeSlice, Location],
@@ -54,24 +54,23 @@ object simulation:
5454
bb: BoundingBox,
5555
gridSize: Int,
5656
timeSlices: List[TimeSlice],
57-
locatedCell: LocatedCell,
57+
moveMatrixCell: LocatedCell,
5858
day: Int,
5959
slice: Int = 0): World[I] =
6060
timeSlices match
6161
case Nil => world
6262
case time :: t =>
6363
def moved = moveType match
64-
case MoveType.Data => dynamic.stableDestinationOrMoveInMoveMatrix(world, locatedCell, time, stableDestinations, location, home, socialCategory, 0.0, rng)
64+
case MoveType.Data => dynamic.stableDestinationOrMoveInMoveMatrix(world, moveMatrixCell, time, stableDestinations, location, home, socialCategory, 0.0, rng)
6565
case MoveType.PartialRandom(p, s) =>
6666
val randomMoveProbability = if s.contains(time) then p else 0.0
67-
dynamic.stableDestinationOrMoveInMoveMatrix(world, locatedCell, time, stableDestinations, location, home, socialCategory, randomMoveProbability, rng)
67+
dynamic.stableDestinationOrMoveInMoveMatrix(world, moveMatrixCell, time, stableDestinations, location, home, socialCategory, randomMoveProbability, rng)
6868
case MoveType.Random => dynamic.stableDestinationOrRandomMove(world, time, location, stableDestinations, rng)
6969
case MoveType.No => world
7070

7171
val convicted = exchange(moved, day, slice, rng)
7272
visitor.foreach(_(convicted, bb, gridSize, Some((day, slice))))
73-
simulateOneDay(convicted, bb, gridSize, t, locatedCell, day, slice + 1)
74-
73+
simulateOneDay(convicted, bb, gridSize, t, moveMatrixCell, day, slice + 1)
7574

7675
// Ensures the world is not retained in memory
7776
var currentWorld = world()
@@ -80,11 +79,29 @@ object simulation:
8079
for
8180
day <- 0 until days
8281
do
83-
currentWorld = simulateOneDay(currentWorld, bbox, gridSize, timeSlices.toList, locatedCell, day)
82+
currentWorld = simulateOneDay(currentWorld, bbox, gridSize, timeSlices.toList, moveMatrixCell, day)
8483

8584
currentWorld
8685

8786

87+
def assignStableMoves[I: ClassTag](
88+
world: World[I],
89+
moveMatrixCell: LocatedCell,
90+
moveType: MoveType,
91+
stableDestinations: Lens[I, Map[TimeSlice, Location]],
92+
location: Lens[I, Location],
93+
home: Lens[I, Location],
94+
socialCategory: I => AggregatedSocialCategory,
95+
rng: Random) =
96+
97+
moveType match
98+
case MoveType.Data | _: MoveType.PartialRandom =>
99+
val fixedDay = assignFixedLocationFromMoveMatrix(world, moveMatrixCell, stableDestinations, dayTimeSlice, location.get, home.get, socialCategory, rng)
100+
assignFixedLocation(fixedDay, stableDestinations, nightTimeSlice, home.get)
101+
case MoveType.Random => assignFixedLocation(world, stableDestinations, nightTimeSlice, home.get)
102+
case MoveType.No => assignFixedLocation(world, stableDestinations, nightTimeSlice, home.get)
103+
104+
88105
def simulate[I: ClassTag](
89106
days: Int,
90107
population: java.io.File,
@@ -105,27 +122,16 @@ object simulation:
105122
val moveMatrix = MoveMatrix.load(moves)
106123

107124
try
108-
def locatedCell: LocatedCell = (timeSlice: TimeSlice, i: Int, j: Int) => moveMatrix.get((i, j), timeSlice)
109125
def world = generateWorld(worldFeature.individualFeatures, buildIndividual, location, home, rng)
110-
111-
def populationWithMoves =
112-
moveType match
113-
case MoveType.Data | _: MoveType.PartialRandom =>
114-
val fixedDay = assignRandomDayLocation(world, locatedCell, stableDestinations, location.get, home.get, socialCategory, rng)
115-
assignFixNightLocation(
116-
fixedDay,
117-
stableDestinations,
118-
home.get
119-
)
120-
case MoveType.Random => assignFixNightLocation(world, stableDestinations, home.get)
121-
case MoveType.No => assignFixNightLocation(world, stableDestinations, home.get)
126+
def moveMatrixCell: LocatedCell = (timeSlice: TimeSlice, i: Int, j: Int) => moveMatrix.get((i, j), timeSlice)
127+
def populationWithMoves = assignStableMoves(world, moveMatrixCell, moveType, stableDestinations, location, home, socialCategory, rng = rng)
122128

123129
simulateWorld(
124130
days = days,
125131
world = () => populationWithMoves,
126132
bbox = bbox,
127133
gridSize = gridSize,
128-
locatedCell = locatedCell,
134+
moveMatrixCell = moveMatrixCell,
129135
moveType = moveType,
130136
exchange = exchange,
131137
stableDestinations = stableDestinations.get,

0 commit comments

Comments
 (0)