24.09., 9:00 - 11:00: Due to updates GitLab will be unavailable for some minutes between 09:00 and 11:00.

Commit d8e644f4 authored by Benedikt Zoennchen's avatar Benedikt Zoennchen

implementation of a parallel event driven update scheme.

parent 8415d0a7
......@@ -110,6 +110,9 @@ public class PedestrianOSM extends Pedestrian {
this.updateScheme.update(timeStepInSec, currentTimeInSec, callMethod);
}*/
/**
* Expensive call!
*/
public void updateNextPosition() {
if (PotentialFieldTargetRingExperiment.class.equals(potentialFieldTarget.getClass())) {
......
......@@ -9,10 +9,13 @@ import org.vadere.util.geometry.shapes.VPoint;
import java.util.Comparator;
import java.util.PriorityQueue;
/**
*
*/
public class UpdateSchemeEventDriven implements UpdateSchemeOSM {
private final Topography topography;
private PriorityQueue<PedestrianOSM> pedestrianEventsQueue;
protected PriorityQueue<PedestrianOSM> pedestrianEventsQueue;
public UpdateSchemeEventDriven(@NotNull final Topography topography) {
this.topography = topography;
......@@ -27,7 +30,7 @@ public class UpdateSchemeEventDriven implements UpdateSchemeOSM {
}
if(!pedestrianEventsQueue.isEmpty()) {
// default is fixed order sequential update
// event driven update ignores time credits!
while (pedestrianEventsQueue.peek().getTimeOfNextStep() < currentTimeInSec) {
PedestrianOSM ped = pedestrianEventsQueue.poll();
update(ped, currentTimeInSec);
......@@ -36,7 +39,7 @@ public class UpdateSchemeEventDriven implements UpdateSchemeOSM {
}
}
private void update(@NotNull final PedestrianOSM pedestrian, final double currentTimeInSec) {
protected void update(@NotNull final PedestrianOSM pedestrian, final double currentTimeInSec) {
VPoint oldPosition = pedestrian.getPosition();
// for the first step after creation, timeOfNextStep has to be initialized
......@@ -44,9 +47,11 @@ public class UpdateSchemeEventDriven implements UpdateSchemeOSM {
pedestrian.setTimeOfNextStep(currentTimeInSec);
}
// this can cause problems if the pedestrian desired speed is 0 (see speed adjuster)
pedestrian.setDurationNextStep(pedestrian.getStepSize() / pedestrian.getDesiredSpeed());
pedestrian.updateNextPosition();
makeStep(topography, pedestrian, pedestrian.getDurationNextStep());
pedestrian.setTimeOfNextStep(pedestrian.getTimeOfNextStep() + pedestrian.getDurationNextStep());
topography.moveElement(pedestrian, oldPosition);
}
......
package org.vadere.simulator.models.osm.updateScheme;
import org.jetbrains.annotations.NotNull;
import org.vadere.simulator.models.osm.PedestrianOSM;
import org.vadere.state.scenario.Topography;
import org.vadere.util.geometry.LinkedCellsGrid;
import org.vadere.util.geometry.shapes.VRectangle;
import java.util.ArrayList;
import java.util.List;
public class UpdateSchemeEventDrivenParallel extends UpdateSchemeEventDriven {
private final Topography topography;
private LinkedCellsGrid<PedestrianOSM> linkedCellsGrid;
private boolean[][] locked;
private double pedestrianPotentialWidth;
public UpdateSchemeEventDrivenParallel(@NotNull final Topography topography, @NotNull final double pedestrianPotentialWidth) {
super(topography);
this.topography = topography;
this.pedestrianPotentialWidth = pedestrianPotentialWidth;
}
@Override
public void update(final double timeStepInSec, final double currentTimeInSec) {
double maxStepSize = 0;
for(PedestrianOSM pedestrianOSM : topography.getElements(PedestrianOSM.class)) {
pedestrianOSM.clearStrides();
maxStepSize = Math.max(pedestrianOSM.getStepSize(), maxStepSize);
}
// event driven update ignores time credits
do{
linkedCellsGrid = new LinkedCellsGrid<>(new VRectangle(topography.getBounds()), pedestrianPotentialWidth + maxStepSize);
locked = new boolean[linkedCellsGrid.getGridWidth()][linkedCellsGrid.getGridHeight()];
for(PedestrianOSM pedestrianOSM : topography.getElements(PedestrianOSM.class)) {
linkedCellsGrid.addObject(pedestrianOSM);
}
List<PedestrianOSM> parallelUpdatablePeds = new ArrayList<>();
List<PedestrianOSM> unUpdatablePedsd = new ArrayList<>();
while (!pedestrianEventsQueue.isEmpty() && pedestrianEventsQueue.peek().getTimeOfNextStep() < currentTimeInSec) {
PedestrianOSM ped = pedestrianEventsQueue.poll();
int[] gridPos = linkedCellsGrid.gridPos(ped.getPosition());
if(!locked[gridPos[0]][gridPos[1]]) {
parallelUpdatablePeds.add(ped);
for(int y = -1; y <= 1; y++) {
for(int x = -1; x <= 1; x++) {
locked[gridPos[0]+x][gridPos[1]+y] = true;
}
}
}
else {
unUpdatablePedsd.add(ped);
}
}
parallelUpdatablePeds.parallelStream().forEach(ped -> {
update(ped, currentTimeInSec);
});
pedestrianEventsQueue.addAll(unUpdatablePedsd);
pedestrianEventsQueue.addAll(parallelUpdatablePeds);
} while (!pedestrianEventsQueue.isEmpty() && pedestrianEventsQueue.peek().getTimeOfNextStep() < currentTimeInSec);
}
}
......@@ -34,6 +34,8 @@ public interface UpdateSchemeOSM extends DynamicElementRemoveListener<Pedestrian
case PARALLEL: return new UpdateSchemeParallel(topography);
case EVENT_DRIVEN: return new UpdateSchemeEventDriven(topography);
case SHUFFLE: return new UpdateSchemeShuffle(topography, random);
//TODO: magic number!
case EVENT_DRIVEN_PARALLEL: return new UpdateSchemeEventDrivenParallel(topography, 0.5);
default: throw new IllegalArgumentException(updateType + " is not supported.");
}
}
......@@ -63,7 +65,9 @@ public interface UpdateSchemeOSM extends DynamicElementRemoveListener<Pedestrian
default void movePedestrian(@NotNull final Topography topography, @NotNull final PedestrianOSM pedestrian, @NotNull final VPoint from, @NotNull final VPoint to) {
pedestrian.setPosition(to);
topography.moveElement(pedestrian, from);
synchronized (topography) {
topography.moveElement(pedestrian, from);
}
}
default void makeStep(@NotNull final Topography topography, @NotNull final PedestrianOSM pedestrian, final double stepTime) {
......
......@@ -37,15 +37,15 @@ public class DynamicElementContainer<T extends DynamicElement> {
this.moveListener = new LinkedList<>();
}
public LinkedCellsGrid<T> getCellsElements() {
public synchronized LinkedCellsGrid<T> getCellsElements() {
return cellsElements;
}
public Collection<T> getElements() {
public synchronized Collection<T> getElements() {
return elementMap.values();
}
public T getElement(int id) {
public synchronized T getElement(int id) {
return elementMap.get(id);
}
......@@ -57,7 +57,7 @@ public class DynamicElementContainer<T extends DynamicElement> {
return this.initialElements;
}
public void addElement(T element) {
public synchronized void addElement(T element) {
this.elementMap.put(element.getId(), element);
this.cellsElements.addObject(element);
......@@ -66,7 +66,7 @@ public class DynamicElementContainer<T extends DynamicElement> {
}
}
public void moveElement(T element, VPoint oldPosition) {
public synchronized void moveElement(T element, VPoint oldPosition) {
this.cellsElements.moveObject(element, oldPosition);
for (DynamicElementMoveListener<T> listener : moveListener) {
......@@ -74,7 +74,7 @@ public class DynamicElementContainer<T extends DynamicElement> {
}
}
public void removeElement(T element) {
public synchronized void removeElement(T element) {
this.elementMap.remove(element.getId());
this.cellsElements.removeObject(element);
......@@ -83,11 +83,11 @@ public class DynamicElementContainer<T extends DynamicElement> {
}
}
public void addElementRemovedListener(DynamicElementRemoveListener<T> listener) {
public synchronized void addElementRemovedListener(DynamicElementRemoveListener<T> listener) {
this.removeListener.add(listener);
}
public void addElementAddedListener(DynamicElementAddListener<T> listener) {
public synchronized void addElementAddedListener(DynamicElementAddListener<T> listener) {
this.addListener.add(listener);
}
......
package org.vadere.state.types;
public enum UpdateType {
SEQUENTIAL, EVENT_DRIVEN, PARALLEL, SHUFFLE, PARALLEL_OPEN_CL
SEQUENTIAL, EVENT_DRIVEN, PARALLEL, SHUFFLE, PARALLEL_OPEN_CL, EVENT_DRIVEN_PARALLEL;
}
......@@ -10,7 +10,9 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.jetbrains.annotations.NotNull;
import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.util.geometry.shapes.VRectangle;
/**
* A grid augmenting the position of generic objects, for faster access. O(1)
......@@ -100,6 +102,18 @@ public class LinkedCellsGrid<T extends PointPositioned> implements Iterable<T> {
return this.grid;
}
public int getGridWidth() {
return gridSize[0];
}
public int getGridHeight() {
return gridSize[1];
}
public LinkedCellsGrid(@NotNull final VRectangle bound, double sideLength) {
this(bound.x, bound.y, bound.width, bound.height, sideLength);
}
/**
* Generates a LinkedCellsGrid with given dimension, position and number of
* items on one side.
......@@ -139,8 +153,6 @@ public class LinkedCellsGrid<T extends PointPositioned> implements Iterable<T> {
this.cellSize[1] = this.height / gridSize[1];
this.grid = generateGrid(this.gridSize[0], this.gridSize[1]);
}
/**
......@@ -152,7 +164,7 @@ public class LinkedCellsGrid<T extends PointPositioned> implements Iterable<T> {
* @return the position in the grid, from 0 to this.gridSize-1 in both
* coordinates.
*/
private int[] gridPos(VPoint pos) {
public int[] gridPos(VPoint pos) {
// compute position in the grid
int iX = (int) Math.max(
0,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment