commit 23f0121a659c520de35865da61a6080e30fed04d
Author: Karsten Loesing <karsten.loesing(a)gmx.net>
Date: Wed Jul 25 20:23:11 2012 +0200
Add exit probability based on advertised bw (#6443).
---
task-6443/cumulated-weights.R | 9 ++-
task-6443/run.sh | 3 +
.../src/CalculatePathSelectionProbabilities.java | 93 +++++++++++++-------
3 files changed, 71 insertions(+), 34 deletions(-)
diff --git a/task-6443/cumulated-weights.R b/task-6443/cumulated-weights.R
index c324acb..811564b 100755
--- a/task-6443/cumulated-weights.R
+++ b/task-6443/cumulated-weights.R
@@ -3,7 +3,9 @@ require(scales)
require(reshape)
cw <- read.csv("cumulated-weights.csv", stringsAsFactors = FALSE)
-v <- sort(as.POSIXlt(unique(cw$validafter), tz = "UTC"),
+v <- cw
+v <- v[v$weight_type == "consensus weights", c(1, 3, 4)]
+v <- sort(as.POSIXlt(unique(v$validafter), tz = "UTC"),
decreasing = TRUE)
now <- week <- month <- threemonths <- year <- v[1]
week$mday <- week$mday - 7
@@ -32,6 +34,7 @@ opts(title = paste("Probability of selecting one of the top-x relays for",
ggsave("exit-probability-cdf-a.png", width = 8, height = 5, dpi = 100)
c <- cw
+c <- c[c$weight_type == "consensus weights", c(1, 3, 4)]
c <- c[c$top_relays %in% c(1, 2, 5, 10, 20, 50), ]
c <- aggregate(list(total_exit_probability = c$total_exit_probability),
by = list(date = as.Date(cut.Date(as.Date(c$validafter,
@@ -48,7 +51,9 @@ opts(title = paste("Probability of selecting one of the top-x relays for",
"the exit position\n"), legend.position = "bottom")
ggsave("exit-probability-cdf-b.png", width = 8, height = 5, dpi = 100)
-i <- read.csv("inverse-cumulated-weights.csv", stringsAsFactors = FALSE)
+iw <- read.csv("inverse-cumulated-weights.csv", stringsAsFactors = FALSE)
+i <- iw
+i <- i[i$weight_type == "consensus weights", c(1, 3, 4)]
i <- i[i$total_exit_probability %in% factor(c(0.3, 0.4, 0.5, 0.6, 0.7)), ]
i <- aggregate(list(top_relays = i$top_relays),
by = list(date = as.Date(cut.Date(as.Date(i$validafter,
diff --git a/task-6443/run.sh b/task-6443/run.sh
new file mode 100755
index 0000000..8ea016e
--- /dev/null
+++ b/task-6443/run.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+javac -d bin -cp lib/descriptor.jar src/CalculatePathSelectionProbabilities.java && java -cp bin:lib/descriptor.jar:lib/commons-codec-1.6.jar:lib/commons-compress-1.4.1.jar CalculatePathSelectionProbabilities
+
diff --git a/task-6443/src/CalculatePathSelectionProbabilities.java b/task-6443/src/CalculatePathSelectionProbabilities.java
index 67bb200..f819d3e 100644
--- a/task-6443/src/CalculatePathSelectionProbabilities.java
+++ b/task-6443/src/CalculatePathSelectionProbabilities.java
@@ -4,7 +4,6 @@ import java.io.FileWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
@@ -24,8 +23,8 @@ import org.torproject.descriptor.RelayNetworkStatusConsensus;
import org.torproject.descriptor.ServerDescriptor;
/*
- * Calculate five path-selection probabilities for relays based on
- * consensus weights and advertised bandwidths:
+ * Calculate path-selection probabilities for relays based on consensus
+ * weights and advertised bandwidths:
*
* - advertised_bandwidth_fraction: Relative advertised bandwidth of
* this relay compared to the total advertised bandwidth in the
@@ -54,6 +53,10 @@ import org.torproject.descriptor.ServerDescriptor;
* weights, relay flags, directory ports, and bandwidth weights in the
* consensus. Path selection depends on more factors, so that this
* probability can only be an approximation.
+ *
+ * - exit_probability_advbw: Probability of this relay to be selected for
+ * the exit position under the assumption that clients would use
+ * advertised bandwidth for path selection.
*/
public class CalculatePathSelectionProbabilities {
public static void main(String[] args) throws Exception {
@@ -99,14 +102,17 @@ public class CalculatePathSelectionProbabilities {
bw = new BufferedWriter(new FileWriter("weights.csv"));
bw.write("validafter,fingerprint,advertised_bandwidth_fraction,"
+ "consensus_weight_fraction,guard_probability,"
- + "middle_probability,exit_probability\n");
+ + "middle_probability,exit_probability,"
+ + "exit_probability_advbw\n");
}
BufferedWriter bw2 = new BufferedWriter(new FileWriter(
"cumulated-weights.csv"));
- bw2.write("validafter,top_relays,total_exit_probability\n");
+ bw2.write("validafter,weight_type,top_relays,"
+ + "total_exit_probability\n");
BufferedWriter bw3 = new BufferedWriter(new FileWriter(
"inverse-cumulated-weights.csv"));
- bw3.write("validafter,total_exit_probability,top_relays\n");
+ bw3.write("validafter,weight_type,total_exit_probability,"
+ + "top_relays\n");
while (descriptorFiles.hasNext()) {
DescriptorFile descriptorFile = descriptorFiles.next();
for (Descriptor descriptor : descriptorFile.getDescriptors()) {
@@ -155,12 +161,14 @@ public class CalculatePathSelectionProbabilities {
consensusWeights = new TreeMap<String, Double>(),
guardWeights = new TreeMap<String, Double>(),
middleWeights = new TreeMap<String, Double>(),
- exitWeights = new TreeMap<String, Double>();
+ exitWeights = new TreeMap<String, Double>(),
+ exitWeightsAdvBw = new TreeMap<String, Double>();
double totalAdvertisedBandwidth = 0.0;
double totalConsensusWeight = 0.0;
double totalGuardWeight = 0.0;
double totalMiddleWeight = 0.0;
double totalExitWeight = 0.0;
+ double totalExitWeightAdvBw = 0.0;
for (NetworkStatusEntry relay :
consensus.getStatusEntries().values()) {
String fingerprint = relay.getFingerprint();
@@ -183,6 +191,7 @@ public class CalculatePathSelectionProbabilities {
double guardWeight = (double) relay.getBandwidth();
double middleWeight = (double) relay.getBandwidth();
double exitWeight = (double) relay.getBandwidth();
+ double exitWeightAdvBw = advertisedBandwidth;
/* Case 1: relay has both Guard and Exit flag and could be
* selected for either guard, middle, or exit position. Apply
@@ -191,6 +200,7 @@ public class CalculatePathSelectionProbabilities {
guardWeight *= wgd;
middleWeight *= wmd;
exitWeight *= wed;
+ exitWeightAdvBw *= wed;
/* Case 2: relay only has the Guard flag, not the Exit flag.
* While, in theory, the relay could also be picked for the exit
@@ -203,6 +213,7 @@ public class CalculatePathSelectionProbabilities {
guardWeight *= wgg;
middleWeight *= wmg;
exitWeight = 0.0;
+ exitWeightAdvBw = 0.0;
/* Case 3: relay only has the Exit flag, not the Guard flag. It
* cannot be picked for the guard position, so set Wge to 0.
@@ -211,6 +222,7 @@ public class CalculatePathSelectionProbabilities {
guardWeight = 0.0;
middleWeight *= wme;
exitWeight *= wee;
+ exitWeightAdvBw *= wee;
/* Case 4: relay has neither Exit nor Guard flag. Similar to
* case 2, this relay *could* have a weird exit policy and be
@@ -221,6 +233,7 @@ public class CalculatePathSelectionProbabilities {
guardWeight = 0.0;
middleWeight *= wmm;
exitWeight = 0.0;
+ exitWeightAdvBw = 0.0;
}
/* Store calculated weights and update totals. */
@@ -229,11 +242,13 @@ public class CalculatePathSelectionProbabilities {
guardWeights.put(fingerprint, guardWeight);
middleWeights.put(fingerprint, middleWeight);
exitWeights.put(fingerprint, exitWeight);
+ exitWeightsAdvBw.put(fingerprint, exitWeightAdvBw);
totalAdvertisedBandwidth += advertisedBandwidth;
totalConsensusWeight += consensusWeight;
totalGuardWeight += guardWeight;
totalMiddleWeight += middleWeight;
totalExitWeight += exitWeight;
+ totalExitWeightAdvBw += exitWeightAdvBw;
}
/* Write calculated path-selection probabilities to the output
@@ -242,7 +257,8 @@ public class CalculatePathSelectionProbabilities {
for (NetworkStatusEntry relay :
consensus.getStatusEntries().values()) {
String fingerprint = relay.getFingerprint();
- bw.write(String.format("%s,%s,%.9f,%.9f,%.9f,%.9f,%.9f%n",
+ bw.write(String.format("%s,%s,%.9f,%.9f,%.9f,%.9f,%.9f,"
+ + "%.9f%n",
validAfter,
fingerprint,
advertisedBandwidths.get(fingerprint)
@@ -250,35 +266,48 @@ public class CalculatePathSelectionProbabilities {
consensusWeights.get(fingerprint) / totalConsensusWeight,
guardWeights.get(fingerprint) / totalGuardWeight,
middleWeights.get(fingerprint) / totalMiddleWeight,
- exitWeights.get(fingerprint) / totalExitWeight));
+ exitWeights.get(fingerprint) / totalExitWeight,
+ exitWeightsAdvBw.get(fingerprint)
+ / totalExitWeightAdvBw));
}
}
/* Write exit probabilities for top-x relays to the second and
* third output files. */
- List<Double> sortedExitWeights = new ArrayList<Double>(
- exitWeights.values());
- Collections.sort(sortedExitWeights);
- Collections.reverse(sortedExitWeights);
- int topRelays = 0;
- double totalExitProbability = 0.0;
- List<Double> inverseProbabilities = new ArrayList<Double>(
- Arrays.asList(new Double[] { 0.1, 0.2, 0.3, 0.4, 0.5, 0.6,
- 0.7, 0.8, 0.9 }));
- for (double exitWeight : sortedExitWeights) {
- topRelays++;
- totalExitProbability += exitWeight / totalExitWeight;
- if (topRelays <= 50) {
- bw2.write(String.format("%s,%d,%.9f%n", validAfter, topRelays,
- totalExitProbability));
- }
- while (!inverseProbabilities.isEmpty() &&
- totalExitProbability > inverseProbabilities.get(0)) {
- bw3.write(String.format("%s,%.1f,%d%n", validAfter,
- inverseProbabilities.remove(0), topRelays));
- }
- if (inverseProbabilities.isEmpty() && topRelays > 50) {
- break;
+ String[] weightTypes = new String[] { "consensus weights",
+ "advertised bandwidth" };
+ Double[][] sortedExitWeightsArray = new Double[][] {
+ exitWeights.values().toArray(new Double[exitWeights.size()]),
+ exitWeightsAdvBw.values().toArray(
+ new Double[exitWeightsAdvBw.size()]) };
+ double[] totalWeights = new double[] { totalExitWeight,
+ totalExitWeightAdvBw };
+ for (int i = 0; i < weightTypes.length; i++) {
+ String weightType = weightTypes[i];
+ Double[] sortedExitWeights = sortedExitWeightsArray[i];
+ double totalWeight = totalWeights[i];
+ Arrays.sort(sortedExitWeights);
+ int topRelays = 0;
+ double totalExitProbability = 0.0;
+ List<Double> inverseProbabilities = new ArrayList<Double>(
+ Arrays.asList(new Double[] { 0.1, 0.2, 0.3, 0.4, 0.5, 0.6,
+ 0.7, 0.8, 0.9 }));
+ for (int j = sortedExitWeights.length - 1; j >= 0; j--) {
+ double exitWeight = sortedExitWeights[j];
+ topRelays++;
+ totalExitProbability += exitWeight / totalWeight;
+ if (topRelays <= 50) {
+ bw2.write(String.format("%s,%s,%d,%.9f%n", validAfter,
+ weightType, topRelays, totalExitProbability));
+ }
+ while (!inverseProbabilities.isEmpty() &&
+ totalExitProbability > inverseProbabilities.get(0)) {
+ bw3.write(String.format("%s,%s,%.1f,%d%n", validAfter,
+ weightType, inverseProbabilities.remove(0), topRelays));
+ }
+ if (inverseProbabilities.isEmpty() && topRelays > 50) {
+ break;
+ }
}
}
}