Author: mrogers
Date: 2006-10-08 21:19:49 +0000 (Sun, 08 Oct 2006)
New Revision: 10653

Added:
   trunk/apps/load-balancing-sims/kleinberg-attack/
   trunk/apps/load-balancing-sims/kleinberg-attack/Node.java
   trunk/apps/load-balancing-sims/kleinberg-attack/Sim.java
Modified:
   trunk/apps/load-balancing-sims/routing.txt
Log:
Some quick and dirty simulations of random and targetted node removal in 
Kleinberg networks

Added: trunk/apps/load-balancing-sims/kleinberg-attack/Node.java
===================================================================
--- trunk/apps/load-balancing-sims/kleinberg-attack/Node.java   2006-10-08 
20:49:08 UTC (rev 10652)
+++ trunk/apps/load-balancing-sims/kleinberg-attack/Node.java   2006-10-08 
21:19:49 UTC (rev 10653)
@@ -0,0 +1,73 @@
+import java.util.HashSet;
+
+class Node
+{
+       private HashSet<Node> neighbours;
+       private double location;
+       
+       public Node (double location)
+       {
+               neighbours = new HashSet<Node>();
+               this.location = location;
+       }
+       
+       public void connect (Node n)
+       {
+               if (n == this || neighbours.contains (n)) return;
+               neighbours.add (n);
+       }
+       
+       public void disconnect (Node n)
+       {
+               neighbours.remove (this);
+       }
+       
+       public void die()
+       {
+               for (Node n : neighbours) n.disconnect (this);
+               neighbours.clear();
+       }
+       
+       // Return the length of the longest link
+       public double longestDistance()
+       {
+               double best = 0.0;
+               for (Node n : neighbours) {
+                       double d = distance (location, n.location);
+                       if (d > best) best = d;
+               }
+               return best;
+       }
+       
+       // Return the total length of all links
+       public double totalDistance()
+       {
+               double d = 0.0;
+               for (Node n : neighbours) d += distance (location, n.location);
+               return d;
+       }
+       
+       public Node route (Node dest)
+       {
+               if (dest == this) return null;
+               Node bestNeighbour = null;
+               double bestDistance = Double.POSITIVE_INFINITY;
+               for (Node n : neighbours) {
+                       double d = distance (n.location, dest.location);
+                       if (d < bestDistance) {
+                               bestNeighbour = n;
+                               bestDistance = d;
+                       }
+               }
+               if (bestDistance < distance (location, dest.location))
+                       return bestNeighbour;
+               else return null;
+       }
+       
+       // Return the circular distance between two locations
+       public static double distance (double a, double b)
+       {
+               if (a > b) return Math.min (a - b, b - a + 1.0);
+               else return Math.min (b - a, a - b + 1.0);
+       }
+}

