From d03603ae8352684408201c43dd1dec5f789041a0 Mon Sep 17 00:00:00 2001 From: Tobias Meuser Date: Fri, 20 Apr 2018 10:16:31 +0200 Subject: [PATCH] Current version for Ad-Hoc Networks --- .../caching/DefaultCachingComponent.java | 3 + .../AveragingCacheDecisionStrategy.java | 71 ++++ .../decision/CacheDecisionStrategyType.java | 2 +- ...tyVotingVectoralCacheDecisionStrategy.java | 77 +++++ .../TTLbasedCacheDecisionStrategy.java | 1 + ...TTLbasedVectoralCacheDecisionStrategy.java | 321 ++++++++++++++++++ 6 files changed, 474 insertions(+), 1 deletion(-) create mode 100755 src/de/tud/kom/p2psim/impl/vehicular/caching/decision/AveragingCacheDecisionStrategy.java create mode 100755 src/de/tud/kom/p2psim/impl/vehicular/caching/decision/MajorityVotingVectoralCacheDecisionStrategy.java create mode 100755 src/de/tud/kom/p2psim/impl/vehicular/caching/decision/TTLbasedVectoralCacheDecisionStrategy.java 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 d6dff3f4..a7efe63f 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 00000000..a793b606 --- /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 6499ddf4..70240818 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 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 00000000..56fccdbe --- /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 4309e925..d899db80 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 00000000..ad05c7f8 --- /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; + } +} -- GitLab