diff --git a/src/de/tud/kom/p2psim/impl/vehicular/caching/DefaultCachingComponent.java b/src/de/tud/kom/p2psim/impl/vehicular/caching/DefaultCachingComponent.java
index d6dff3f462a5337e6cb516b55832f4fb73df82ab..a7efe63f4e9cfe8d8eeebc027503e1f95f14601d 100755
--- a/src/de/tud/kom/p2psim/impl/vehicular/caching/DefaultCachingComponent.java
+++ b/src/de/tud/kom/p2psim/impl/vehicular/caching/DefaultCachingComponent.java
@@ -38,6 +38,7 @@ import de.tudarmstadt.maki.simonstrator.api.component.vehicular.caching.replacem
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;
+import de.tudarmstadt.maki.simonstrator.api.component.vehicular.information.RoadInformation;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.RoadNetworkEdge;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.RoadNetworkRoute;
@@ -178,6 +179,8 @@ implements CachingComponent, ConnectivityListener {
if (information.hasAttribute(AvailableInformationAttributes.EDGE)) {
return information
.getAttribute(AvailableInformationAttributes.EDGE);
+ } else if (information instanceof RoadInformation) {
+ return ((RoadInformation) information).getEdge();
} else {
return information.getLocation();
}
diff --git a/src/de/tud/kom/p2psim/impl/vehicular/caching/decision/AveragingCacheDecisionStrategy.java b/src/de/tud/kom/p2psim/impl/vehicular/caching/decision/AveragingCacheDecisionStrategy.java
new file mode 100755
index 0000000000000000000000000000000000000000..a793b606f54a4599adc341641140e1b3c7daa27e
--- /dev/null
+++ b/src/de/tud/kom/p2psim/impl/vehicular/caching/decision/AveragingCacheDecisionStrategy.java
@@ -0,0 +1,71 @@
+/*
+ * 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 .
+ *
+ */
+
+package de.tud.kom.p2psim.impl.vehicular.caching.decision;
+
+import java.util.List;
+
+import de.tudarmstadt.maki.simonstrator.api.component.sensor.environment.data.NumericVectoralProperty;
+import de.tudarmstadt.maki.simonstrator.api.component.sensor.environment.data.VectoralJamProperty;
+import de.tudarmstadt.maki.simonstrator.api.component.vehicular.caching.decision.CacheDecisionStrategy;
+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 {
+
+ @Override
+ public T decideOnCorrectInformation(
+ List pSimilarPointInformation) {
+ if (pSimilarPointInformation.size() == 1) {
+ T decision = pSimilarPointInformation.get(0);
+ return decision;
+ } 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, 0);
+ } else {
+ throw new AssertionError("Unknown data type " + cloned.getClass().getSimpleName());
+ }
+
+ return (T) new RoadInformation(cloned);
+ }
+
+}
diff --git a/src/de/tud/kom/p2psim/impl/vehicular/caching/decision/CacheDecisionStrategyType.java b/src/de/tud/kom/p2psim/impl/vehicular/caching/decision/CacheDecisionStrategyType.java
index 6499ddf4385a5bd9cd76da6e53ac6a6cea9ed774..70240818d241d8dcaf3720f3149508d13b996def 100755
--- a/src/de/tud/kom/p2psim/impl/vehicular/caching/decision/CacheDecisionStrategyType.java
+++ b/src/de/tud/kom/p2psim/impl/vehicular/caching/decision/CacheDecisionStrategyType.java
@@ -28,7 +28,7 @@ import java.util.Map;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.caching.decision.CacheDecisionStrategy;
public enum CacheDecisionStrategyType {
- DEFAULT(NewestCacheDecisionStrategy.class), NEWEST(NewestCacheDecisionStrategy.class), TTL(TTLbasedCacheDecisionStrategy.class), MAJORITY(MajorityVotingCacheDecisionStrategy.class), OPTIMAL(OptimalCacheDecisionStrategy.class), RANDOM(RandomCacheDecisionStrategy.class);
+ 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 params = new HashMap<>();
diff --git a/src/de/tud/kom/p2psim/impl/vehicular/caching/decision/MajorityVotingVectoralCacheDecisionStrategy.java b/src/de/tud/kom/p2psim/impl/vehicular/caching/decision/MajorityVotingVectoralCacheDecisionStrategy.java
new file mode 100755
index 0000000000000000000000000000000000000000..56fccdbea6e80c0762e6d4ac69d25ab8b0c2d80a
--- /dev/null
+++ b/src/de/tud/kom/p2psim/impl/vehicular/caching/decision/MajorityVotingVectoralCacheDecisionStrategy.java
@@ -0,0 +1,77 @@
+/*
+ * 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 .
+ *
+ */
+
+package de.tud.kom.p2psim.impl.vehicular.caching.decision;
+
+import java.util.Arrays;
+import java.util.List;
+
+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.vector.TemporalDependencyMatrix;
+import de.tudarmstadt.maki.simonstrator.api.component.vehicular.caching.decision.CacheDecisionStrategy;
+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 {
+ private static final long SCALING = Time.SECOND;
+
+ @Override
+ public T decideOnCorrectInformation(
+ List pSimilarPointInformation) {
+ VectoralProperty currentProperty = null;
+
+ long minTimestamp = Long.MAX_VALUE;
+ long maxTimestamp = 0;
+ for (T t : pSimilarPointInformation) {
+ long timestamp = t.getDetectionDate();
+
+ if (timestamp < minTimestamp) {
+ minTimestamp = timestamp;
+ }
+ if (timestamp > maxTimestamp) {
+ 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);
+ } else {
+ currentProperty = agedProperty;
+ }
+ }
+
+ TemporalDependencyMatrix dependencyMatrix = currentProperty.getDependencyMatrix();
+
+ VectoralProperty agedProperty = currentProperty.age((Time.getCurrentTime() - maxTimestamp) / SCALING, dependencyMatrix);
+
+ return (T) new RoadInformation(agedProperty);
+ }
+
+}
diff --git a/src/de/tud/kom/p2psim/impl/vehicular/caching/decision/TTLbasedCacheDecisionStrategy.java b/src/de/tud/kom/p2psim/impl/vehicular/caching/decision/TTLbasedCacheDecisionStrategy.java
index 4309e925378d1c2d387fa92a4442f2ad7eb80ce7..d899db8001a20d87db595ca70ddb53d038d59db3 100755
--- a/src/de/tud/kom/p2psim/impl/vehicular/caching/decision/TTLbasedCacheDecisionStrategy.java
+++ b/src/de/tud/kom/p2psim/impl/vehicular/caching/decision/TTLbasedCacheDecisionStrategy.java
@@ -20,6 +20,7 @@
package de.tud.kom.p2psim.impl.vehicular.caching.decision;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
diff --git a/src/de/tud/kom/p2psim/impl/vehicular/caching/decision/TTLbasedVectoralCacheDecisionStrategy.java b/src/de/tud/kom/p2psim/impl/vehicular/caching/decision/TTLbasedVectoralCacheDecisionStrategy.java
new file mode 100755
index 0000000000000000000000000000000000000000..ad05c7f8cc9e5a0de16a4b1b832bcd1421ded0d6
--- /dev/null
+++ b/src/de/tud/kom/p2psim/impl/vehicular/caching/decision/TTLbasedVectoralCacheDecisionStrategy.java
@@ -0,0 +1,321 @@
+/*
+ * 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 .
+ *
+ */
+
+package de.tud.kom.p2psim.impl.vehicular.caching.decision;
+
+import java.util.Comparator;
+import java.util.List;
+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.VectoralProperty;
+import de.tudarmstadt.maki.simonstrator.api.component.sensor.environment.data.vector.TemporalDependencyMatrix;
+import de.tudarmstadt.maki.simonstrator.api.component.vehicular.caching.decision.CacheDecisionStrategy;
+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 edu.emory.mathcs.backport.java.util.Collections;
+
+public class TTLbasedVectoralCacheDecisionStrategy implements CacheDecisionStrategy {
+ private static final long SCALING = Time.SECOND;
+
+ private static final double ACCURACY_FACTOR = 100000;
+
+ private double accuracy = 1;
+
+ private double costWrongKeep = 1;
+ private double costWrongChange = 1;
+
+ private Object _lastDecision = false;
+
+ public TTLbasedVectoralCacheDecisionStrategy(Map pParams) {
+ for (Entry param : pParams.entrySet()) {
+ switch (param.getKey()) {
+ case "ACCURACY":
+ accuracy = Double.valueOf(param.getValue());
+ break;
+ case "COST_RATIO":
+ double ratio = Double.valueOf(param.getValue());
+ costWrongChange = 2 / (ratio + 1);
+ costWrongKeep = 2 - costWrongChange;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ public double getCostWrongChange() {
+ return costWrongChange;
+ }
+
+ public double getCostWrongKeep() {
+ return costWrongKeep;
+ }
+
+ @Override
+ public T decideOnCorrectInformation(
+ List pSimilarPointInformation) {
+ if (pSimilarPointInformation.size() == 1) {
+ T decision = pSimilarPointInformation.get(0);
+ _lastDecision = decision.getValue();
+ return decision;
+ } else if (pSimilarPointInformation.size() == 0) {
+ return null;
+ }
+
+ Collections.sort(pSimilarPointInformation, new Comparator() {
+
+ @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);
+
+ long ttl = (long)pSimilarPointInformation.get(0).getAttribute(AvailableInformationAttributes.TTL) / SCALING;
+ rate = Math.min(rate, ttl / 10);
+
+ double b = determineB(rate, 1 - accuracy, ttl, costWrongKeep, costWrongChange);
+
+ VectoralProperty currentProperty = null;
+
+ for (T t : pSimilarPointInformation) {
+ RoadInformation roadInformation = ((RoadInformation) t);
+ VectoralProperty property = (VectoralProperty) roadInformation.getValue();
+
+ double impact = calculateImpact(1 - accuracy, ttl, t.getDetectionDate() / SCALING, b, maxTimestamp / SCALING) / (accuracy);
+
+ TemporalDependencyMatrix dependencyMatrix = property.getDependencyMatrix();
+ dependencyMatrix = dependencyMatrix.age((maxTimestamp - property.getDetectionDate()) / SCALING);
+ dependencyMatrix = modifyDependencyMatrix(dependencyMatrix, impact);
+
+ VectoralProperty agedProperty = property.age(1, dependencyMatrix);
+ if (currentProperty != null) {
+ currentProperty = currentProperty.combine(agedProperty);
+ } else {
+ currentProperty = agedProperty;
+ }
+ }
+
+ return (T) new RoadInformation(currentProperty);
+ } else {
+ maxTimestamp = -1;
+ T maxFitting = null;
+ for (T t : pSimilarPointInformation) {
+ long timestamp = (long) t.getAttribute(AvailableInformationAttributes.TTL);
+
+ if (timestamp > maxTimestamp) {
+ maxTimestamp = timestamp;
+ maxFitting = t;
+ }
+ }
+
+ _lastDecision = maxFitting.getValue();
+
+ return maxFitting;
+ }
+ }
+
+ 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 + (dependencies[i][j] - finalPercentages) * pImpact;
+ }
+ }
+
+ return result;
+ }
+
+ 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));
+ }
+
+ public double determineB(double rate, double errorProbability, long ttl, double costSlow, double costFast) {
+ return determineB(rate, errorProbability, ttl, costSlow, costFast, 1);
+ }
+
+ 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;
+ }
+
+ double b;
+ double p_c = getChangeProbability((long) (ttl / rate));
+
+ int optimalAmount = getOptimalMessageAmountForSwitch(p_c, errorProbability, costSlow, costFast);
+
+ if (optimalAmount == 1) {
+ return Double.NEGATIVE_INFINITY;
+ }
+
+ boolean first = true;
+
+ double leftSide;
+ double rightSide;
+
+ double step = 5;
+
+ if (errorProbability < 0.5) {
+ b = -2 * step * reversed;
+ } else {
+ b = 2 * step * reversed;
+ }
+
+ 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;
+ }
+
+ 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;
+ }
+ }
+
+ 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 b;
+ }
+
+ 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;
+ }
+
+ 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;
+ }
+}