Added: trunk/apps/load-balancing-sims/kleinberg-attack/Sim.java
===================================================================
--- trunk/apps/load-balancing-sims/kleinberg-attack/Sim.java    2006-10-08 
20:49:08 UTC (rev 10652)
+++ trunk/apps/load-balancing-sims/kleinberg-attack/Sim.java    2006-10-08 
21:19:49 UTC (rev 10653)
@@ -0,0 +1,109 @@
+class Sim
+{
+       private final static int NODES = 1000;
+       private final static int DEGREE = 20;
+       private final static int DEATHS = 30;
+       private final static int TRIALS = 1000;
+       
+       private Node[] nodes;
+       
+       public Sim()
+       {
+               nodes = new Node[NODES];
+               for (int i = 0; i < NODES; i++)
+                       nodes[i] = new Node (1.0 / NODES * i);
+               
+               // Calculate the normalising constant
+               double norm = 0.0;
+               for (int i = 1; i < NODES; i++)
+                       norm += 1.0 / latticeDistance (0, i);
+               
+               // Add DEGREE shortcuts per node, randomly with replacement
+               double outDegree = DEGREE * 0.5;
+               for (int i = 0; i < NODES; i++) {
+                       for (int j = 0; j < NODES; j++) {
+                               if (i == j) continue;
+                               double p = 1.0 / latticeDistance (i, j) / norm;
+                               for (int k = 0; k < outDegree; k++) {
+                                       if (Math.random() < p) {
+                                               nodes[i].connect (nodes[j]);
+                                               nodes[j].connect (nodes[i]);
+                                               break;
+                                       }
+                               }
+                       }
+               }
+       }
+       
+       // Remove a randomly chosen node from the network
+       private void killRandomNode()
+       {
+               int i = (int) (Math.random() * NODES);
+               while (nodes[i] == null) i = (int) (Math.random() * NODES);
+               nodes[i].die();
+               nodes[i] = null;
+       }
+       
+       // Remove the node with the longest links from the network
+       private void killBestNode()
+       {
+               int bestIndex = 0;
+               double bestDistance = Double.NEGATIVE_INFINITY;
+               for (int i = 0; i < NODES; i++) {
+                       if (nodes[i] == null) continue;
+                       double d = nodes[i].totalDistance();
+                       // double d = nodes[i].longestDistance();
+                       if (d > bestDistance) {
+                               bestIndex = i;
+                               bestDistance = d;
+                       }
+               }
+               nodes[bestIndex].die();
+               nodes[bestIndex] = null;
+       }
+       
+       // Route a message from a random source to a random destination, without
+       // backtracking. If the message arrives, return the number of hops. If
+       // the message does not arrive, return zero minus the number of hops.
+       private int route()
+       {
+               Node n = null, dest = null;
+               while (n == null) n = nodes[(int) (Math.random() * NODES)];
+               while (dest == null) dest = nodes[(int) (Math.random() *NODES)];
+               int hops;
+               for (hops = 0; n != dest && n != null; hops++)
+                       n = n.route (dest);
+               if (n == null) return -hops;
+               else return hops;
+       }
+       
+       // Return the Kleinberg lattice distance between a and b
+       private int latticeDistance (int a, int b)
+       {
+               if (a > b) return Math.min (a - b, b - a + NODES);
+               else return Math.min (b - a, a - b + NODES);
+       }
+       
+       public static void main (String[] args)
+       {
+               double successes = 0.0;
+               double successHops = 0.0;
+               double failureHops = 0.0;
+               Sim s = new Sim();
+               
+               for (int i = 0; i < DEATHS; i++) s.killBestNode();
+               // for (int i = 0; i < DEATHS; i++) s.killRandomNode();
+               
+               for (int i = 0; i < TRIALS; i++) {
+                       int hops = s.route();
+                       if (hops >= 0) {
+                               successes++;
+                               successHops += hops;
+                       }
+                       else failureHops -= hops;
+               }
+               System.out.println ("success rate " + (successes/TRIALS));
+               System.out.println ("success hops " + (successHops/successes));
+               System.out.println ("failure hops " + 
(failureHops/(TRIALS-successes)));
+       }
+}

Modified: trunk/apps/load-balancing-sims/routing.txt
===================================================================
--- trunk/apps/load-balancing-sims/routing.txt  2006-10-08 20:49:08 UTC (rev 
10652)
+++ trunk/apps/load-balancing-sims/routing.txt  2006-10-08 21:19:49 UTC (rev 
10653)
@@ -16,7 +16,7 @@
 If this is the closest node so far, update closest location and reset htl
 Send Accepted
 If data is in store or cache:
-  If key is an SSK, send DataFound and SSKPubKey if requested, return
+  If key is an SSK, send SSKDataFound and SSKPubKey if requested, return
   If key is a CHK, start a new BlockTransmitter and return
 If there's a transferring RequestSender with the same key, coalesce
 Otherwise if htl==0, send DataNotFound and return
@@ -134,7 +134,7 @@
 Wait 60 seconds for DataNotFound, RouteNotFound, RejectedOverload, SSKPubKey, 
CHKDataFound or SSKDataFound
   If peer disconnects, try another peer
   If wait times out, back off and return TIMED_OUT
-  If DataNotFound, return data not found
+  If DataNotFound, return DATA_NOT_FOUND
   If RouteNotFound, let htl=min(htl,newHtl) and try another peer
   If local RejectedOverload, back off and try another peer
   If non-local RejectedOverload, forward it


Reply via email to