Robert Hailey wrote:
I don't know, it just seems like a degree-6 graph should not have node(s) with 21 connections.

Agreed, it should be very rare (though not impossible). The degree distribution should be Poisson, approximately normal for large graphs. The histogram at the end of the test code output looks about right to me - what kind of degree distribution are you getting in RealNodeTest?

Something's afowl here, the array-scanning was just my best guess when I ran out of time to track it down. Running your sim at the stats of the present network coloring test (50 nodes, degree=6), I get a graph with an average degree of about 4 and a peak connection count of 8 (not 21).

That sounds about right - the actual mean will usually be lower than the specified mean, especially in small networks, because duplicate connections are discarded.

Without Michael's forceNeighborConnections mod, it would also make quite a number of leaf nodes. I don't recall if it makes zero- connection nodes.

Again, it's possible but it should be very rare.

(Slightly updated version of the test code attached - you can now choose regular or random locations. Still no correlation between index and degree.)

Cheers,
Michael
import java.util.ArrayList;
import java.util.HashSet;

class KleinbergDegreeTest
{
	static final int NODES = 1000, DEGREE = 10, MAX_DEGREE = 20;
	static final boolean LIMIT = false, RANDOM_LOCS = true;
	
	ArrayList<Node> nodes;
	
	KleinbergDegreeTest()
	{
		nodes = new ArrayList<Node> (NODES);
		double div = 1.0 / NODES;
		double loc = 0.0;
		for (int i = 0; i < NODES; i++) {
			if (RANDOM_LOCS) nodes.add (new Node (Math.random()));
			else nodes.add (new Node (loc));
			loc += div;
		}
	}
	
	void makeKleinbergNetwork()
	{
		for (Node a : nodes) {
			// Normalise the probabilities
			double norm = 0.0;
			for (Node b : nodes) {
				if (a.location == b.location) continue;
				norm += 1.0 / distance (a, b);
			}
			// Create DEGREE/2 outgoing connections
			for (Node b : nodes) {
				if (a.location == b.location) continue;
				double p = 1.0 / distance (a, b) / norm;
				for (int i = 0; i < DEGREE / 2; i++) {
					if (Math.random() < p) {
						connect (a, b);
						break;
					}
				}
			}
		}
	}
	
	double distance (Node a, Node b)
	{
		double x = a.location, y = b.location;
		if (x > y) return Math.min (x - y, y - x + 1.0);
		else return Math.min (y - x, x - y + 1.0);
	}
	
	void connect (Node a, Node b)
	{
		if (LIMIT &&
		(a.neighbours.size() == MAX_DEGREE
		|| b.neighbours.size() == MAX_DEGREE)) return;
		a.neighbours.add (b);
		b.neighbours.add (a);
	}
	
	// Print a scatterplot of index vs degree and a histogram of degree
	void printDegreeDistribution()
	{
		int[] histogram = new int[DEGREE];
		for (int i = 0; i < NODES; i++) {
			Node n = nodes.get (i);
			System.out.println (i + " " + n.neighbours.size());
			int degree = n.neighbours.size();
			if (degree >= histogram.length) {
				int[] newHistogram = new int[degree + 1];
				for (int j = 0; j < histogram.length; j++)
					newHistogram[j] = histogram[j];
				histogram = newHistogram;
			}
			histogram[degree]++;
		}
		System.out.print ("#");
		for (int i = 0; i < histogram.length; i++)
			System.out.print (" " + histogram[i]);
		System.out.println();
	}
	
	public static void main (String[] args)
	{
		KleinbergDegreeTest kdt = new KleinbergDegreeTest();
		kdt.makeKleinbergNetwork();
		kdt.printDegreeDistribution();
	}
	
	class Node
	{
		HashSet<Node> neighbours = new HashSet<Node>();
		double location = 0.0;
		
		Node (double location)
		{
			this.location = location;
		}
	}
}
_______________________________________________
Devl mailing list
[email protected]
http://emu.freenetproject.org/cgi-bin/mailman/listinfo/devl

Reply via email to