Commit 91748aa4 authored by Stefan Schuhbaeck's avatar Stefan Schuhbaeck
Browse files

groupSizeDistribution on source level

parent 8d6f3d8c
......@@ -23,7 +23,7 @@ public class GroupSourceControllerFactory extends SourceControllerFactory {
DynamicElementFactory dynamicElementFactory,
AttributesDynamicElement attributesDynamicElement,
Random random) {
groupModel.initializeGroupFactory(source.getId(), source.getAttributes().getGroupSizeDistribution());
return new GroupSourceController(scenario, source, dynamicElementFactory, attributesDynamicElement, random, groupModel);
}
}
......@@ -57,4 +57,12 @@ public class CentroidGroupFactory extends GroupFactory {
CentroidGroup group = groupCollection.removeMember(ped);
// System.out.printf("Remove ped %s from group %s %n", ped.getId(), group != null ? group.getID() : "noGroup");
}
public GroupSizeDeterminator getGroupSizeDeterminator() {
return groupSizeDeterminator;
}
public void setGroupSizeDeterminator(GroupSizeDeterminator groupSizeDeterminator) {
this.groupSizeDeterminator = groupSizeDeterminator;
}
}
......@@ -23,7 +23,7 @@ import java.util.concurrent.atomic.AtomicInteger;
public class CentroidGroupModel
implements GroupModel, DynamicElementAddListener<Pedestrian>, DynamicElementRemoveListener<Pedestrian> {
private GroupSizeDeterminator groupSizeDeterminator;
private Random random;
private Map<Integer, CentroidGroupFactory> groupFactories;
private Map<ScenarioElement, CentroidGroup> pedestrianGroupData;
......@@ -44,8 +44,9 @@ public class CentroidGroupModel
AttributesAgent attributesPedestrian, Random random) {
this.attributesCGM = Model.findAttributes(attributesList, AttributesCGM.class);
this.topography = topography;
setGroupSizeDeterminator(new GroupSizeDeterminatorRandom(
attributesCGM.getGroupSizeDistribution(), random));
this.random = random;
// setGroupSizeDeterminator(new GroupSizeDeterminatorRandom(
// attributesCGM.getGroupSizeDistribution(), random));
}
public void setPotentialFieldTarget(IPotentialFieldTarget potentialFieldTarget) {
......@@ -62,13 +63,21 @@ public class CentroidGroupModel
CentroidGroupFactory result = groupFactories.get(sourceId);
if (result == null) {
result = new CentroidGroupFactory(this, groupSizeDeterminator);
groupFactories.put(sourceId, result);
throw new IllegalArgumentException("For SourceID: " + sourceId + " no GroupFactory exists. " +
"Is this really a valid source?");
}
return result;
}
@Override
public void initializeGroupFactory(int sourceId, List<Double> groupSizeDistribution) {
GroupSizeDeterminator gsD = new GroupSizeDeterminatorRandom(groupSizeDistribution, random);
CentroidGroupFactory result =
new CentroidGroupFactory(this, gsD);
groupFactories.put(sourceId, result);
}
@Override
public CentroidGroup getGroup(final ScenarioElement ped) {
return pedestrianGroupData.get(ped);
......@@ -125,8 +134,4 @@ public class CentroidGroupModel
getGroupFactory(pedestrian.getSource().getId()).elementRemoved(pedestrian);
}
public void setGroupSizeDeterminator(GroupSizeDeterminator groupSizeDeterminator) {
this.groupSizeDeterminator = groupSizeDeterminator;
}
}
......@@ -3,6 +3,8 @@ package org.vadere.simulator.models.groups;
import org.vadere.simulator.models.Model;
import org.vadere.state.scenario.ScenarioElement;
import java.util.List;
public interface GroupModel extends Model {
public Group getGroup(ScenarioElement ped);
......@@ -12,5 +14,7 @@ public interface GroupModel extends Model {
public Group getNewGroup(int size);
public GroupFactory getGroupFactory(int SourceId);
public GroupFactory getGroupFactory(int sourceId);
public void initializeGroupFactory(int sourceId, List<Double> groupSizeDistribution);
}
package org.vadere.simulator.control;
import org.junit.Ignore;
import org.junit.Test;
import org.mockito.Mockito;
import org.vadere.simulator.control.factory.GroupSourceControllerFactory;
import org.vadere.simulator.control.factory.SingleSourceControllerFactory;
import org.vadere.simulator.control.factory.SourceControllerFactory;
import org.vadere.simulator.models.groups.CentroidGroupFactory;
import org.vadere.simulator.models.groups.CentroidGroupModel;
import org.vadere.simulator.models.groups.GroupModel;
import org.vadere.simulator.models.groups.GroupSizeDeterminatorRandom;
import org.vadere.state.attributes.Attributes;
import org.vadere.state.attributes.models.AttributesCGM;
......@@ -14,6 +17,7 @@ import org.vadere.state.attributes.scenario.SourceTestAttributesBuilder;
import org.vadere.state.scenario.Pedestrian;
import org.vadere.state.util.StateJsonConverter;
import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.util.geometry.shapes.VRectangle;
import java.util.ArrayList;
import java.util.Arrays;
......@@ -24,40 +28,47 @@ import static org.junit.Assert.assertEquals;
public class GroupSourceControllerTest extends TestSourceControllerUsingConstantSpawnRate {
private Integer[] groupSpawn;
private double[] groupDist;
private GroupModel m;
public void initSourceControllerFactory() {
CentroidGroupModel m = new CentroidGroupModel();
public SourceControllerFactory getSourceControllerFactory(SourceTestData d) {
m = new CentroidGroupModel();
ArrayList<Attributes> attrs = new ArrayList<>();
attrs.add(generateCGMAttributesJson(groupDist));
m.initialize(attrs, topography, attributesPedestrian, random);
attrs.add(new AttributesCGM());
m.initialize(attrs, d.topography, d.attributesPedestrian, d.random);
return new GroupSourceControllerFactory(m);
}
@Override
public void initialize(SourceTestAttributesBuilder builder) {
super.initialize(builder);
SourceTestData d = sourceTestData.get(sourceTestData.size() - 1);
if (groupSpawn.length > 0) {
GroupSizeDeterminatorRandom gsdRnd = Mockito.mock(GroupSizeDeterminatorRandom.class, Mockito.RETURNS_DEEP_STUBS);
Mockito.when(gsdRnd.nextGroupSize())
.thenReturn(groupSpawn[0], Arrays.copyOfRange(groupSpawn, 1, groupSpawn.length));
m.setGroupSizeDeterminator(gsdRnd);
CentroidGroupFactory cgf = (CentroidGroupFactory) m.getGroupFactory(d.source.getId());
cgf.setGroupSizeDeterminator(gsdRnd);
}
sourceControllerFactory = new GroupSourceControllerFactory(m);
}
@Test
public void testUpdateEqualStartAndEndTime() {
SourceTestAttributesBuilder builder = new SourceTestAttributesBuilder()
.setOneTimeSpawn(0)
.setSourceDim(5.0, 5.0);
groupDist = new double[]{0.0, 0.5, 0.5};
.setSourceDim(5.0, 5.0)
.setGroupSizeDistribution(0.0, 0.5, 0.5);
groupSpawn = new Integer[]{2, 2, 3, 3};
initialize(builder);
sourceController.update(0);
sourceController.update(1);
sourceController.update(2);
sourceController.update(3);
first().sourceController.update(0);
first().sourceController.update(1);
first().sourceController.update(2);
first().sourceController.update(3);
assertEquals("wrong pedestrian number", 2, countPedestrians());
assertEquals("wrong pedestrian number", 2, countPedestrians(0));
}
......@@ -69,18 +80,18 @@ public class GroupSourceControllerTest extends TestSourceControllerUsingConstant
SourceTestAttributesBuilder builder = new SourceTestAttributesBuilder()
.setStartTime(startTime).setEndTime(endTime)
.setSpawnIntervalForConstantDistribution(10)
.setSourceDim(5.0, 5.0);
groupDist = new double[]{0.0, 0.5, 0.5};
.setSourceDim(5.0, 5.0)
.setGroupSizeDistribution(0.0, 0.5, 0.5);
groupSpawn = new Integer[]{2, 3, 2, 3};
initialize(builder);
sourceController.update(startTime);
first().sourceController.update(startTime);
// one at the beginning
assertEquals("wrong pedestrian number.", 2, countPedestrians());
assertEquals("wrong pedestrian number.", 2, countPedestrians(0));
sourceController.update(endTime);
first().sourceController.update(endTime);
// and one at the end
assertEquals("wrong pedestrian number.", 5, countPedestrians());
assertEquals("wrong pedestrian number.", 5, countPedestrians(0));
}
......@@ -91,16 +102,16 @@ public class GroupSourceControllerTest extends TestSourceControllerUsingConstant
SourceTestAttributesBuilder builder = new SourceTestAttributesBuilder()
.setStartTime(0).setEndTime(endTime)
.setSpawnIntervalForConstantDistribution(5)
.setSourceDim(5.0, 5.0);
groupDist = new double[]{0.0, 0.5, 0.5};
.setSourceDim(5.0, 5.0)
.setGroupSizeDistribution(0.0, 0.5, 0.5);
groupSpawn = new Integer[]{2, 3, 2, 3};
initialize(builder);
for (double simTimeInSec = 0; simTimeInSec < endTime * 2; simTimeInSec += 1.0) {
sourceController.update(simTimeInSec);
first().sourceController.update(simTimeInSec);
}
assertEquals("wrong pedestrian number.", 7, countPedestrians());
assertEquals("wrong pedestrian number.", 7, countPedestrians(0));
}
......@@ -111,17 +122,17 @@ public class GroupSourceControllerTest extends TestSourceControllerUsingConstant
SourceTestAttributesBuilder builder = new SourceTestAttributesBuilder()
.setStartTime(0).setEndTime(endTime)
.setSpawnIntervalForConstantDistribution(0.1)
.setSourceDim(5.0, 5.0);
groupDist = new double[]{0.0, 0.5, 0.5};
.setSourceDim(5.0, 5.0)
.setGroupSizeDistribution(0.0, 0.5, 0.5);
groupSpawn = new Integer[]{2, 3, 2, 3, 2, 2, 3, 3, 3, 2, 2, 3, 3, 3, 3};
initialize(builder);
for (double simTimeInSec = 0; simTimeInSec < endTime * 2; simTimeInSec += 1.0) {
sourceController.update(simTimeInSec);
first().sourceController.update(simTimeInSec);
}
// sum(2, 3, 2, 3, 2, 2, 3, 3, 3, 2, 2) = 24
assertEquals("wrong pedestrian number.", 27, countPedestrians());
assertEquals("wrong pedestrian number.", 27, countPedestrians(0));
}
/**
......@@ -135,31 +146,31 @@ public class GroupSourceControllerTest extends TestSourceControllerUsingConstant
.setOneTimeSpawn(0)
.setSpawnNumber(100)
.setUseFreeSpaceOnly(true)
.setSourceDim(2 * d + 0.1, 4 * d + 0.1);
groupDist = new double[]{0.0, 0.0, 1}; // only groups of 3
.setSourceDim(2 * d + 0.1, 4 * d + 0.1)
.setGroupSizeDistribution(0.0, 0.0, 1);
groupSpawn = new Integer[]{};
initialize(builder);
for (double simTimeInSec = 0; simTimeInSec < 1000; simTimeInSec += 1.0) {
sourceController.update(simTimeInSec);
first().sourceController.update(simTimeInSec);
}
// The source has space for tow groups of three (with Random seed of 0)
// ist could also be the case that only one group can be placed.
assertEquals("wrong pedestrian number.", 6, countPedestrians());
assertEquals("wrong pedestrian number.", 6, countPedestrians(0));
// now, move the peds away after creating them
for (double simTimeInSec = 1000; simTimeInSec < 2000; simTimeInSec += 1.0) {
sourceController.update(simTimeInSec);
first().sourceController.update(simTimeInSec);
VPoint positionFarAway = new VPoint(1000, 1000);
for (Pedestrian pedestrian : topography.getElements(Pedestrian.class)) {
for (Pedestrian pedestrian : first().topography.getElements(Pedestrian.class)) {
pedestrian.setPosition(positionFarAway);
}
}
// now, all pedestrians should have been created
assertEquals("wrong pedestrian number.", 300, countPedestrians());
assertEquals("wrong pedestrian number.", 300, countPedestrians(0));
}
// WithDistribution
......@@ -168,17 +179,17 @@ public class GroupSourceControllerTest extends TestSourceControllerUsingConstant
public void testStartTime() {
SourceTestAttributesBuilder builder = new SourceTestAttributesBuilder()
.setDistributionClass(TestSourceControllerUsingDistributions.ConstantTestDistribution.class)
.setSourceDim(5.0, 5.0);
groupDist = new double[]{0.0, 0.0, 1}; // only groups of 3
.setSourceDim(5.0, 5.0)
.setGroupSizeDistribution(0.0, 0.0, 1);
groupSpawn = new Integer[]{3, 3, 3, 3};
initialize(builder);
sourceController.update(0);
first().sourceController.update(0);
pedestrianCountEquals(0);
sourceController.update(0.9);
first().sourceController.update(0.9);
pedestrianCountEquals(0);
sourceController.update(1);
first().sourceController.update(1);
pedestrianCountEquals(3);
}
......@@ -187,33 +198,34 @@ public class GroupSourceControllerTest extends TestSourceControllerUsingConstant
SourceTestAttributesBuilder builder = new SourceTestAttributesBuilder()
.setDistributionClass(TestSourceControllerUsingDistributions.ConstantTestDistribution.class)
.setEndTime(2)
.setSourceDim(5.0, 5.0);
groupDist = new double[]{0.0, 0.0, 1}; // only groups of 3
.setSourceDim(5.0, 5.0)
.setGroupSizeDistribution(0.0, 0.0, 1); // only groups of 3
groupSpawn = new Integer[]{3, 3, 3, 3};
initialize(builder);
sourceController.update(1);
first().sourceController.update(1);
pedestrianCountEquals(3);
sourceController.update(2);
first().sourceController.update(2);
pedestrianCountEquals(6);
sourceController.update(3); // end time reached -> no effect
first().sourceController.update(3); // end time reached -> no effect
pedestrianCountEquals(6);
}
@Test
public void testOneTimeSpawn() {
SourceTestAttributesBuilder builder = new SourceTestAttributesBuilder()
.setOneTimeSpawn(1).setSourceDim(5.0, 5.0);
groupDist = new double[]{0.0, 0.0, 1}; // only groups of 3
.setOneTimeSpawn(1)
.setSourceDim(5.0, 5.0)
.setGroupSizeDistribution(0.0, 0.0, 1); // only groups of 3
groupSpawn = new Integer[]{3, 3, 3, 3};
initialize(builder);
sourceController.update(0);
first().sourceController.update(0);
pedestrianCountEquals(0);
sourceController.update(1);
first().sourceController.update(1);
pedestrianCountEquals(3);
sourceController.update(2);
first().sourceController.update(2);
pedestrianCountEquals(3);
}
......@@ -221,14 +233,14 @@ public class GroupSourceControllerTest extends TestSourceControllerUsingConstant
public void testSpawnNumber() {
SourceTestAttributesBuilder builder = new SourceTestAttributesBuilder()
.setSpawnNumber(10)
.setSourceDim(5.0, 5.0);
groupDist = new double[]{0.0, 0.0, 0.0, 1}; // only groups of 4
.setSourceDim(5.0, 5.0)
.setGroupSizeDistribution(0.0, 0.0, 0.0, 1); // only groups of 4
groupSpawn = new Integer[]{}; // do not mock group Dist.
initialize(builder);
sourceController.update(1);
first().sourceController.update(1);
pedestrianCountEquals(10 * 4);
sourceController.update(2);
first().sourceController.update(2);
pedestrianCountEquals(20 * 4);
}
......@@ -237,16 +249,16 @@ public class GroupSourceControllerTest extends TestSourceControllerUsingConstant
SourceTestAttributesBuilder builder = new SourceTestAttributesBuilder()
.setStartTime(0).setEndTime(1)
.setSpawnIntervalForConstantDistribution(0.3)
.setSourceDim(5.0, 5.0);
groupDist = new double[]{0.0, 0.0, 0.25, 0.75}; // only groups of 4
.setSourceDim(5.0, 5.0)
.setGroupSizeDistribution(0.0, 0.0, 0.25, 0.75);
groupSpawn = new Integer[]{4, 3, 4, 4}; // do not mock group Dist.
initialize(builder);
// per update only one "spawn action" is performed.
// if the spawn rate is higher than the update time increment, spawns will get lost.
sourceController.update(0);
first().sourceController.update(0);
pedestrianCountEquals(4);
sourceController.update(1);
first().sourceController.update(1);
pedestrianCountEquals(15);
}
......@@ -261,37 +273,37 @@ public class GroupSourceControllerTest extends TestSourceControllerUsingConstant
.setStartTime(startTime).setEndTime(endTime)
.setSpawnNumber(100)
.setUseFreeSpaceOnly(true)
.setSourceDim(2 * d + 0.1, 4 * d + 0.1);
groupDist = new double[]{0.0, 0.0, 0.0, 1}; // only groups of 4
.setSourceDim(2 * d + 0.1, 4 * d + 0.1)
.setGroupSizeDistribution(0.0, 0.0, 0.0, 1);
groupSpawn = new Integer[]{};
initialize(builder);
doUpdates(100, startTime, endTime + 1);
doUpdates(0, 100, startTime, endTime + 1);
// despite many updates, only tow groups of four can be spawned
assertEquals(8, countPedestrians());
assertEquals(8, countPedestrians(0));
doUpdatesBeamingPedsAway(1000);
doUpdatesBeamingPedsAway(0, 1000);
// now, all pedestrians should have been created
assertEquals(2 * spawnNumber * 4, countPedestrians());
assertEquals(2 * spawnNumber * 4, countPedestrians(0));
}
@Test
public void testMaxSpawnNumberTotalSetTo0() {
SourceTestAttributesBuilder builder = new SourceTestAttributesBuilder()
.setMaxSpawnNumberTotal(0) // <-- max 0 -> spawn no peds at all
.setSourceDim(5.0, 5.0);
groupDist = new double[]{0.0, 0.0, 0.25, 0.75};
.setSourceDim(5.0, 5.0)
.setGroupSizeDistribution(0.0, 0.0, 0.25, 0.75);
groupSpawn = new Integer[]{4, 3, 4, 4};
initialize(builder);
sourceController.update(1);
sourceController.update(2);
sourceController.update(3);
first().sourceController.update(1);
first().sourceController.update(2);
first().sourceController.update(3);
assertEquals(0, countPedestrians());
assertEquals(0, countPedestrians(0));
}
@Test
......@@ -299,16 +311,16 @@ public class GroupSourceControllerTest extends TestSourceControllerUsingConstant
SourceTestAttributesBuilder builder = new SourceTestAttributesBuilder()
.setMaxSpawnNumberTotal(AttributesSource.NO_MAX_SPAWN_NUMBER_TOTAL) // <-- maximum not set
.setEndTime(2)
.setSourceDim(5.0, 5.0);
groupDist = new double[]{0.0, 0.0, 0.25, 0.75};
.setSourceDim(5.0, 5.0)
.setGroupSizeDistribution(0.0, 0.0, 0.25, 0.75);
groupSpawn = new Integer[]{4, 3, 4, 4};
initialize(builder);
sourceController.update(1);
sourceController.update(2);
sourceController.update(3);
first().sourceController.update(1);
first().sourceController.update(2);
first().sourceController.update(3);
assertEquals(7, countPedestrians());
assertEquals(7, countPedestrians(0));
}
@Test
......@@ -316,16 +328,16 @@ public class GroupSourceControllerTest extends TestSourceControllerUsingConstant
SourceTestAttributesBuilder builder = new SourceTestAttributesBuilder()
.setMaxSpawnNumberTotal(4) // <-- not exhausted
.setEndTime(2)
.setSourceDim(5.0, 5.0);
groupDist = new double[]{0.0, 0.0, 0.25, 0.75};
.setSourceDim(5.0, 5.0)
.setGroupSizeDistribution(0.0, 0.0, 0.25, 0.75);
groupSpawn = new Integer[]{4, 3, 4, 4};
initialize(builder);
sourceController.update(1);
sourceController.update(2);
sourceController.update(3);
first().sourceController.update(1);
first().sourceController.update(2);
first().sourceController.update(3);
assertEquals(7, countPedestrians());
assertEquals(7, countPedestrians(0));
}
@Test
......@@ -335,16 +347,18 @@ public class GroupSourceControllerTest extends TestSourceControllerUsingConstant
SourceTestAttributesBuilder builder = new SourceTestAttributesBuilder()
.setEndTime(endTime)
.setMaxSpawnNumberTotal(maxSpawnNumberTotal) // <-- exhausted!
.setSourceDim(5.0, 5.0);
groupDist = new double[]{0.0, 0.0, 0.25, 0.75};
.setSourceDim(5.0, 5.0)
.setGroupSizeDistribution(0.0, 0.0, 0.25, 0.75);
groupSpawn = new Integer[]{4, 3, 4, 4};
initialize(builder);
doUpdates(50, 0, 200);
doUpdates(0, 50, 0, 200);
assertEquals(15, countPedestrians());
assertEquals(15, countPedestrians(0));
}
@Test
public void testMaxSpawnNumberTotalWithLargeEndTimeAndSpawnNumberGreater1() {
int maxSpawnNumberTotal = 4; // <-- exhausted!
......@@ -352,39 +366,32 @@ public class GroupSourceControllerTest extends TestSourceControllerUsingConstant
.setEndTime(100)
.setSpawnNumber(5)
.setMaxSpawnNumberTotal(maxSpawnNumberTotal)
.setSourceDim(5.0, 5.0);
groupDist = new double[]{0.0, 0.0, 0.25, 0.75};
.setSourceDim(5.0, 5.0)
.setGroupSizeDistribution(0.0, 0.0, 0.25, 0.75);
groupSpawn = new Integer[]{4, 3, 4, 4};
initialize(builder);
doUpdates(50, 0, 200);
assertEquals(15, countPedestrians());
}
doUpdates(0, 50, 0, 200);
private AttributesCGM generateCGMAttributesJson(double[] groups) {
StringBuilder sb = new StringBuilder();
sb.append("[");
for (int i = 0; i < groups.length - 1; i++) {
sb.append(groups[i]).append(", ");
}
sb.append(groups[groups.length - 1]).append(" ]");
String json = "{\n" +
" \"groupMemberRepulsionFactor\" : 0.01,\n" +
" \"leaderAttractionFactor\" : 0.003,\n" +
" \"groupSizeDistribution\" : " + sb.toString() + "\n" +
" }";
return StateJsonConverter.deserializeObjectFromJson(json, AttributesCGM.class);
assertEquals(15, countPedestrians(0));
}
@Test
@Ignore
public void multipleSources() {
int maxSpawnNumberTotal = 4;
SourceTestAttributesBuilder builder1 = new SourceTestAttributesBuilder()
.setGroupSizeDistribution(0.0, 0.0, 0.25, 0.75)
.setSourceDim(new VRectangle(0, 0, 3, 4));
SourceTestAttributesBuilder builder2 = new SourceTestAttributesBuilder()
.setGroupSizeDistribution(0.0, 1.0)
.setSourceDim(new VRectangle(20, 20, 3, 2));
groupSpawn = new Integer[]{4, 3, 4, 4}; // todo spawn group for multiple sources
initialize(builder1);
initialize(builder2);
//todo test different Distributions for sources
private CentroidGroupModel mockGroupSizeSpawn(CentroidGroupModel m, Integer first, Integer... groups) {
GroupSizeDeterminatorRandom gsdRnd = Mockito.mock(GroupSizeDeterminatorRandom.class, Mockito.RETURNS_DEEP_STUBS);
Mockito.when(gsdRnd.nextGroupSize()).thenReturn(first