Commit eff5d429 authored by Julian Zobel's avatar Julian Zobel 🦄
Browse files

Merge branch 'master' into 'cherry-pick-7698d9d7'

# Conflicts:
#   src/de/tud/kom/p2psim/impl/analyzer/metric/output/MetricOutputDAO.java
#   src/de/tud/kom/p2psim/impl/util/db/dao/DAO.java
parents 1c7f20ec 37020b44
......@@ -25,7 +25,7 @@ package de.tud.kom.p2psim.impl.util.stat.distributions;
import de.tudarmstadt.maki.simonstrator.api.Randoms;
import de.tudarmstadt.maki.simonstrator.api.util.Distribution;
import de.tudarmstadt.maki.simonstrator.api.util.XMLConfigurableConstructor;
import umontreal.iro.lecuyer.probdist.LognormalDist;
import umontreal.ssj.probdist.LognormalDist;
public class LognormalDistribution implements Distribution {
......
......@@ -25,7 +25,7 @@ package de.tud.kom.p2psim.impl.util.stat.distributions;
import de.tudarmstadt.maki.simonstrator.api.Randoms;
import de.tudarmstadt.maki.simonstrator.api.util.Distribution;
import de.tudarmstadt.maki.simonstrator.api.util.XMLConfigurableConstructor;
import umontreal.iro.lecuyer.probdist.LognormalDist;
import umontreal.ssj.probdist.LognormalDist;
public class MixedLogNormalDistribution implements Distribution {
......
......@@ -20,7 +20,7 @@
package de.tud.kom.p2psim.impl.util.structures;
import de.tud.kom.p2psim.impl.topology.PositionVector;
import de.tud.kom.p2psim.impl.topology.util.PositionVector;
import de.tud.kom.p2psim.impl.topology.waypoints.graph.Waypoint;
public class WaypointKdTree extends KdTree<Waypoint> {
......
......@@ -24,8 +24,15 @@ import java.util.List;
import java.util.Set;
import de.tudarmstadt.maki.simonstrator.api.Host;
import de.tudarmstadt.maki.simonstrator.api.Time;
import de.tudarmstadt.maki.simonstrator.api.common.graph.INodeID;
import de.tudarmstadt.maki.simonstrator.api.component.ComponentNotAvailableException;
import de.tudarmstadt.maki.simonstrator.api.component.privacy.PrivacyComponent;
import de.tudarmstadt.maki.simonstrator.api.component.privacy.PrivacyLevel;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.environment.data.properties.VehicleProperty;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.LocationListener;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.LocationRequest;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.route.Route;
import de.tudarmstadt.maki.simonstrator.api.component.sis.SiSComponent;
import de.tudarmstadt.maki.simonstrator.api.component.sis.SiSDataCallback;
......@@ -50,6 +57,8 @@ public class DefaultVehicleInformationComponent implements VehicleInformationCom
private String vehicleID;
private long _startingTime = -1;
public DefaultVehicleInformationComponent(Host host, VehicleController controller, SimulationSetupExtractor extractor, boolean pRouteKnown) {
this.host = host;
......@@ -87,31 +96,57 @@ public class DefaultVehicleInformationComponent implements VehicleInformationCom
});
siSComponent.provide().nodeState(SiSTypes.HEADING, new SiSDataCallback<Double>() {
@Override
public Double getValue(INodeID pNodeID,
SiSProviderHandle pProviderHandle)
throws InformationNotAvailableException {
if (pNodeID == getHost().getId()) {
if (isValid()) {
return controller.getVehicleHeading(vehicleID);
}
}
return null;
}
@Override
public Set<INodeID> getObservedNodes() {
return INodeID.getSingleIDSet(getHost().getId());
}
@Override
public SiSInfoProperties getInfoProperties() {
return new SiSInfoProperties();
}
});
siSComponent.provide().nodeState(SiSTypes.HEADING, new SiSDataCallback<Double>() {
@Override
public Double getValue(INodeID pNodeID,
SiSProviderHandle pProviderHandle)
throws InformationNotAvailableException {
if (pNodeID == getHost().getId()) {
if (isValid()) {
return controller.getVehicleHeading(vehicleID);
}
}
return null;
}
@Override
public Set<INodeID> getObservedNodes() {
return INodeID.getSingleIDSet(getHost().getId());
}
@Override
public SiSInfoProperties getInfoProperties() {
return new SiSInfoProperties();
}
});
siSComponent.provide().nodeState(SiSTypes.VEHICLE_LENGTH, new SiSDataCallback<Double>() {
@Override
public Double getValue(INodeID pNodeID,
SiSProviderHandle pProviderHandle)
throws InformationNotAvailableException {
if (pNodeID == getHost().getId()) {
if (isValid()) {
return controller.getVehicleLength(vehicleID);
}
}
return null;
}
@Override
public Set<INodeID> getObservedNodes() {
return INodeID.getSingleIDSet(getHost().getId());
}
@Override
public SiSInfoProperties getInfoProperties() {
return new SiSInfoProperties();
}
});
if (pRouteKnown) {
siSComponent.provide().nodeState(SiSTypes.ROUTE, new SiSDataCallback<RoadNetworkRoute>() {
......@@ -145,11 +180,32 @@ public class DefaultVehicleInformationComponent implements VehicleInformationCom
}
}
@Override
public VehicleProperty getVehicleProperty() {
PrivacyLevel privacyLevel = PrivacyLevel.NO_PRIVACY;
try {
PrivacyComponent privacyComponent = getHost().getComponent(PrivacyComponent.class);
privacyLevel = privacyComponent.getPrivacyLevel();
} catch (ComponentNotAvailableException e) {
// Nothing to be done
}
return new VehicleProperty(host.getId().value(), getLastLocation(),
getCurrentRoute().getStart(), getCurrentSpeed(), getLength(), privacyLevel);
}
@Override
public void setVehicleID(String pVehicleID) {
vehicleID = pVehicleID;
_startingTime = Time.getCurrentTime();
}
@Override
public long getStartingTime() {
return _startingTime;
}
@Override
public void resetVehicleID() {
vehicleID = null;
......@@ -183,6 +239,10 @@ public class DefaultVehicleInformationComponent implements VehicleInformationCom
return true;
}
public double getLength() {
return controller.getVehicleLength(vehicleID);
}
@Override
public RoadNetworkRoute findNewRoute() {
try {
......@@ -243,4 +303,24 @@ public class DefaultVehicleInformationComponent implements VehicleInformationCom
throw new UnsupportedOperationException();
}
@Override
public Location getLastLocation() {
return controller.getVehiclePosition(vehicleID);
}
@Override
public void requestLocationUpdates(LocationRequest pRequest, LocationListener pListener) {
throw new UnsupportedOperationException();
}
@Override
public void removeLocationUpdates(LocationListener pListener) {
throw new UnsupportedOperationException();
}
@Override
public LocationRequest getLocationRequest() {
throw new UnsupportedOperationException();
}
}
......@@ -24,18 +24,24 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import de.tudarmstadt.maki.simonstrator.api.Host;
import de.tudarmstadt.maki.simonstrator.api.common.graph.INodeID;
import de.tudarmstadt.maki.simonstrator.api.component.ComponentNotAvailableException;
import de.tudarmstadt.maki.simonstrator.api.component.network.NetInterface;
import de.tudarmstadt.maki.simonstrator.api.component.network.NetworkComponent.NetInterfaceName;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.environment.data.VectoralProperty;
import de.tudarmstadt.maki.simonstrator.api.component.transition.TransitionEngine;
import de.tudarmstadt.maki.simonstrator.api.component.transport.ConnectivityListener;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.VehicleInformationComponent;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.caching.CacheStateListener;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.caching.CachingComponent;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.caching.decision.CacheDecisionStrategy;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.caching.decision.CacheSizeAwareCacheDecisionStrategy;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.caching.invalidation.CacheInvalidationStrategy;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.caching.replacement.CacheReplacementStrategy;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.information.AggregatedInformation;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.information.AvailableInformationAttributes;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.information.JamInformation;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.information.PointInformation;
......@@ -44,8 +50,8 @@ import de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.Road
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.RoadNetworkEdge;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.RoadNetworkRoute;
public class DefaultCachingComponent
implements CachingComponent, ConnectivityListener {
public class DefaultCachingComponent implements CachingComponent, ConnectivityListener {
private Map<Class<? extends Object>, List<PointInformation>> _cache = new HashMap<>();
private Map<Integer, Integer> _lastColorValues = new HashMap<>();
......@@ -56,10 +62,17 @@ implements CachingComponent, ConnectivityListener {
private CacheReplacementStrategy _replacementStrategy;
private CacheDecisionStrategy _decisionStrategy;
private CacheDecisionStrategy _defaultDecisionStrategy;
private Map<Class<? extends Object>, CacheDecisionStrategy> _decisionStrategies = new HashMap<>();
private int _minObservations = 0;
private int _maxCacheSize = Integer.MAX_VALUE;
private double[] informationRatios = new double[] {1, 0.75, 0.5, 0.25, 0};
private List<CacheStateListener> _cacheStateListeners = new ArrayList<>();
public DefaultCachingComponent(Host pHost,
CacheInvalidationStrategy pInvalidationStrategy,
CacheReplacementStrategy pReplacementStrategy,
......@@ -67,46 +80,149 @@ implements CachingComponent, ConnectivityListener {
_host = pHost;
if (_host != null) {
_host.getNetworkComponent().getByName(NetInterfaceName.WIFI)
.addConnectivityListener(this);
NetInterface cellular = _host.getNetworkComponent().getByName(NetInterfaceName.MOBILE);
cellular.addConnectivityListener(this);
}
_invalidationStrategy = pInvalidationStrategy;
_replacementStrategy = pReplacementStrategy;
_decisionStrategy = pDecisionStrategy;
_defaultDecisionStrategy = pDecisionStrategy;
}
private TransitionEngine getTransitionEngine() throws AssertionError {
try {
return getHost().getComponent(TransitionEngine.class);
} catch (ComponentNotAvailableException e) {
throw new AssertionError("Unable to get transition engine!");
}
}
@Override
public void registerCacheStateListener(CacheStateListener pListener) {
_cacheStateListeners.add(pListener);
}
@Override
public <T extends PointInformation> List<T> getDecidedCacheEntries(
Class<T> pCacheEntryClass) {
CacheDecisionStrategy decisionStrategy = getCacheDecisionStrategy(pCacheEntryClass);
Set<RoadNetworkEdge> allEverActiveEdges = RoadNetwork.CURRENT_ROAD_NETWORK.getAllEverActiveEdges();
List<T> cacheEntries = getCacheEntries(pCacheEntryClass);
if (cacheEntries == null) {
return null;
}
Map<Object, List<PointInformation>> similarCacheEntries = new HashMap<>();
Map<Object, Map<Class<? extends Object>, List<PointInformation>>> similarCacheEntries = new HashMap<>();
for (T t : cacheEntries) {
Object position = getEdgeOrPosition(t);
if (!similarCacheEntries.containsKey(position)) {
similarCacheEntries.put(position, new ArrayList<>());
if (!(position instanceof RoadNetworkEdge) || allEverActiveEdges.contains((position))) {
if (!similarCacheEntries.containsKey(position)) {
similarCacheEntries.put(position, new HashMap<>());
}
if (!similarCacheEntries.get(position).containsKey(t.getValue().getClass())) {
similarCacheEntries.get(position).put(t.getValue().getClass(), new ArrayList<PointInformation>());
}
similarCacheEntries.get(position).get(t.getValue().getClass()).add(t);
}
similarCacheEntries.get(position).add(t);
}
List<T> decidedInformation = new ArrayList<>();
for (List<PointInformation> similarEntries : similarCacheEntries
for (Map<Class<? extends Object>, List<PointInformation>> similarEdges : similarCacheEntries
.values()) {
PointInformation correctInformation = _decisionStrategy
.decideOnCorrectInformation(similarEntries);
decidedInformation.add((T) correctInformation);
for (List<PointInformation> similarInformation : similarEdges.values()) {
if (similarInformation.size() >= _minObservations) {
PointInformation correctInformation = decisionStrategy
.decideOnCorrectInformation(similarInformation);
decidedInformation.add((T) correctInformation);
}
}
}
return decidedInformation;
}
@Override
public <T extends PointInformation> List<T> getDecidedCacheEntries(
Class<T> pCacheEntryClass, RoadNetworkEdge pEdge) {
return getDecidedCacheEntries(pCacheEntryClass, null, pEdge);
}
@Override
public <T extends PointInformation> List<T> getDecidedCacheEntries(
Class<T> pCacheEntryClass, Class<?> pCacheValueClass, RoadNetworkEdge pEdge) {
return getDecidedCacheEntries(pCacheEntryClass, pCacheValueClass, pEdge, null);
}
@Override
public <T extends PointInformation> List<T> getDecidedCacheEntries(Class<T> pCacheEntryClass, Class<?> pCacheValueClass,
RoadNetworkEdge pEdge, INodeID pWithoutID) {
CacheDecisionStrategy decisionStrategy = getCacheDecisionStrategy(pCacheEntryClass);
Set<RoadNetworkEdge> allEverActiveEdges = RoadNetwork.CURRENT_ROAD_NETWORK.getAllEverActiveEdges();
if (!allEverActiveEdges.contains(pEdge)) {
return null;
}
List<T> cacheEntries = getCacheEntries(pCacheEntryClass);
if (cacheEntries == null) {
return null;
}
Map<Class<? extends Object>, List<PointInformation>> similarCacheEntries = new HashMap<>();
for (T t : cacheEntries) {
if (pWithoutID == null || !t.getAttribute(AvailableInformationAttributes.OWNER).equals(pWithoutID)) {
Object position = getEdgeOrPosition(t);
if (position.equals(pEdge) && (pCacheValueClass == null || t.getValue().getClass().equals(pCacheValueClass))) {
if (!similarCacheEntries.containsKey(t.getValue().getClass())) {
similarCacheEntries.put(t.getValue().getClass(), new ArrayList<PointInformation>());
}
similarCacheEntries.get(t.getValue().getClass()).add(t);
}
}
}
List<T> decidedInformation = new ArrayList<>();
for (List<PointInformation> similarInformation : similarCacheEntries.values()) {
if (similarInformation.size() >= _minObservations) {
PointInformation correctInformation = decisionStrategy
.decideOnCorrectInformation(similarInformation);
decidedInformation.add((T) correctInformation);
}
}
return decidedInformation;
}
private <T extends PointInformation> CacheDecisionStrategy getCacheDecisionStrategy(Class<T> pCacheEntryClass)
throws AssertionError {
if (!_decisionStrategies.containsKey(pCacheEntryClass)) {
CacheDecisionStrategy clone = _defaultDecisionStrategy.clone();
TransitionEngine tEngine = getTransitionEngine();
clone = tEngine.createMechanismProxy(CacheDecisionStrategy.class, clone, DECISION_STRATEGY + pCacheEntryClass.getSimpleName());
_decisionStrategies.put(pCacheEntryClass, clone);
}
CacheDecisionStrategy decisionStrategy = _decisionStrategies.get(pCacheEntryClass);
return decisionStrategy;
}
public void setMinObservations(int pMinObservations) {
this._minObservations = pMinObservations;
}
@Override
public <T extends PointInformation> List<T> getCacheEntries(
Class<T> pCacheEntryClass) {
......@@ -131,8 +247,8 @@ implements CachingComponent, ConnectivityListener {
@Override
public <T extends PointInformation> boolean containsEntry(T pCacheEntry) {
if (_cache.containsKey(pCacheEntry)) {
List<? extends Object> cacheEntries = _cache.get(pCacheEntry);
if (_cache.containsKey(pCacheEntry.getClass())) {
List<? extends Object> cacheEntries = _cache.get(pCacheEntry.getClass());
return cacheEntries.contains(pCacheEntry);
}
return false;
......@@ -145,7 +261,81 @@ implements CachingComponent, ConnectivityListener {
}
List<PointInformation> entries = _cache.get(pCacheEntry.getClass());
if (pCacheEntry instanceof AggregatedInformation && ((AggregatedInformation) pCacheEntry).isAggregated()) {
List<PointInformation> toBeRemoved = new ArrayList<>();
for (PointInformation pointInformation : entries) {
if (_replacementStrategy.replaceInformation(pointInformation, pCacheEntry)) {
toBeRemoved.add(pointInformation);
}
}
for (PointInformation pointInformation : toBeRemoved) {
entries.remove(pointInformation);
}
}
shrinkCache(_maxCacheSize);
entries.add(pCacheEntry);
for (CacheStateListener cacheStateListener : _cacheStateListeners) {
cacheStateListener.entryStored(pCacheEntry);
}
}
private void shrinkCache(int maxSize) {
while (getTotalCacheSize() > maxSize) {
int maxSizeValue = 0;
List<PointInformation> removedValues = null;
List<PointInformation> removedList = null;
for (List<PointInformation> informationList : _cache.values()) {
Map<Object, List<PointInformation>> perPosition = new HashMap<>();
for (PointInformation pointInformation : informationList) {
Object position = getEdgeOrPosition(pointInformation);
if (!perPosition.containsKey(position)) {
perPosition.put(position, new ArrayList<>());
}
perPosition.get(position).add(pointInformation);
}
for (Entry<Object, List<PointInformation>> entry : perPosition.entrySet()) {
if (!((RoadNetworkEdge) entry.getKey()).isActive()) {
removedValues = entry.getValue();
removedList = informationList;
break;
}
if (maxSizeValue < entry.getValue().size()) {
maxSizeValue = entry.getValue().size();
removedValues = entry.getValue();
removedList = informationList;
}
}
}
removedList.removeAll(removedValues);
CacheDecisionStrategy decisionStrategy = getCacheDecisionStrategy(removedValues.get(0).getClass());
PointInformation correctInformation = decisionStrategy
.decideOnCorrectInformation(removedValues);
for (CacheStateListener cacheStateListener : _cacheStateListeners) {
cacheStateListener.entriesRemoved(removedValues, correctInformation);
}
}
}
private int getTotalCacheSize() {
int sum = 0;
for (List<PointInformation> informationList : _cache.values()) {
sum += informationList.size();
}
return sum;
}
@Override
......@@ -172,11 +362,47 @@ implements CachingComponent, ConnectivityListener {
}
@Override
public void performDecisionTransition(Class<? extends Object> pInformationClass, Class<? extends CacheDecisionStrategy> pCacheDecisionStrategy) {
getTransitionEngine().executeAtomicTransition(DECISION_STRATEGY + pInformationClass.getSimpleName(), pCacheDecisionStrategy);
}
@Override
public void setMaxSize(int pMaxCacheSize) {
_maxCacheSize = pMaxCacheSize;
shrinkCache(_maxCacheSize);
}
@Override
public void adjustCacheSizePerEntry(Class<? extends Object> pInformationClass, int pMaxCacheSizePerEntry) {
getTransitionEngine().alterLocalState(DECISION_STRATEGY + pInformationClass.getSimpleName(), CacheSizeAwareCacheDecisionStrategy.class, "CacheSize", pMaxCacheSizePerEntry);
}
@Override
public void clear() {
_cache.clear();
}
@Override
public <T extends PointInformation> void partialClear(Class<T> pCacheEntryClass, Class<?> pCacheValueClass, RoadNetworkEdge pEdge) {
List<PointInformation> cacheEntries = _cache.get(pCacheEntryClass);
if (cacheEntries == null) {
return;
}
List<PointInformation> toBeRemoved = new ArrayList<>();
for (PointInformation entry : cacheEntries) {
if ((pEdge == null || getEdgeOrPosition(entry).equals(pEdge))
&& (pCacheEntryClass == null || entry.getValue().getClass().equals(pCacheValueClass))) {
toBeRemoved.add(entry);
}
}
cacheEntries.removeAll(toBeRemoved);
}
public Object getEdgeOrPosition(PointInformation information) {
if (information.hasAttribute(AvailableInformationAttributes.EDGE)) {
return information
......@@ -188,13 +414,12 @@ implements CachingComponent, ConnectivityListener {
}
}
public CacheDecisionStrategy getDecisionStrategy() {
return _decisionStrategy;
}
@Override
public String getNodeDescription() {
return " " + getHost().getId();
if (getHost().getId().value() > 47) {
return " " + getHost().getId();
}
return "";
}
@Override
......
......@@ -21,14 +21,25 @@
package de.tud.kom.p2psim.impl.vehicular.caching.decision;
import java.util.List;
import java.util.Map;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.environment.data.NumericVectoralProperty;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.environment.data.jam.VectoralJamProperty;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.environment.data.properties.vectoral.NumericVectoralProperty;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.environment.data.properties.vectoral.VectoralJamProperty;
import de.tudarmstadt.maki.simonstrator.api.component.transition.TransferState;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.caching.decision.AbstractCacheDecisionStrategy;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.caching.decision.CacheDecisionStrategy;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.caching.decision.CacheDecisionStrategyParameters;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.information.PointInformation;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.information.RoadInformation;
public class AveragingCacheDecisionStrategy implements CacheDecisionStrategy {
public class AveragingCacheDecisionStrategy extends AbstractCacheDecisionStrategy implements CacheDecisionStrategy {
private Map<CacheDecisionStrategyParameters, String> _params;
@TransferState(value = { "Params" })
public AveragingCacheDecisionStrategy(Map<CacheDecisionStrategyParameters, String> pParams) {
_params = pParams;
}
@Override
public <T extends PointInformation> T decideOnCorrectInformation(
......@@ -39,33 +50,43 @@ public class AveragingCacheDecisionStrategy implements CacheDecisionStrategy {
} else if (pSimilarPointInformation.size() == 0) {
return null;
}
double sum = 0;
double count = 0;
NumericVectoralProperty cloned = null;
for (T t : pSimilarPointInformation) {
RoadInformation roadInformation = ((RoadInformation) t);
NumericVectoralProperty property = (NumericVectoralProperty) roadInformation.getValue();
if (cloned == null) {
cloned = property.clone();
}
sum += property.getMostProbableValue();
count++;
}
double value = sum / count;
if (cloned instanceof VectoralJamProperty) {
((VectoralJamProperty) cloned).setSpeed(((int)(value / VectoralJamProperty.SCALING)) * VectoralJamProperty.SCALING);
} else {
throw new AssertionError("Unknown data type " + cloned.getClass().getSimpleName());
}
return (T) new RoadInformation(cloned);
RoadInformation aggregate = new RoadInformation(cloned);
addAggregationInformation(pSimilarPointInformation, aggregate);
return (T) aggregate;
}
public Map<CacheDecisionStrategyParameters, String> getParams() {
return _params;
}
@Override
public AveragingCacheDecisionStrategy clone() {
return new AveragingCacheDecisionStrategy(_params);
}
}
......@@ -26,12 +26,13 @@ import java.util.HashMap;
import java.util.Map;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.caching.decision.CacheDecisionStrategy;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.caching.decision.CacheDecisionStrategyParameters;
public enum CacheDecisionStrategyType {
DEFAULT(NewestCacheDecisionStrategy.class), NEWEST(NewestCacheDecisionStrategy.class), MAJORITY(MajorityVotingCacheDecisionStrategy.class), AVERAGING(AveragingCacheDecisionStrategy.class), TTL(TTLbasedCacheDecisionStrategy.class), OPTIMAL(OptimalCacheDecisionStrategy.class), RANDOM(RandomCacheDecisionStrategy.class), TTL_VECTOR(TTLbasedVectoralCacheDecisionStrategy.class), MAJORITY_VECTOR(MajorityVotingVectoralCacheDecisionStrategy.class);
private final Class<? extends CacheDecisionStrategy> decisionStrategy;
private final Map<String, String> params = new HashMap<>();
private final Map<CacheDecisionStrategyParameters, String> params = new HashMap<>();
private CacheDecisionStrategyType(final Class<? extends CacheDecisionStrategy> decisionStrategy) {
this.decisionStrategy = decisionStrategy;
......@@ -50,7 +51,7 @@ public enum CacheDecisionStrategyType {
}
}
public void addAttribute(String pKey, String pValue) {
params.put(pKey, pValue);
public void addAttribute(CacheDecisionStrategyParameters pParam, String pValue) {
params.put(pParam, pValue);
}
}
......@@ -25,21 +25,37 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.environment.data.properties.vectoral.VectoralProperty;
import de.tudarmstadt.maki.simonstrator.api.component.transition.TransferState;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.caching.decision.AbstractCacheDecisionStrategy;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.caching.decision.CacheDecisionStrategy;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.caching.decision.CacheDecisionStrategyParameters;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.information.PointInformation;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.information.RoadInformation;
public class MajorityVotingCacheDecisionStrategy implements CacheDecisionStrategy {
public class MajorityVotingCacheDecisionStrategy extends AbstractCacheDecisionStrategy implements CacheDecisionStrategy {
private Map<CacheDecisionStrategyParameters, String> _params;
@TransferState(value = { "Params" })
public MajorityVotingCacheDecisionStrategy(Map<CacheDecisionStrategyParameters, String> pParams) {
_params = pParams;
}
@Override
public <T extends PointInformation> T decideOnCorrectInformation(
List<T> pSimilarPointInformation) {
Map<Object, Integer> voting = new HashMap<>();
for (T t : pSimilarPointInformation) {
if (!voting.containsKey(t.getValue())) {
voting.put(t.getValue(), 0);
Object value = t.getValue();
if (value instanceof VectoralProperty) {
value = ((VectoralProperty) value).getMostProbableValue();
}
if (!voting.containsKey(value)) {
voting.put(value, 0);
}
voting.put(t.getValue(), voting.get(t.getValue()) + 1);
voting.put(value, voting.get(value) + 1);
}
Entry<Object, Integer> maxEntry = null;
......@@ -58,13 +74,23 @@ public class MajorityVotingCacheDecisionStrategy implements CacheDecisionStrateg
for (T t : pSimilarPointInformation) {
long timestamp = t.getDetectionDate();
if (t.getValue().equals(maxEntry.getKey()) && timestamp > maxTimestamp) {
if ((t.getValue().equals(maxEntry.getKey()) || t.getValue() instanceof VectoralProperty && ((VectoralProperty)t.getValue()).getMostProbableValue().equals(maxEntry.getKey())) && timestamp > maxTimestamp) {
maxTimestamp = timestamp;
maxFitting = t;
}
}
addAggregationInformation(pSimilarPointInformation, maxFitting);
return maxFitting;
}
public Map<CacheDecisionStrategyParameters, String> getParams() {
return _params;
}
@Override
public MajorityVotingCacheDecisionStrategy clone() {
return new MajorityVotingCacheDecisionStrategy(_params);
}
}
......@@ -21,23 +21,34 @@
package de.tud.kom.p2psim.impl.vehicular.caching.decision;
import java.util.List;
import java.util.Map;
import de.tudarmstadt.maki.simonstrator.api.Time;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.environment.data.TemporalDependencyMatrix;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.environment.data.VectoralProperty;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.environment.data.properties.vectoral.VectoralProperty;
import de.tudarmstadt.maki.simonstrator.api.component.transition.TransferState;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.caching.decision.AbstractCacheDecisionStrategy;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.caching.decision.CacheDecisionStrategy;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.caching.decision.CacheDecisionStrategyParameters;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.information.AvailableInformationAttributes;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.information.PointInformation;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.information.RoadInformation;
public class MajorityVotingVectoralCacheDecisionStrategy implements CacheDecisionStrategy {
public class MajorityVotingVectoralCacheDecisionStrategy extends AbstractCacheDecisionStrategy implements CacheDecisionStrategy {
private static final long SCALING = Time.SECOND;
private Map<CacheDecisionStrategyParameters, String> _params;
@TransferState(value = { "Params" })
public MajorityVotingVectoralCacheDecisionStrategy(Map<CacheDecisionStrategyParameters, String> pParams) {
_params = pParams;
}
@Override
public <T extends PointInformation> T decideOnCorrectInformation(
List<T> pSimilarPointInformation) {
VectoralProperty currentProperty = null;
long minTimestamp = Long.MAX_VALUE;
long maxTimestamp = 0;
for (T t : pSimilarPointInformation) {
......@@ -50,14 +61,14 @@ public class MajorityVotingVectoralCacheDecisionStrategy implements CacheDecisio
maxTimestamp = timestamp;
}
}
for (T t : pSimilarPointInformation) {
RoadInformation roadInformation = ((RoadInformation) t);
VectoralProperty property = (VectoralProperty) roadInformation.getValue();
TemporalDependencyMatrix dependencyMatrix = property.getDependencyMatrix();
VectoralProperty agedProperty = property.age((maxTimestamp - property.getDetectionDate()) / SCALING, dependencyMatrix);
if (currentProperty != null) {
currentProperty = currentProperty.combine(agedProperty);
......@@ -65,15 +76,16 @@ public class MajorityVotingVectoralCacheDecisionStrategy implements CacheDecisio
currentProperty = agedProperty;
}
}
TemporalDependencyMatrix dependencyMatrix = currentProperty.getDependencyMatrix();
VectoralProperty agedProperty = currentProperty.age((Time.getCurrentTime() - maxTimestamp) / SCALING, dependencyMatrix);
RoadInformation roadInformation = new RoadInformation(agedProperty);
// TemporalDependencyMatrix dependencyMatrix = currentProperty.getDependencyMatrix();
//
// VectoralProperty agedProperty = currentProperty.age((Time.getCurrentTime() - maxTimestamp) / SCALING, dependencyMatrix);
RoadInformation roadInformation = new RoadInformation(currentProperty);
copyAttributes((RoadInformation) pSimilarPointInformation.get(0), roadInformation);
addAggregationInformation(pSimilarPointInformation, roadInformation);
return (T) roadInformation;
}
......@@ -87,4 +99,13 @@ public class MajorityVotingVectoralCacheDecisionStrategy implements CacheDecisio
}
}
public Map<CacheDecisionStrategyParameters, String> getParams() {
return _params;
}
@Override
public MajorityVotingVectoralCacheDecisionStrategy clone() {
return new MajorityVotingVectoralCacheDecisionStrategy(_params);
}
}
......@@ -21,11 +21,22 @@
package de.tud.kom.p2psim.impl.vehicular.caching.decision;
import java.util.List;
import java.util.Map;
import de.tudarmstadt.maki.simonstrator.api.component.transition.TransferState;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.caching.decision.AbstractCacheDecisionStrategy;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.caching.decision.CacheDecisionStrategy;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.caching.decision.CacheDecisionStrategyParameters;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.information.PointInformation;
public class NewestCacheDecisionStrategy implements CacheDecisionStrategy {
public class NewestCacheDecisionStrategy extends AbstractCacheDecisionStrategy implements CacheDecisionStrategy {
private Map<CacheDecisionStrategyParameters, String> _params;
@TransferState(value = { "Params" })
public NewestCacheDecisionStrategy(Map<CacheDecisionStrategyParameters, String> pParams) {
_params = pParams;
}
@Override
public <T extends PointInformation> T decideOnCorrectInformation(
......@@ -41,4 +52,13 @@ public class NewestCacheDecisionStrategy implements CacheDecisionStrategy {
return chosenInformation;
}
public Map<CacheDecisionStrategyParameters, String> getParams() {
return _params;
}
@Override
public NewestCacheDecisionStrategy clone() {
return new NewestCacheDecisionStrategy(_params);
}
}
......@@ -21,17 +21,26 @@
package de.tud.kom.p2psim.impl.vehicular.caching.decision;
import java.util.List;
import java.util.Map;
import de.tudarmstadt.maki.simonstrator.api.Time;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.environment.data.VectoralProperty;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.environment.data.jam.JamProperty;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.environment.data.properties.JamProperty;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.environment.data.properties.vectoral.VectoralProperty;
import de.tudarmstadt.maki.simonstrator.api.component.transition.TransferState;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.caching.decision.AbstractCacheDecisionStrategy;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.caching.decision.CacheDecisionStrategy;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.caching.decision.CacheDecisionStrategyParameters;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.information.AvailableInformationAttributes;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.information.PointInformation;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.RoadNetworkEdge;
public class OptimalCacheDecisionStrategy implements CacheDecisionStrategy {
public OptimalCacheDecisionStrategy() {
public class OptimalCacheDecisionStrategy extends AbstractCacheDecisionStrategy implements CacheDecisionStrategy {
private Map<CacheDecisionStrategyParameters, String> _params;
@TransferState(value = { "Params" })
public OptimalCacheDecisionStrategy(Map<CacheDecisionStrategyParameters, String> pParams) {
_params = pParams;
}
@Override
......@@ -43,11 +52,11 @@ public class OptimalCacheDecisionStrategy implements CacheDecisionStrategy {
} else if (pSimilarPointInformation.size() == 0) {
return null;
}
RoadNetworkEdge edge = (RoadNetworkEdge) pSimilarPointInformation.get(0).getAttribute(AvailableInformationAttributes.EDGE);
double actualSpeed = edge.getCurrentSpeed();
JamProperty jamProperty = edge.getJamProperty();
long maxTimestamp;
......@@ -66,7 +75,7 @@ public class OptimalCacheDecisionStrategy implements CacheDecisionStrategy {
if (currentValue instanceof VectoralProperty) {
currentValue = ((VectoralProperty) currentValue).getMostProbableValue();
}
if (timestamp >= maxTimestamp) {
if (currentValue.equals(actualSpeed)) {
maxFitting = t;
......@@ -93,4 +102,14 @@ public class OptimalCacheDecisionStrategy implements CacheDecisionStrategy {
return maxFitting;
}
public Map<CacheDecisionStrategyParameters, String> getParams() {
return _params;
}
@Override
public OptimalCacheDecisionStrategy clone() {
return new OptimalCacheDecisionStrategy(_params);
}
}
......@@ -21,16 +21,24 @@
package de.tud.kom.p2psim.impl.vehicular.caching.decision;
import java.util.List;
import java.util.Map;
import java.util.Random;
import de.tudarmstadt.maki.simonstrator.api.Randoms;
import de.tudarmstadt.maki.simonstrator.api.component.transition.TransferState;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.caching.decision.AbstractCacheDecisionStrategy;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.caching.decision.CacheDecisionStrategy;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.caching.decision.CacheDecisionStrategyParameters;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.information.PointInformation;
public class RandomCacheDecisionStrategy implements CacheDecisionStrategy {
public class RandomCacheDecisionStrategy extends AbstractCacheDecisionStrategy implements CacheDecisionStrategy {
private Random _random = Randoms.getRandom(getClass());
public RandomCacheDecisionStrategy() {
private Map<CacheDecisionStrategyParameters, String> _params;
@TransferState(value = { "Params" })
public RandomCacheDecisionStrategy(Map<CacheDecisionStrategyParameters, String> pParams) {
_params = pParams;
}
@Override
......@@ -45,4 +53,14 @@ public class RandomCacheDecisionStrategy implements CacheDecisionStrategy {
return pSimilarPointInformation.get(_random.nextInt(pSimilarPointInformation.size()));
}
public Map<CacheDecisionStrategyParameters, String> getParams() {
return _params;
}
@Override
public RandomCacheDecisionStrategy clone() {
return new RandomCacheDecisionStrategy(_params);
}
}
......@@ -29,19 +29,26 @@ import java.util.Map;
import java.util.Map.Entry;
import de.tudarmstadt.maki.simonstrator.api.Time;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.environment.data.RoadProperty;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.environment.data.VectoralProperty;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.environment.data.jam.VectoralJamProperty;
import de.tudarmstadt.maki.simonstrator.api.component.relevance.vehicular.impl.SimpleQoIBasedImpactFunction;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.environment.data.properties.RoadProperty;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.environment.data.properties.vectoral.VectoralJamProperty;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.environment.data.properties.vectoral.VectoralProperty;
import de.tudarmstadt.maki.simonstrator.api.component.transition.TransferState;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.caching.decision.AbstractCacheDecisionStrategy;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.caching.decision.CacheDecisionStrategy;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.caching.decision.CacheDecisionStrategyParameters;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.caching.decision.CacheSizeAwareCacheDecisionStrategy;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.information.AvailableInformationAttributes;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.information.PointInformation;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.information.RoadInformation;
public class TTLbasedCacheDecisionStrategy implements CacheDecisionStrategy {
public class TTLbasedCacheDecisionStrategy extends AbstractCacheDecisionStrategy implements CacheSizeAwareCacheDecisionStrategy {
private static final long SCALING = Time.SECOND;
private static final double ACCURACY_FACTOR = 100000;
private final Map<CacheDecisionStrategyParameters, String> _params;
private long ttl = 300 * Time.SECOND / SCALING;
private double accuracy = 1;
......@@ -50,13 +57,17 @@ public class TTLbasedCacheDecisionStrategy implements CacheDecisionStrategy {
private Object _lastDecision = false;
public TTLbasedCacheDecisionStrategy(Map<String, String> pParams) {
for (Entry<String, String> param : pParams.entrySet()) {
private int _maxCacheSize = Integer.MAX_VALUE;
@TransferState(value = { "Params" })
public TTLbasedCacheDecisionStrategy(Map<CacheDecisionStrategyParameters, String> pParams) {
_params = pParams;
for (Entry<CacheDecisionStrategyParameters, String> param : pParams.entrySet()) {
switch (param.getKey()) {
case "ACCURACY":
case ACCURACY:
accuracy = Double.valueOf(param.getValue());
break;
case "COST_RATIO":
case COST_RATIO:
double ratio = Double.valueOf(param.getValue());
costWrongChange = 2 / (ratio + 1);
costWrongKeep = 2 - costWrongChange;
......@@ -80,283 +91,118 @@ public class TTLbasedCacheDecisionStrategy implements CacheDecisionStrategy {
List<T> pSimilarPointInformation) {
if (pSimilarPointInformation.size() == 1) {
T decision = pSimilarPointInformation.get(0);
addAggregationInformation(pSimilarPointInformation, decision);
_lastDecision = decision.getValue();
return decision;
} else if (pSimilarPointInformation.size() == 0) {
return null;
}
Collections.sort(pSimilarPointInformation, new Comparator<T>() {
@Override
public int compare(T pArg0, T pArg1) {
return Long.compare(pArg0.getDetectionDate(), pArg1.getDetectionDate());
}
});
long minTimestamp = Long.MAX_VALUE;
long maxTimestamp = 0;
Object value = pSimilarPointInformation.get(0).getValue();
boolean differentValue = false;
for (T t : pSimilarPointInformation) {
if (!t.hasAttribute(AvailableInformationAttributes.TTL)) {
throw new AssertionError("Unable to perform TTL-based majority voting witout TTL");
}
long timestamp = t.getDetectionDate();
if (timestamp < minTimestamp) {
minTimestamp = timestamp;
}
if (timestamp > maxTimestamp) {
maxTimestamp = timestamp;
}
if (!value.equals(t.getValue())) {
differentValue = true;
}
}
if (differentValue) {
long difference = maxTimestamp - minTimestamp;
if (difference == 0) {
return pSimilarPointInformation.get(pSimilarPointInformation.size() - 1);
}
double rate = difference / ((double) (pSimilarPointInformation.size() - 1) * SCALING);
SimpleQoIBasedImpactFunction<T> impactFunction = new SimpleQoIBasedImpactFunction<>(pSimilarPointInformation, accuracy, _maxCacheSize);
long ttl = (long)pSimilarPointInformation.get(0).getAttribute(AvailableInformationAttributes.TTL) / SCALING;
rate = Math.min(rate, ttl / 10.0);
Map<Object, Double> weight = new HashMap<>();
double b;
if (Boolean.FALSE.equals(_lastDecision)) {
b = determineB(rate, 1 - accuracy, ttl, costWrongKeep, costWrongChange);
} else {
b = determineB(rate, 1 - accuracy, ttl, costWrongChange, costWrongKeep);
}
Map<Object, Double> weight = new HashMap<>();
for (T t : pSimilarPointInformation) {
double impact = calculateImpact(1 - accuracy, ttl, t.getDetectionDate() / SCALING, b, maxTimestamp / SCALING);
double sumImpact = 0;
Object currentValue = t.getValue();
if (currentValue instanceof VectoralJamProperty) {
currentValue = ((VectoralJamProperty) currentValue).getMostProbableValue();
}
if (weight.containsKey(currentValue)) {
sumImpact = weight.get(currentValue);
}
sumImpact += impact;
for (T t : pSimilarPointInformation) {
double impact = impactFunction.calculateImpact(t);
weight.put(currentValue, sumImpact);
}
double sumImpact = 0;
double maxWeight = -1;
Object maxValue = null;
Object currentValue = t.getValue();
for (Object key : weight.keySet()) {
if (weight.get(key) > maxWeight) {
maxWeight = weight.get(key);
maxValue = key;
}
if (currentValue instanceof VectoralJamProperty) {
currentValue = ((VectoralJamProperty) currentValue).getMostProbableValue();
}
maxTimestamp = -1;
T maxFitting = null;
for (T t : pSimilarPointInformation) {
long timestamp = t.getDetectionDate();
Object currentValue = t.getValue();
if (currentValue instanceof VectoralProperty) {
currentValue = ((VectoralProperty)currentValue).getMostProbableValue();
}
if (currentValue.equals(maxValue) && timestamp > maxTimestamp) {
maxTimestamp = timestamp;
maxFitting = t;
}
}
if (maxFitting.getValue() instanceof VectoralProperty) {
VectoralProperty vectoralProperty = ((VectoralProperty)maxFitting.getValue()).clone();
double[] valueProbabilities = vectoralProperty.getValueProbabilities();
Arrays.fill(valueProbabilities, 0);
double sum = 0;
for (Object key : weight.keySet()) {
valueProbabilities[vectoralProperty.getIndexForValue(key)] = weight.get(key);
sum += weight.get(key);
}
for (int i = 0; i < valueProbabilities.length; i++) {
valueProbabilities[i] /= sum;
}
RoadInformation roadInformation = new RoadInformation(vectoralProperty);
roadInformation.copyAttributes((RoadInformation)maxFitting);
maxFitting = (T) roadInformation;
if (weight.containsKey(currentValue)) {
sumImpact = weight.get(currentValue);
}
sumImpact += impact;
_lastDecision = maxFitting.getValue();
weight.put(currentValue, sumImpact);
}
return maxFitting;
} else {
maxTimestamp = -1;
T maxFitting = null;
for (T t : pSimilarPointInformation) {
long timestamp = (long) t.getAttribute(AvailableInformationAttributes.TTL);
double maxWeight = -1;
Object maxValue = null;
if (timestamp > maxTimestamp) {
maxTimestamp = timestamp;
maxFitting = t;
}
for (Object key : weight.keySet()) {
if (weight.get(key) > maxWeight) {
maxWeight = weight.get(key);
maxValue = key;
}
_lastDecision = maxFitting.getValue();
return maxFitting;
}
}
public double calculateImpact(double errorProbability, long ttl, long time, double b, long maxTimestamp) {
long age = maxTimestamp - time;
if (errorProbability == 0) {
if (time == maxTimestamp) {
return 1;
} else {
return 0;
}
} else if (errorProbability == 1) {
return 1;
} else if (errorProbability == 0.5) {
return (errorProbability - 1) / ttl * age + errorProbability;
} else if (b == Double.NEGATIVE_INFINITY) {
if (time == maxTimestamp) {
return 1;
} else {
return 0;
}
}
return (1 - errorProbability) * (Math.exp(b * age) - Math.exp(b * ttl)) / (1 - Math.exp(b * ttl));
}
public double getChangeProbability(long ttl) {
return 1 - Math.pow(0.5, 1 / (double) ttl);
}
public int getOptimalMessageAmountForSwitch(double changeProbability, double errorProbability, double costSlow, double costFast) {
return (int) Math.round(Math.log(-changeProbability / Math.log(errorProbability) * costSlow / costFast) / Math.log(errorProbability));
}
long maxTimestamp = -1;
T maxFitting = null;
for (T t : pSimilarPointInformation) {
long timestamp = t.getDetectionDate();
public double determineB(double rate, double errorProbability, long ttl, double costSlow, double costFast) {
return determineB(rate, errorProbability, ttl, costSlow, costFast, 1);
}
Object currentValue = t.getValue();
if (currentValue instanceof VectoralProperty) {
currentValue = ((VectoralProperty)currentValue).getMostProbableValue();
}
public double determineB(double rate, double errorProbability, long ttl, double costSlow, double costFast, int reversed) {
if (errorProbability == 0 || errorProbability == 1 || errorProbability == 0.5) {
return Double.NaN;
if (currentValue.equals(maxValue) && timestamp > maxTimestamp) {
maxTimestamp = timestamp;
maxFitting = t;
}
}
double b;
double p_c = getChangeProbability((long) (ttl / rate));
int optimalAmount = getOptimalMessageAmountForSwitch(p_c, errorProbability, costSlow, costFast);
if (maxFitting.getValue() instanceof VectoralProperty) {
VectoralProperty vectoralProperty = ((VectoralProperty)maxFitting.getValue()).clone();
double[] valueProbabilities = vectoralProperty.getValueProbabilities();
Arrays.fill(valueProbabilities, 0);
if (optimalAmount == 1) {
return Double.NEGATIVE_INFINITY;
}
boolean first = true;
double leftSide;
double rightSide;
double sum = 0;
for (Object key : weight.keySet()) {
valueProbabilities[vectoralProperty.getIndexForValue(key)] = weight.get(key);
sum += weight.get(key);
}
double step = 5;
for (int i = 0; i < valueProbabilities.length; i++) {
valueProbabilities[i] /= sum;
}
if (errorProbability < 0.5) {
b = -2 * step * reversed;
} else {
b = 2 * step * reversed;
RoadInformation roadInformation = new RoadInformation(vectoralProperty);
roadInformation.copyAttributes((RoadInformation)maxFitting);
maxFitting = (T) roadInformation;
}
int similar = 0;
double lastDifference = -1;
do {
leftSide = calculateWeightingForOldState(optimalAmount, rate, errorProbability, ttl, b);
rightSide = calculateWeightingForNewState(optimalAmount, rate, errorProbability, ttl, b);
if (Math.abs(Math.round((rightSide - leftSide) * ACCURACY_FACTOR)) == lastDifference) {
similar++;
} else {
lastDifference = Math.abs(Math.round((rightSide - leftSide) * ACCURACY_FACTOR));
similar = 0;
}
_lastDecision = maxFitting.getValue();
if (Double.isNaN(leftSide) || Double.isNaN(rightSide) || similar > 100) {
if (reversed != -1) {
double determineB = determineB(rate, errorProbability, ttl, costSlow, costFast, -1);
if (!Double.isNaN(determineB)) {
return determineB;
} else {
return b;
}
} else {
return Double.NaN;
}
}
addAggregationInformation(pSimilarPointInformation, maxFitting);
leftSide = Math.round(leftSide * ACCURACY_FACTOR);
rightSide = Math.round(rightSide * ACCURACY_FACTOR);
if (leftSide > rightSide) {
if (b < 0) {
b -= step;
if (!first) {
step *= 0.5;
}
} else {
b -= step;
step *= 0.5;
first = false;
}
} else if (leftSide < rightSide) {
if (b > 0) {
b += step;
if (!first) {
step *= 0.5;
}
} else {
b += step;
step *= 0.5;
first = false;
}
} else {
break;
}
} while (true);
return maxFitting;
}
return b;
public Map<CacheDecisionStrategyParameters, String> getParams() {
return _params;
}
public double calculateWeightingForOldState(int optimalMessageAmount, double rate, double errorProbability, long ttl, double b) {
double impact = 0;
for (int a = optimalMessageAmount; a < Math.max(Math.floor(ttl / rate), optimalMessageAmount + 2); a++) {
impact += calculateImpact(errorProbability, ttl, Time.getCurrentTime() / SCALING - (long)Math.floor(a * rate), b, Time.getCurrentTime() / SCALING);
}
return impact;
@Override
public void setCacheSize(int pCacheSize) {
_maxCacheSize = pCacheSize;
}
public double calculateWeightingForNewState(int optimalMessageAmount, double rate, double errorProbability, long ttl, double b) {
double impact = 0;
for (int a = 0; a < optimalMessageAmount; a++) {
impact += calculateImpact(errorProbability, ttl, Time.getCurrentTime() / SCALING - (long)Math.floor(a * rate), b, Time.getCurrentTime() / SCALING);
}
return impact;
@Override
public TTLbasedCacheDecisionStrategy clone() {
return new TTLbasedCacheDecisionStrategy(_params);
}
}
......@@ -21,7 +21,6 @@
package de.tud.kom.p2psim.impl.vehicular.caching.decision;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
......@@ -29,36 +28,46 @@ import java.util.Map;
import java.util.Map.Entry;
import de.tudarmstadt.maki.simonstrator.api.Time;
import de.tudarmstadt.maki.simonstrator.api.component.relevance.vehicular.impl.VectoralQoIBasedImpactFunction;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.environment.data.TemporalDependencyMatrix;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.environment.data.VectoralProperty;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.environment.data.measurement.MeasurementDistributionTypeContainer;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.environment.data.aggregation.AggregationInformation;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.environment.data.properties.RoadProperty;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.environment.data.properties.vectoral.VectoralProperty;
import de.tudarmstadt.maki.simonstrator.api.component.transition.MechanismState;
import de.tudarmstadt.maki.simonstrator.api.component.transition.TransferState;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.caching.decision.AbstractCacheDecisionStrategy;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.caching.decision.CacheDecisionStrategy;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.caching.decision.CacheDecisionStrategyParameters;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.caching.decision.CacheSizeAwareCacheDecisionStrategy;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.information.AggregatedInformation;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.information.AvailableInformationAttributes;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.information.PointInformation;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.information.RoadInformation;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.RoadNetworkEdge;
public class TTLbasedVectoralCacheDecisionStrategy implements CacheDecisionStrategy {
public class TTLbasedVectoralCacheDecisionStrategy extends AbstractCacheDecisionStrategy implements CacheSizeAwareCacheDecisionStrategy {
private static final long SCALING = Time.SECOND;
private static final double ACCURACY_FACTOR = 100000;
private static final double MIN_STEP = 0.00001;
private final Map<CacheDecisionStrategyParameters, String> _params;
private double accuracy = 1;
private double costWrongKeep = 1;
private double costWrongChange = 1;
private int cacheSize = Integer.MAX_VALUE;
private Object _lastDecision = null;
public TTLbasedVectoralCacheDecisionStrategy(Map<String, String> pParams) {
for (Entry<String, String> param : pParams.entrySet()) {
@TransferState(value = { "Params" })
public TTLbasedVectoralCacheDecisionStrategy(Map<CacheDecisionStrategyParameters, String> pParams) {
_params = pParams;
for (Entry<CacheDecisionStrategyParameters, String> param : pParams.entrySet()) {
switch (param.getKey()) {
case "ACCURACY":
case ACCURACY:
accuracy = Double.valueOf(param.getValue());
break;
case "COST_RATIO":
case COST_RATIO:
double ratio = Double.valueOf(param.getValue());
costWrongChange = 2 / (ratio + 1);
costWrongKeep = 2 - costWrongChange;
......@@ -82,19 +91,21 @@ public class TTLbasedVectoralCacheDecisionStrategy implements CacheDecisionStrat
List<T> pSimilarPointInformation) {
if (pSimilarPointInformation.size() == 1) {
T decision = pSimilarPointInformation.get(0);
addAggregationInformation(pSimilarPointInformation, decision);
_lastDecision = decision.getValue();
return decision;
} else if (pSimilarPointInformation.size() == 0) {
return null;
}
Collections.sort(pSimilarPointInformation, new Comparator<T>() {
@Override
public int compare(T pArg0, T pArg1) {
return Long.compare(pArg0.getDetectionDate(), pArg1.getDetectionDate());
}
});
long minTimestamp = Long.MAX_VALUE;
......@@ -103,151 +114,92 @@ public class TTLbasedVectoralCacheDecisionStrategy implements CacheDecisionStrat
if (value instanceof VectoralProperty) {
value = ((VectoralProperty) value).getMostProbableIndex();
}
boolean differentValue = false;
List<Integer> possibleValues = new ArrayList<>();
for (T t : pSimilarPointInformation) {
if (!t.hasAttribute(AvailableInformationAttributes.TTL)) {
throw new AssertionError("Unable to perform TTL-based majority voting witout TTL");
}
long timestamp = t.getDetectionDate();
boolean differentValue = true;
if (timestamp < minTimestamp) {
minTimestamp = timestamp;
}
if (timestamp > maxTimestamp) {
maxTimestamp = timestamp;
}
Object currentValue = t.getValue();
if (currentValue instanceof VectoralProperty) {
VectoralProperty currentProperty = (VectoralProperty) currentValue;
currentValue = currentProperty.getMostProbableIndex();
if (!value.equals(currentValue)) {
differentValue = true;
}
for (int i = 0; i < currentProperty.getValueProbabilities().length; i++) {
if (!possibleValues.contains(i)) {
possibleValues.add(i);
}
}
}
}
if (differentValue) {
long difference = maxTimestamp - minTimestamp;
List<Integer> possibleValues = new ArrayList<>();
if (difference == 0) {
return pSimilarPointInformation.get(pSimilarPointInformation.size() - 1);
}
for (T t : pSimilarPointInformation) {
if (!t.hasAttribute(AvailableInformationAttributes.TTL)) {
throw new AssertionError("Unable to perform TTL-based majority voting witout TTL");
}
long timestamp = t.getDetectionDate();
double rate = difference / ((double) (pSimilarPointInformation.size() - 1) * SCALING);
if (timestamp < minTimestamp) {
minTimestamp = timestamp;
}
if (timestamp > maxTimestamp) {
maxTimestamp = timestamp;
}
long ttl = getTTL(pSimilarPointInformation.get(0));
double numberOfMessages = ttl / rate + 1;
Object currentValue = t.getValue();
if (currentValue instanceof VectoralProperty) {
VectoralProperty currentProperty = (VectoralProperty) currentValue;
currentValue = currentProperty.getMostProbableIndex();
VectoralProperty currentProperty = null;
if (!value.equals(currentValue)) {
differentValue = true;
}
List<Double> bValues = new ArrayList<>();
double b;
for (Integer possibleValue : possibleValues) {
double temp = determineB((VectoralProperty) pSimilarPointInformation.get(0).getValue(), ((RoadInformation)pSimilarPointInformation.get(0)).getEdge(), possibleValue, getChangeRate(pSimilarPointInformation.get(0), rate), rate, 1 - accuracy, numberOfMessages, costWrongKeep, costWrongChange);
if (!Double.isNaN(temp)) {
bValues.add(temp);
for (int i = 0; i < currentProperty.getValueProbabilities().length; i++) {
if (!possibleValues.contains(i)) {
possibleValues.add(i);
}
}
}
}
Collections.sort(bValues);
if (bValues.size() > 0) {
if (bValues.size() % 2 == 0) {
b = (bValues.get(bValues.size() / 2) + bValues.get(bValues.size() / 2 - 1)) / 2.0;
} else {
b = bValues.get(bValues.size() / 2);
if (t instanceof AggregatedInformation) {
AggregationInformation aggregationInformation = ((AggregatedInformation)t).getAggregationInformation();
if (aggregationInformation != null && aggregationInformation.getMinTimestamp() < minTimestamp) {
minTimestamp = aggregationInformation.getMinTimestamp();
}
}
} else {
b = Double.NEGATIVE_INFINITY;
}
int count = 0;
VectoralProperty currentProperty = null;
VectoralQoIBasedImpactFunction<T> impactFunction = new VectoralQoIBasedImpactFunction<>(pSimilarPointInformation, accuracy, cacheSize, _lastDecision);
for (T t : pSimilarPointInformation) {
RoadInformation roadInformation = ((RoadInformation) t);
VectoralProperty property = (VectoralProperty) roadInformation.getValue();
double impact = calculateImpact(1 - accuracy, numberOfMessages, (((t.getDetectionDate() - maxTimestamp) / SCALING + ttl) / (double)ttl) * numberOfMessages, b) / (accuracy);
double impact = impactFunction.calculateImpact(t);
TemporalDependencyMatrix dependencyMatrix = property.getDependencyMatrix();
dependencyMatrix = modifyDependencyMatrix(dependencyMatrix.age((maxTimestamp - property.getDetectionDate()) / SCALING), impact);
VectoralProperty agedProperty = property.age(1, dependencyMatrix);
VectoralProperty agedProperty = property.age(1, dependencyMatrix);
if (currentProperty != null) {
currentProperty = currentProperty.combine(agedProperty);
} else {
currentProperty = agedProperty;
}
}
if (Double.isNaN(currentProperty.getValueProbabilities()[0])) {
return pSimilarPointInformation.get(pSimilarPointInformation.size() - 1);
}
RoadInformation roadInformation = new RoadInformation(currentProperty);
copyAttributes((RoadInformation) pSimilarPointInformation.get(0), roadInformation);
copyAttributes((RoadInformation) pSimilarPointInformation.get(pSimilarPointInformation.size() - 1), roadInformation);
addAggregationInformation(pSimilarPointInformation, roadInformation);
_lastDecision = roadInformation.getValue();
return (T) roadInformation;
} else {
maxTimestamp = -1;
T maxFitting = null;
for (T t : pSimilarPointInformation) {
long timestamp = (long) t.getAttribute(AvailableInformationAttributes.TTL);
if (timestamp > maxTimestamp) {
maxTimestamp = timestamp;
maxFitting = t;
}
}
RoadProperty currentProperty = (RoadProperty) pSimilarPointInformation.get(pSimilarPointInformation.size() - 1).getValue();
_lastDecision = maxFitting.getValue();
RoadInformation roadInformation = new RoadInformation(currentProperty );
return maxFitting;
}
}
copyAttributes((RoadInformation) pSimilarPointInformation.get(pSimilarPointInformation.size() - 1), roadInformation);
addAggregationInformation(pSimilarPointInformation, roadInformation);
/**
* @param pT
* @return
*/
private <T extends PointInformation> double getAccuracy(T pT) {
// if (pT instanceof RoadInformation) {
// RoadInformation roadInformation = ((RoadInformation) pT);
// VectoralProperty property = (VectoralProperty) roadInformation.getValue();
// double accuracy = property.getProbabilityForIndex(property.getMostProbableIndex());
// return accuracy;
// }
return this.accuracy;
}
private <T extends PointInformation> double getChangeRate(T pT, double pRate) {
// if (pT instanceof RoadInformation) {
// RoadInformation roadInformation = ((RoadInformation) pT);
// VectoralProperty property = (VectoralProperty) roadInformation.getValue();
//
// TemporalDependencyMatrix dependencyMatrix = property.getDependencyMatrix();
// return 1 - Math.pow(1 - dependencyMatrix.getChangeProbability(0), pRate * (SCALING / Time.SECOND));
// }
return getChangeProbability((long) (getTTL(pT) / pRate));
}
_lastDecision = roadInformation.getValue();
public <T extends PointInformation> long getTTL(
T pT) {
return (long)pT.getAttribute(AvailableInformationAttributes.TTL) / SCALING;
return (T) roadInformation;
}
}
/**
......@@ -263,187 +215,31 @@ public class TTLbasedVectoralCacheDecisionStrategy implements CacheDecisionStrat
private TemporalDependencyMatrix modifyDependencyMatrix(
TemporalDependencyMatrix pDependencyMatrix, double pImpact) {
TemporalDependencyMatrix result = pDependencyMatrix.clone();
double[][] dependencies = result.getDependencies();
for (int i = 0; i < dependencies.length; i++) {
double finalPercentages = 1.0 / dependencies[i].length;
for (int j = 0; j < dependencies[i].length; j++) {
dependencies[i][j] = finalPercentages + (pDependencyMatrix.getDependencies()[i][j] - finalPercentages) * pImpact;
}
}
return result;
}
public double calculateImpact(double errorProbability, double pNumberOfMessages, double pMessageNumber, double b) {
double age = pNumberOfMessages - pMessageNumber;
if (errorProbability == 0) {
if (pMessageNumber == pNumberOfMessages) {
return 1;
} else {
return 0;
}
} else if (errorProbability == 1) {
return 1;
} else if (errorProbability == 0.5 || b == 0) {
return (1 - errorProbability) / pNumberOfMessages * age + errorProbability;
} else if (b == Double.NEGATIVE_INFINITY) {
if (pMessageNumber == pNumberOfMessages) {
return 1;
} else {
return 0;
}
}
return (1 - errorProbability) * (Math.exp(b * age) - Math.exp(b * pNumberOfMessages)) / (1 - Math.exp(b * pNumberOfMessages));
return result;
}
public double getChangeProbability(long ttl) {
return 1 - Math.pow(0.5, 1 / (double) ttl);
public Map<CacheDecisionStrategyParameters, String> getParams() {
return _params;
}
public int getOptimalMessageAmountForSwitch(double changeProbability, double errorProbability, double costSlow, double costFast) {
return (int) Math.round(Math.log(-changeProbability / Math.log(errorProbability) * costSlow / costFast) / Math.log(errorProbability));
@Override
public void setCacheSize(int pCacheSize) {
cacheSize = pCacheSize;
}
public double determineB(VectoralProperty pTemplate, RoadNetworkEdge pRoadNetworkEdge, int pPossibleValue, double change, double rate, double errorProbability, double pNumberOfMessages, double costSlow, double costFast) {
if (errorProbability == 0 || errorProbability == 1 || errorProbability == 0.5) {
return Double.NaN;
}
if (_lastDecision != null) {
if (pPossibleValue == ((VectoralProperty)_lastDecision).getMostProbableIndex()) {
return Double.NaN;
}
} else {
if (pPossibleValue == pTemplate.getDefaultIndex()) {
return Double.NaN;
}
}
double b;
double p_c = change;
int optimalAmount = getOptimalMessageAmountForSwitch(p_c, errorProbability, costSlow, costFast);
if ((int)pNumberOfMessages <= optimalAmount) {
return Double.POSITIVE_INFINITY;
}
if (optimalAmount == 1) {
return Double.NEGATIVE_INFINITY;
}
boolean first = true;
double step = 10;
if (errorProbability < 0.5) {
b = -1 * step;
} else {
b = 1 * step;
}
do {
VectoralProperty valueAfterN = calculateMostProbable(pTemplate, pRoadNetworkEdge, pPossibleValue, optimalAmount, rate, errorProbability, pNumberOfMessages, b);
double probableValueAfterN = Double.NaN;
if (valueAfterN != null) {
probableValueAfterN = valueAfterN.getMostProbableIndex();
}
VectoralProperty valueBeforeN = calculateMostProbable(pTemplate, pRoadNetworkEdge, pPossibleValue, optimalAmount - 1, rate, errorProbability, pNumberOfMessages, b);
double probableValueBeforeN = Double.NaN;
if (valueBeforeN != null) {
probableValueBeforeN = valueBeforeN.getMostProbableIndex();
}
if (probableValueAfterN == pPossibleValue && probableValueAfterN != probableValueBeforeN) {
return b;
}
if (!Double.isNaN(probableValueBeforeN) && !Double.isNaN(probableValueBeforeN) && step >= MIN_STEP) {
if (probableValueAfterN != pPossibleValue) {
if (b < 0) {
b -= step;
if (!first) {
step *= 0.5;
}
} else {
b -= step;
step *= 0.5;
first = false;
}
} else if (probableValueAfterN == pPossibleValue && probableValueAfterN == probableValueBeforeN) {
if (b > 0) {
b += step;
if (!first) {
step *= 0.5;
}
} else {
b += step;
step *= 0.5;
first = false;
}
} else {
return Double.NaN;
}
} else {
return Double.NaN;
}
} while (true);
@Override
public TTLbasedVectoralCacheDecisionStrategy clone() {
return new TTLbasedVectoralCacheDecisionStrategy(_params);
}
public VectoralProperty calculateMostProbable(VectoralProperty pTemplate, RoadNetworkEdge pRoadNetworkEdge, int pNewValue, int optimalMessageAmount, double rate, double errorProbability, double pNumberOfMessages, double b) {
VectoralProperty currentProperty = null;
for (int a = optimalMessageAmount + 1; a <= pNumberOfMessages; a++) {
VectoralProperty jamProperty = pTemplate.clone();
if (_lastDecision != null) {
jamProperty.set(((VectoralProperty)_lastDecision).getMostProbableIndex(), accuracy, MeasurementDistributionTypeContainer.getDistribution(pTemplate.getClass()));
} else {
jamProperty.set(pTemplate.getDefaultIndex(), accuracy, MeasurementDistributionTypeContainer.getDistribution(pTemplate.getClass()));
}
TemporalDependencyMatrix temporalDependencyMatrix = jamProperty.getDependencyMatrix();
temporalDependencyMatrix = temporalDependencyMatrix.age((long) (a * rate));
double impact = calculateImpact(errorProbability, pNumberOfMessages, pNumberOfMessages - a, b);
if (Double.isNaN(impact)) {
return null;
}
temporalDependencyMatrix = modifyDependencyMatrix(temporalDependencyMatrix, impact);
jamProperty = (VectoralProperty) jamProperty.age(1, temporalDependencyMatrix);
if (currentProperty != null) {
currentProperty = (VectoralProperty) currentProperty.combine(jamProperty);
} else {
currentProperty = jamProperty;
}
}
for (int a = 0; a <= optimalMessageAmount; a++) {
VectoralProperty jamProperty = pTemplate.clone();
jamProperty.setGaussianWithAccuracy(pNewValue, accuracy);
TemporalDependencyMatrix temporalDependencyMatrix = jamProperty.getDependencyMatrix();
temporalDependencyMatrix = temporalDependencyMatrix.age((long) (a * rate));
double impact = calculateImpact(errorProbability, pNumberOfMessages, pNumberOfMessages - a, b);
if (Double.isNaN(impact)) {
return null;
}
temporalDependencyMatrix = modifyDependencyMatrix(temporalDependencyMatrix, impact);
jamProperty = (VectoralProperty) jamProperty.age(1, temporalDependencyMatrix);
if (currentProperty != null) {
currentProperty = (VectoralProperty) currentProperty.combine(jamProperty);
} else {
currentProperty = jamProperty;
}
}
return currentProperty;
}
}
......@@ -21,9 +21,10 @@
package de.tud.kom.p2psim.impl.vehicular.caching.replacement;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.caching.replacement.CacheReplacementStrategy;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.caching.replacement.SimilarInformationReplacementStrategy;
public enum CacheReplacementStrategyType {
DEFAULT(NoCacheReplacementStrategy.class), NONE(NoCacheReplacementStrategy.class), IMMEDIATE(ImmediateCacheReplacementStrategy.class), TTL(TTLbasedCacheReplacementStrategy.class);
DEFAULT(NoCacheReplacementStrategy.class), NONE(NoCacheReplacementStrategy.class), IMMEDIATE(ImmediateCacheReplacementStrategy.class), TTL(TTLbasedCacheReplacementStrategy.class), SIMILAR(SimilarInformationReplacementStrategy.class);
private final Class<? extends CacheReplacementStrategy> replacementStrategy;
......
/*
* Copyright (c) 2005-2010 KOM – Multimedia Communications Lab
*
* This file is part of Simonstrator.KOM.
*
* Simonstrator.KOM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* PeerfactSim.KOM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.vehicular.decision;
import de.tud.kom.p2psim.impl.topology.movement.VehicleMovementModel;
import de.tudarmstadt.maki.simonstrator.api.Event;
import de.tudarmstadt.maki.simonstrator.api.EventHandler;
import de.tudarmstadt.maki.simonstrator.api.Host;
import de.tudarmstadt.maki.simonstrator.api.Monitor;
import de.tudarmstadt.maki.simonstrator.api.Time;
import de.tudarmstadt.maki.simonstrator.api.component.ComponentNotAvailableException;
import de.tudarmstadt.maki.simonstrator.api.component.core.MonitorComponent.AnalyzerNotAvailableException;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.environment.EnvironmentSensor;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.VehicleDecisionComponent;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.VehicleInformationComponent;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.caching.CachingComponent;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.information.RoadInformation;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.RoadNetwork;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.RoadNetworkEdge;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.RoadNetworkRoute;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.VehicleRouteAnalyzer;
public abstract class AbstractVehicleDecisionComponent implements VehicleDecisionComponent, EventHandler {
private static final int EVENT_DECISION_MAKING_CYCLE = 0;
private static final long EVENT_DECISION_MAKING_FREQUENCY = Time.SECOND * VehicleMovementModel.TIMESTEP_RATIO;
private VehicleInformationComponent _vehicleInformation;
private Host _host;
private CachingComponent _cache;
private boolean _routeAnalyzerInit = false;
private VehicleRouteAnalyzer _routeAnalyzer = null;
private EnvironmentSensor _sensors;
public AbstractVehicleDecisionComponent(Host pHost) {
_host = pHost;
}
@Override
public void initialize() {
try {
_cache = getHost().getComponent(CachingComponent.class);
_sensors = getHost().getComponent(EnvironmentSensor.class);
} catch (ComponentNotAvailableException e) {
throw new AssertionError(e);
}
}
@Override
public void shutdown() {
// Nothing to do
}
public VehicleInformationComponent getVehicleInformation() {
if (_vehicleInformation == null) {
try {
_vehicleInformation = getHost().getComponent(VehicleInformationComponent.class);
} catch (ComponentNotAvailableException e) {
throw new AssertionError(e);
}
}
return _vehicleInformation;
}
@Override
public Host getHost() {
return _host;
}
@Override
public void startDecisionMaking() {
Event.scheduleWithDelay(EVENT_DECISION_MAKING_FREQUENCY / 3 * 2, this, null, EVENT_DECISION_MAKING_CYCLE);
}
@Override
public final void eventOccurred(Object pContent, int pType) {
switch (pType) {
case EVENT_DECISION_MAKING_CYCLE:
RoadNetworkRoute currentRoute = getVehicleInformation().getCurrentRoute();
if (currentRoute != null) {
boolean changed = false;
if (currentRoute.getRoute().size() > 2) {
BenefitBasedRoute optimalRouteWithBenefit = getOptimalRoute(currentRoute,
_cache.getDecidedCacheEntries(RoadInformation.class), _sensors.getEnvironment());
if (optimalRouteWithBenefit != null && optimalRouteWithBenefit.getBenefit() > 0) {
RoadNetworkRoute optimalRoute = optimalRouteWithBenefit.getRoute();
if (optimalRouteWithBenefit.getRoute().getRoute().size() > 1) {
if (hasRouteAnalyzer()) {
getRouteAnalyzer().routeChanged(getHost().getId(), currentRoute, optimalRoute);
}
changed = true;
getVehicleInformation().changeCurrentRoute(optimalRouteWithBenefit.getRoute());
}
}
}
if (!changed && hasRouteAnalyzer()) {
getRouteAnalyzer().routeUnchanged(getHost().getId(), currentRoute);
}
}
Event.scheduleWithDelay(EVENT_DECISION_MAKING_FREQUENCY, this, null, EVENT_DECISION_MAKING_CYCLE);
break;
default:
break;
}
}
public boolean hasRouteAnalyzer() {
if (!_routeAnalyzerInit) {
_routeAnalyzerInit = true;
try {
_routeAnalyzer = Monitor.get(VehicleRouteAnalyzer.class);
} catch (AnalyzerNotAvailableException e) {
}
}
return _routeAnalyzer != null;
}
public VehicleRouteAnalyzer getRouteAnalyzer() {
return _routeAnalyzer;
}
}
\ No newline at end of file
/*
* Copyright (c) 2005-2010 KOM – Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* PeerfactSim.KOM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.vehicular.decision;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import de.tudarmstadt.maki.simonstrator.api.Host;
import de.tudarmstadt.maki.simonstrator.api.Time;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.environment.data.properties.RoadProperty;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.information.AvailableInformationAttributes;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.information.RoadInformation;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.RoadNetwork;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.RoadNetworkEdge;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.RoadNetworkRoute;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.paths.VehiclePathTracker;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.paths.VehiclePathTrackerFactory;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.routing.DijkstraAlgorithm;
public class CombinedInformationVehicleDecisionComponent extends AbstractVehicleDecisionComponent {
private static final boolean ENABLE_CACHING = true;
private static Map<RoadNetworkEdge, CostGraph> _unknownCostGraphs = new HashMap<>();
private static Map<RoadProperty, Map<RoadNetworkEdge, CostGraph>> _knownCostGraphs = new HashMap<>();
public CombinedInformationVehicleDecisionComponent(Host pHost) {
super(pHost);
}
@Override
public BenefitBasedRoute getOptimalRoute(RoadNetworkRoute pInvestigatedRoute, List<RoadInformation> knownInformation) {
if (!ENABLE_CACHING) {
_unknownCostGraphs.clear();
_knownCostGraphs.clear();
}
if (getVehicleInformation().isValid() && pInvestigatedRoute.getRoute().size() > 1) {
if (knownInformation != null && knownInformation.size() > 1) {
for (RoadInformation roadInformation : knownInformation) {
System.out.println("Known information for road " + roadInformation.getEdge());
}
throw new AssertionError("Only one information currently supported!");
}
DijkstraAlgorithm dijkstraAlgorithm = new DijkstraAlgorithm();
List<RoadNetworkRoute> known = new ArrayList<>();
known.add(pInvestigatedRoute);
RoadNetworkRoute optimalRoute = dijkstraAlgorithm.findRoute(RoadNetwork.CURRENT_ROAD_NETWORK, pInvestigatedRoute.getStart(), pInvestigatedRoute.getDestination(), known, Collections.emptyList(), knownInformation);
if (optimalRoute != null) {
if (pInvestigatedRoute.equals(optimalRoute)) {
return new BenefitBasedRoute(0, pInvestigatedRoute);
}
double oldCostsActive = getRouteCosts(pInvestigatedRoute, knownInformation);
double oldCostsInactive = getRouteCosts(pInvestigatedRoute, Collections.emptyList());
double newCostsActive = getRouteCosts(optimalRoute, knownInformation);
double activeProbability = 0;
if (knownInformation != null && knownInformation.size() > 0) {
if (!knownInformation.get(0).getValue()
.equals(knownInformation.get(0).getValue().getDefaultProperty())) {
double traveltime = getRouteDuration(pInvestigatedRoute, knownInformation.get(0).getEdge());
long expected = (long) knownInformation.get(0)
.getAttribute(AvailableInformationAttributes.EXPECTED_DURATION) / Time.SECOND;
if (!Double.isNaN(traveltime)) {
activeProbability = Math.pow(1 - 1 / (double) (expected), traveltime);
}
} else {
activeProbability = 0;
}
}
// Check if detour can immediately be triggered due to high probability of success.
double oldCosts = oldCostsActive * activeProbability + oldCostsInactive * (1 - activeProbability);
if (oldCosts > newCostsActive) {
known.clear();
known.add(pInvestigatedRoute);
known.add(optimalRoute);
RoadNetworkRoute secondOptimalRoute = dijkstraAlgorithm.findRoute(RoadNetwork.CURRENT_ROAD_NETWORK, pInvestigatedRoute.getStart(), pInvestigatedRoute.getDestination(), known, Collections.emptyList(), knownInformation);
double secondOptimalCosts = 0;
if (secondOptimalRoute != null) {
secondOptimalCosts = getRouteCosts(secondOptimalRoute, knownInformation);
}
if (secondOptimalRoute == null || secondOptimalCosts * activeProbability + oldCostsInactive * (1 - activeProbability) > newCostsActive) {
return new BenefitBasedRoute(oldCosts - newCostsActive, optimalRoute);
}
}
// Check if detour can immediately be discarded due to high probability of failure.
if (oldCosts < newCostsActive && optimalRoute.getRoute().size() > 1) {
known.clear();
known.add(pInvestigatedRoute);
known.add(optimalRoute);
RoadNetworkRoute secondOptimalRoute = dijkstraAlgorithm.findRoute(RoadNetwork.CURRENT_ROAD_NETWORK, optimalRoute.getRoute().get(1), pInvestigatedRoute.getDestination(), known, Collections.emptyList(), Collections.emptyList());
secondOptimalRoute.getRoute().add(0, optimalRoute.getStart());
if (secondOptimalRoute != null) {
double secondOptimalCosts = getRouteCosts(secondOptimalRoute, Collections.emptyList());
if (newCostsActive * activeProbability + secondOptimalCosts * (1 - activeProbability) > oldCosts || activeProbability == 0) {
return new BenefitBasedRoute(0, pInvestigatedRoute);
}
}
}
}
CostGraph usedCostGraph = null;
if (!_unknownCostGraphs.containsKey(pInvestigatedRoute.getDestination())) {
CostGraph costGraph = new CostGraph(pInvestigatedRoute.getDestination());
costGraph.createCostGraph();
_unknownCostGraphs.put(pInvestigatedRoute.getDestination(), costGraph);
}
if (knownInformation != null && knownInformation.size() > 0) {
if (!_knownCostGraphs.containsKey(knownInformation.get(0).getValue())) {
_knownCostGraphs.put(knownInformation.get(0).getValue(), new HashMap<>());
}
Map<RoadNetworkEdge, CostGraph> costGraphs = _knownCostGraphs.get(knownInformation.get(0).getValue());
if (!costGraphs.containsKey(pInvestigatedRoute.getDestination())) {
CostGraph costGraph = new CostGraph(pInvestigatedRoute.getDestination(), knownInformation.get(0), _unknownCostGraphs.get(pInvestigatedRoute.getDestination()));
costGraph.setCostLimit(getRouteCosts(pInvestigatedRoute, knownInformation));
costGraph.createCostGraph();
costGraphs.put(pInvestigatedRoute.getDestination(), costGraph);
}
}
if (knownInformation != null && knownInformation.size() > 0 && !knownInformation.get(0).getValue().equals(knownInformation.get(0).getValue().getDefaultProperty())) {
Map<RoadNetworkEdge, CostGraph> costGraphs = _knownCostGraphs.get(knownInformation.get(0).getValue());
usedCostGraph = costGraphs.get(pInvestigatedRoute.getDestination());
} else {
usedCostGraph = _unknownCostGraphs.get(pInvestigatedRoute.getDestination());
}
double minCosts = Double.MAX_VALUE;
optimalRoute = null;
for (RoadNetworkEdge edge : pInvestigatedRoute.getStart().getAccessibleEdges()) {
if (usedCostGraph.getCosts(edge) < minCosts) {
RoadNetworkRoute roadNetworkRoute = usedCostGraph.getOptimalRoute(edge);
minCosts = usedCostGraph.getCosts(edge);
optimalRoute = roadNetworkRoute;
}
}
if (optimalRoute != null) {
optimalRoute.getRoute().add(0, pInvestigatedRoute.getStart());
double oldCosts = getRouteCosts(pInvestigatedRoute, knownInformation);
double newCosts = getRouteCosts(optimalRoute, knownInformation);
if (oldCosts > newCosts) {
return new BenefitBasedRoute(oldCosts - newCosts, optimalRoute);
}
}
return new BenefitBasedRoute(0, pInvestigatedRoute);
}
return new BenefitBasedRoute(0, pInvestigatedRoute);
}
private double getRouteCosts(RoadNetworkRoute pInvestigatedRoute, List<RoadInformation> knownInformation) {
double oldCosts = 0;
for (RoadNetworkEdge edge : pInvestigatedRoute.getRoute()) {
oldCosts += edge.calculateStandardEdgeCosts();
if (knownInformation != null) {
for (RoadInformation roadInformation : knownInformation) {
double cost = edge.calculateAdditionalCostIfKnown(roadInformation.getValue());
oldCosts += cost;
}
}
}
return oldCosts;
}
private double getRouteDuration(RoadNetworkRoute pInvestigatedRoute, RoadNetworkEdge pEvent) {
double duration = 0;
if (!pInvestigatedRoute.containsEdge(pEvent)) {
return Double.NaN;
}
for (int i = 1; i < pInvestigatedRoute.getRoute().size(); i++) {
RoadNetworkEdge edge = pInvestigatedRoute.getRoute().get(i);
if (edge.equals(pEvent)) {
break;
}
duration += VehiclePathTrackerFactory.getVehiclePathTracker().getTravelTime(edge);
}
return duration;
}
private class CostGraph {
private Map<RoadNetworkEdge, Double> _costGraph = new HashMap<>();
private Map<RoadNetworkEdge, RoadNetworkEdge> _nextEdgeGraph = new HashMap<>();
// For event active
private RoadInformation _information;
private CostGraph _costGraphWithoutEvent;
private RoadNetworkEdge _destination;
private double _maxCosts = Double.POSITIVE_INFINITY;
// If event inactive
public CostGraph(RoadNetworkEdge pDestination) {
_costGraph.put(pDestination, 0d);
_destination = pDestination;
}
public void setCostLimit(double pRouteCosts) {
_maxCosts = pRouteCosts;
}
// If event active
public CostGraph(RoadNetworkEdge pDestination, RoadInformation pInformation, CostGraph pCostGraphWithoutEvent) {
this(pDestination);
_information = pInformation;
_costGraphWithoutEvent = pCostGraphWithoutEvent;
}
public RoadNetworkRoute getOptimalRoute(RoadNetworkEdge pEdge) {
List<RoadNetworkEdge> edges = new ArrayList<>();
RoadNetworkEdge current = pEdge;
edges.add(current);
while (_nextEdgeGraph.containsKey(current)) {
RoadNetworkEdge next = _nextEdgeGraph.get(current);
edges.add(next);
current = next;
if (next.equals(_destination) || !_costGraph.containsKey(current) || !_costGraph.containsKey(next)
|| _costGraph.get(current) < _costGraph.get(next)) {
break;
}
}
if (edges.get(edges.size() - 1).equals(_destination)) {
return new RoadNetworkRoute(edges);
}
return null;
}
public void createCostGraph() {
createCostGraph(25);
}
public void createCostGraph(int pMaxDepth) {
RoadProperty property = null;
if (_information != null) {
property = _information.getValue();
}
if (_information != null) {
VehiclePathTracker tracker = VehiclePathTrackerFactory.getVehiclePathTracker();
long duration = _information.getAttribute(AvailableInformationAttributes.EXPECTED_DURATION);
double existProbability = 1 - 1 / (double) (duration / Time.SECOND);
for (int i = 0; i < pMaxDepth; i++) {
List<RoadNetworkEdge> labeledEdges = new ArrayList<>(_costGraph.keySet());
int updated = 0;
for (RoadNetworkEdge roadNetworkEdge : labeledEdges) {
List<RoadNetworkEdge> incomingEdges = roadNetworkEdge.getIncomingEdges();
for (RoadNetworkEdge incomingEdge : incomingEdges) {
if (isCyclic(incomingEdge, roadNetworkEdge)) {
continue;
}
double edgeCost = incomingEdge.calculateEdgeCostIfKnown(property);
if (edgeCost > duration / Time.SECOND) {
edgeCost = duration / (double) Time.SECOND;
}
double eventActiveCost = _costGraph.get(roadNetworkEdge);
double eventInactiveCost = _costGraphWithoutEvent.getCosts(roadNetworkEdge);
double stillExistProbability = Math.pow(existProbability,
tracker.getTravelTime(incomingEdge, roadNetworkEdge));
double totalCosts = edgeCost + eventInactiveCost * (1 - stillExistProbability)
+ eventActiveCost * stillExistProbability;
if ((!_costGraph.containsKey(incomingEdge) || totalCosts < _costGraph.get(incomingEdge)) && totalCosts <= _maxCosts) {
_costGraph.put(incomingEdge, totalCosts);
_nextEdgeGraph.put(incomingEdge, roadNetworkEdge);
updated++;
}
}
}
if (updated == 0) {
break;
}
}
} else {
for (int i = 0; i < pMaxDepth; i++) {
List<RoadNetworkEdge> labeledEdges = new ArrayList<>(_costGraph.keySet());
int updated = 0;
for (RoadNetworkEdge roadNetworkEdge : labeledEdges) {
List<RoadNetworkEdge> incomingEdges = roadNetworkEdge.getIncomingEdges();
for (RoadNetworkEdge incomingEdge : incomingEdges) {
double edgeCost = incomingEdge.calculateStandardEdgeCosts();
double totalCosts = _costGraph.get(roadNetworkEdge) + edgeCost;
if ((!_costGraph.containsKey(incomingEdge) || totalCosts < _costGraph.get(incomingEdge)) && totalCosts <= _maxCosts) {
_costGraph.put(incomingEdge, totalCosts);
_nextEdgeGraph.put(incomingEdge, roadNetworkEdge);
updated++;
}
}
}
if (updated == 0) {
break;
}
}
}
}
private boolean isCyclic(RoadNetworkEdge pIncomingEdge, RoadNetworkEdge pRoadNetworkEdge) {
RoadNetworkEdge current = pRoadNetworkEdge;
while (_nextEdgeGraph.containsKey(current)) {
if (pIncomingEdge.equals(current)) {
return true;
}
if (current == _destination) {
break;
}
current = _nextEdgeGraph.get(current);
}
return false;
}
public double getCosts(RoadNetworkEdge pEdge) {
if (_costGraph.containsKey(pEdge)) {
return _costGraph.get(pEdge);
} else {
return Double.MAX_VALUE;
}
}
}
}
/*
* Copyright (c) 2005-2010 KOM – Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* PeerfactSim.KOM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.vehicular.decision;
import java.util.List;
import de.tudarmstadt.maki.simonstrator.api.Host;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.environment.data.properties.RoadProperty;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.information.RoadInformation;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.RoadNetworkRoute;
public class DefaultVehicleDecisionComponent extends AbstractVehicleDecisionComponent {
public DefaultVehicleDecisionComponent(Host pHost) {
super(pHost);
}
@Override
public BenefitBasedRoute getOptimalRoute(RoadNetworkRoute pInvestigatedRoute, List<RoadInformation> knownInformation) {
if (getVehicleInformation().isValid()) {
return new BenefitBasedRoute(0, pInvestigatedRoute);
}
return null;
}
}
/*
* Copyright (c) 2005-2010 KOM – Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* PeerfactSim.KOM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.vehicular.decision;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import de.tudarmstadt.maki.simonstrator.api.Host;
import de.tudarmstadt.maki.simonstrator.api.Time;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.environment.data.properties.RoadProperty;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.information.AvailableInformationAttributes;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.information.RoadInformation;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.RoadNetwork;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.RoadNetworkEdge;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.RoadNetworkRoute;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.paths.VehiclePathTracker;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.paths.VehiclePathTrackerFactory;
public class DynamicInformationVehicleDecisionComponent extends AbstractVehicleDecisionComponent {
private static Map<RoadNetworkEdge, CostGraph> _unknownCostGraphs = new HashMap<>();
private static Map<RoadProperty, Map<RoadNetworkEdge, CostGraph>> _knownCostGraphs = new HashMap<>();
public DynamicInformationVehicleDecisionComponent(Host pHost) {
super(pHost);
}
@Override
public BenefitBasedRoute getOptimalRoute(RoadNetworkRoute pInvestigatedRoute, List<RoadInformation> knownInformation) {
if (getVehicleInformation().isValid() && pInvestigatedRoute.getRoute().size() > 1) {
if (knownInformation != null && knownInformation.size() > 1) {
for (RoadInformation roadInformation : knownInformation) {
System.out.println("Known information for road " + roadInformation.getEdge());
}
throw new AssertionError("Only one information currently supported!");
}
CostGraph usedCostGraph = null;
if (!_unknownCostGraphs.containsKey(pInvestigatedRoute.getDestination())) {
CostGraph costGraph = new CostGraph(pInvestigatedRoute.getDestination());
costGraph.createCostGraph();
_unknownCostGraphs.put(pInvestigatedRoute.getDestination(), costGraph);
}
CostGraph unknown = _unknownCostGraphs.get(pInvestigatedRoute.getDestination());
if (knownInformation != null && knownInformation.size() > 0) {
if (!_knownCostGraphs.containsKey(knownInformation.get(0).getValue())) {
_knownCostGraphs.put(knownInformation.get(0).getValue(), new HashMap<>());
}
Map<RoadNetworkEdge, CostGraph> costGraphs = _knownCostGraphs.get(knownInformation.get(0).getValue());
if (!costGraphs.containsKey(pInvestigatedRoute.getDestination())) {
CostGraph costGraph = new CostGraph(pInvestigatedRoute.getDestination(), knownInformation.get(0), unknown);
// costGraph.setCostLimit(getRouteCosts(pInvestigatedRoute, knownInformation));
costGraph.createCostGraph();
costGraphs.put(pInvestigatedRoute.getDestination(), costGraph);
}
}
if (knownInformation != null && knownInformation.size() > 0 && !knownInformation.get(0).getValue().equals(knownInformation.get(0).getValue().getDefaultProperty())) {
Map<RoadNetworkEdge, CostGraph> costGraphs = _knownCostGraphs.get(knownInformation.get(0).getValue());
usedCostGraph = costGraphs.get(pInvestigatedRoute.getDestination());
} else {
usedCostGraph = unknown;
}
// if (knownInformation != null && knownInformation.size() > 0) {
// String[] edges = new String[] {"gneE8", "gneE6", "gneE4", "gneE2"};
// String[] nextEdges = new String[] {"event", "gneE7", "gneE5", "gneE3"};
// String[] alternativeEdges = new String[] {"gneE68", "gneE16", "gneE51", "gneE56"};
// for (int i = 0; i < edges.length; i++) {
// String edge = edges[i];
// System.out.println(edge);
// System.out.println("\tUnknown: " + unknown.getCosts(RoadNetwork.CURRENT_ROAD_NETWORK.getEdge(edge)) + " via " + unknown.getOptimalRoute(RoadNetwork.CURRENT_ROAD_NETWORK.getEdge(edge)));
// System.out.println("\tUnknown (along path): " + (unknown.getCosts(RoadNetwork.CURRENT_ROAD_NETWORK.getEdge(nextEdges[i])) + RoadNetwork.CURRENT_ROAD_NETWORK.getEdge(edge).calculateStandardEdgeCosts()) + " via " + unknown.getOptimalRoute(RoadNetwork.CURRENT_ROAD_NETWORK.getEdge(nextEdges[i])));
// System.out.println("\tUnknown (along alternative): " + (unknown.getCosts(RoadNetwork.CURRENT_ROAD_NETWORK.getEdge(alternativeEdges[i])) + RoadNetwork.CURRENT_ROAD_NETWORK.getEdge(edge).calculateStandardEdgeCosts()) + " via " + unknown.getOptimalRoute(RoadNetwork.CURRENT_ROAD_NETWORK.getEdge(alternativeEdges[i])));
// if (knownInformation != null && knownInformation.size() > 0) {
// CostGraph known = _knownCostGraphs.get(knownInformation.get(0).getValue()).get(pInvestigatedRoute.getDestination());
// System.out.println("\tKnown: " + known.getCosts(RoadNetwork.CURRENT_ROAD_NETWORK.getEdge(edge)) + " via " + known.getOptimalRoute(RoadNetwork.CURRENT_ROAD_NETWORK.getEdge(edge)));
// System.out.println("\tKnown (along path): " + (known.getCosts(RoadNetwork.CURRENT_ROAD_NETWORK.getEdge(nextEdges[i]))) + " via " + known.getOptimalRoute(RoadNetwork.CURRENT_ROAD_NETWORK.getEdge(nextEdges[i])));
// System.out.println("\tKnown (along alternative): " + (known.getCosts(RoadNetwork.CURRENT_ROAD_NETWORK.getEdge(alternativeEdges[i]))) + " via " + known.getOptimalRoute(RoadNetwork.CURRENT_ROAD_NETWORK.getEdge(alternativeEdges[i])));
// }
// System.out.println();
// }
// System.out.println("_____________________________________________");
//
// System.out.println();
// }
double minCosts = Double.MAX_VALUE;
RoadNetworkRoute optimalRoute = null;
for (RoadNetworkEdge edge : pInvestigatedRoute.getStart().getAccessibleEdges()) {
if (usedCostGraph.getCosts(edge) < minCosts) {
RoadNetworkRoute roadNetworkRoute = usedCostGraph.getOptimalRoute(edge);
minCosts = usedCostGraph.getCosts(edge);
optimalRoute = roadNetworkRoute;
}
}
if (optimalRoute != null) {
optimalRoute.getRoute().add(0, pInvestigatedRoute.getStart());
double oldCosts = getRouteCosts(pInvestigatedRoute, knownInformation);
double newCosts = getRouteCosts(optimalRoute, knownInformation);
if (oldCosts > newCosts) {
return new BenefitBasedRoute(oldCosts - newCosts, optimalRoute);
}
}
return new BenefitBasedRoute(0, pInvestigatedRoute);
}
return new BenefitBasedRoute(0, pInvestigatedRoute);
}
private double getRouteCosts(RoadNetworkRoute pInvestigatedRoute, List<RoadInformation> knownInformation)
throws AssertionError {
double oldCosts = 0;
for (RoadNetworkEdge edge : pInvestigatedRoute.getRoute()) {
oldCosts += edge.calculateStandardEdgeCosts();
if (knownInformation != null) {
for (RoadInformation roadInformation : knownInformation) {
double cost = edge.calculateAdditionalCostIfKnown(roadInformation.getValue());
oldCosts += cost;
}
}
}
return oldCosts;
}
private class CostGraph {
private Map<RoadNetworkEdge, Double> _costGraph = new HashMap<>();
private Map<RoadNetworkEdge, RoadNetworkEdge> _nextEdgeGraph = new HashMap<>();
// For event active
private RoadInformation _information;
private CostGraph _costGraphWithoutEvent;
private RoadNetworkEdge _destination;
private double _maxCosts = Double.POSITIVE_INFINITY;
// If event inactive
public CostGraph(RoadNetworkEdge pDestination) {
_costGraph.put(pDestination, 0d);
_destination = pDestination;
}
public void setCostLimit(double pRouteCosts) {
_maxCosts = pRouteCosts;
}
// If event active
public CostGraph(RoadNetworkEdge pDestination, RoadInformation pInformation, CostGraph pCostGraphWithoutEvent) {
this(pDestination);
_information = pInformation;
_costGraphWithoutEvent = pCostGraphWithoutEvent;
}
public RoadNetworkRoute getOptimalRoute(RoadNetworkEdge pEdge) {
List<RoadNetworkEdge> edges = new ArrayList<>();
RoadNetworkEdge current = pEdge;
edges.add(current);
while (_nextEdgeGraph.containsKey(current)) {
RoadNetworkEdge next = _nextEdgeGraph.get(current);
edges.add(next);
current = next;
if (next.equals(_destination) || !_costGraph.containsKey(current) || !_costGraph.containsKey(next)
|| _costGraph.get(current) < _costGraph.get(next)) {
break;
}
}
if (edges.get(edges.size() - 1).equals(_destination)) {
return new RoadNetworkRoute(edges);
}
return null;
}
public void createCostGraph() {
createCostGraph(RoadNetwork.CURRENT_ROAD_NETWORK.getUsableEdges().size());
}
public void createCostGraph(int pMaxDepth) {
_costGraph.clear();
_costGraph.put(_destination, 0d);
RoadProperty property = null;
if (_information != null) {
property = _information.getValue();
}
if (_information != null) {
VehiclePathTracker tracker = VehiclePathTrackerFactory.getVehiclePathTracker();
long duration = _information.getAttribute(AvailableInformationAttributes.EXPECTED_DURATION);
double existProbability = 1 - 1 / (double) (duration / Time.SECOND);
for (int i = 0; i < pMaxDepth; i++) {
List<RoadNetworkEdge> labeledEdges = new ArrayList<>(_costGraph.keySet());
int updated = 0;
for (RoadNetworkEdge roadNetworkEdge : labeledEdges) {
List<RoadNetworkEdge> incomingEdges = roadNetworkEdge.getIncomingEdges();
for (RoadNetworkEdge incomingEdge : incomingEdges) {
if (isCyclic(incomingEdge, roadNetworkEdge)) {
continue;
}
double edgeCost = incomingEdge.calculateStandardEdgeCosts();
double additionalCosts = incomingEdge.calculateAdditionalCostIfKnown(property);
edgeCost += additionalCosts;
double eventActiveCost = _costGraph.get(roadNetworkEdge);
double eventInactiveCost = _costGraphWithoutEvent.getCosts(roadNetworkEdge);
double stillExistProbability = Math.pow(existProbability,
tracker.getTravelTime(incomingEdge, roadNetworkEdge));
double totalCosts = edgeCost + eventInactiveCost * (1 - stillExistProbability)
+ eventActiveCost * stillExistProbability;
if ((!_costGraph.containsKey(incomingEdge) || totalCosts < _costGraph.get(incomingEdge)) && totalCosts <= _maxCosts) {
_costGraph.put(incomingEdge, totalCosts);
_nextEdgeGraph.put(incomingEdge, roadNetworkEdge);
updated++;
}
}
}
if (updated == 0) {
break;
}
}
} else {
for (int i = 0; i < pMaxDepth; i++) {
List<RoadNetworkEdge> labeledEdges = new ArrayList<>(_costGraph.keySet());
int updated = 0;
for (RoadNetworkEdge roadNetworkEdge : labeledEdges) {
List<RoadNetworkEdge> incomingEdges = roadNetworkEdge.getIncomingEdges();
for (RoadNetworkEdge incomingEdge : incomingEdges) {
double edgeCost = incomingEdge.calculateStandardEdgeCosts();
double totalCosts = _costGraph.get(roadNetworkEdge) + edgeCost;
if ((!_costGraph.containsKey(incomingEdge) || totalCosts < _costGraph.get(incomingEdge)) && totalCosts <= _maxCosts) {
_costGraph.put(incomingEdge, totalCosts);
_nextEdgeGraph.put(incomingEdge, roadNetworkEdge);
updated++;
}
}
}
if (updated == 0) {
break;
}
}
}
}
private boolean isCyclic(RoadNetworkEdge pIncomingEdge, RoadNetworkEdge pRoadNetworkEdge) {
RoadNetworkEdge current = pRoadNetworkEdge;
while (_nextEdgeGraph.containsKey(current)) {
if (pIncomingEdge.equals(current)) {
return true;
}
if (current == _destination) {
break;
}
current = _nextEdgeGraph.get(current);
}
return false;
}
public double getCosts(RoadNetworkEdge pEdge) {
if (_costGraph.containsKey(pEdge)) {
return _costGraph.get(pEdge);
} else {
return Double.MAX_VALUE;
}
}
}
}
/*
* Copyright (c) 2005-2010 KOM – Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* PeerfactSim.KOM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.vehicular.decision;
import de.tudarmstadt.maki.simonstrator.api.Host;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.routing.DijkstraAlgorithm;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.routing.LatestPossibleDijkstraAlgorithm;
public class LatestPossibleVehicleDecisionComponent extends StaticInformationVehicleDecisionComponent {
public LatestPossibleVehicleDecisionComponent(Host pHost) {
super(pHost);
}
@Override
protected DijkstraAlgorithm getRoutingAlgorithm() {
return new LatestPossibleDijkstraAlgorithm();
}
}
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