Commit 22d6d204 authored by Ulysse Beaugnon's avatar Ulysse Beaugnon

Betweeness centrality has been removed : it was making things much slower and...

Betweeness centrality has been removed : it was making things much slower and wasn't needed right now. We will enable it when we need it
main.ccp has been split into 3 files :
    graph.cpp for graph generation and manipulation
    results.cpp to gather the results of the simulation
    main.cpp to launch the simulation and display the results
parent cd6631b4
#include "main.h"
Graph::Graph(int size, int k, int maxPeers, mt19937 rng) :
distrib(uniform_int_distribution<int>(0, size-1)),
size(size)
{
adjacency = new vector<int>[size];
for(int i=0; i<size; i++)
{
set<int> alreadyConnected;
alreadyConnected.insert(i);
for(int j=0; j<k; j++)
{
int otherNode;
while(alreadyConnected.count(otherNode = distrib(rng)) == 1
|| otherNode > i && adjacency[otherNode].size() > maxPeers-10
|| adjacency[otherNode].size() > maxPeers)
{ }
adjacency[i].push_back(otherNode);
adjacency[otherNode].push_back(i);
}
}
}
void Graph::GetDistancesFrom(int node, int* distance)
{
for(int j=0; j<size; j++)
distance[j] = -1;
distance[node] = 0;
queue<int> remainingNodes;
remainingNodes.push(node);
while(!remainingNodes.empty())
{
int node = remainingNodes.front();
remainingNodes.pop();
for(int neighbor : adjacency[node])
if(distance[neighbor] == -1)
{
distance[neighbor] = distance[node]+1;
remainingNodes.push(neighbor);
}
}
}
// kill the last proportion*size machines of the graph
void Graph::KillMachines(float proportion)
{
// TODO
}
// To compile with -std=c++0x // To compile with -std=c++0x
// The GET_BC option might not be working
//#define GET_BC // Uncomment this line to get the betweeness centrality
#include "main.h" #include "main.h"
int n = 1000; // the number of peer int n = 1000; // the number of peer
int k = 10; // each peer try to make k connections with the others int k = 10; // each peer try to make k connections with the others
int maxPeer = 25; // no more that 25 connections per peer int maxPeer = 25; // no more that 25 connections per peer
int runs = 100; // use this to run the simulation multiple times to get more accurate values int runs = 10; // use this to run the simulation multiple times to get more accurate values
int betweenessDiv = 20; // to kown how to sample the BC. Max BC should be betweenessDiv*100
Graph::Graph(int size, int k, int maxPeers, mt19937 rng) :
distrib(uniform_int_distribution<int>(0, n-1)),
size(size)
{
adjacency = new vector<int>[size];
for(int i=0; i<size; i++)
{
set<int> alreadyConnected;
alreadyConnected.insert(i);
for(int j=0; j<k; j++)
{
int otherNode;
while(alreadyConnected.count(otherNode = distrib(rng)) == 1
|| otherNode > i && adjacency[otherNode].size() > maxPeers-10
|| adjacency[otherNode].size() > maxPeers)
{ }
adjacency[i].push_back(otherNode);
adjacency[otherNode].push_back(i);
}
}
}
void Graph::GetDistancesFrom(int node, int* distance)
{
for(int j=0; j<size; j++)
distance[j] = -1;
distance[node] = 0;
queue<int> remainingNodes;
remainingNodes.push(node);
while(!remainingNodes.empty())
{
int node = remainingNodes.front();
remainingNodes.pop();
for(int neighbor : adjacency[node])
if(distance[neighbor] == -1)
{
distance[neighbor] = distance[node]+1;
remainingNodes.push(neighbor);
}
}
}
// kill the last proportion*size machines of the graph
void Graph::KillMachines(float proportion)
{
// TODO
}
int main() int main()
{ {
mt19937 rng(time(NULL)); mt19937 rng(time(NULL));
Results results(maxPeer, 20);
// Init the parameters
double array(arityDistrib, maxPeer+1);
double array(distanceDistrib, n);
double array(betweenessDistrib, 100);
int disconnected = 0;
for(int r=0; r<runs; r++) for(int r=0; r<runs; r++)
{ {
...@@ -78,104 +17,35 @@ int main() ...@@ -78,104 +17,35 @@ int main()
cout.flush(); cout.flush();
Graph graph(n, k, maxPeer, rng); Graph graph(n, k, maxPeer, rng);
double array(betweeness, n); results.UpdateArity(graph);
// Get the arity distribution
for(int i=0; i<n; i++)
arityDistrib[graph.adjacency[i].size()]++;
// Compute the shortest path // Compute the shortest path
// TODO : optimise this
// switch to int64 ?
for(int i=0; i<graph.size; i++) for(int i=0; i<graph.size; i++)
{ {
int distance[graph.size]; int distance[graph.size];
// if(i%10==0) cout << "Computing distances from node " << i << endl;
graph.GetDistancesFrom(i, distance); graph.GetDistancesFrom(i, distance);
results.UpdateDistance(distance, graph.size);
// retrieve the distance
int maxDistance = -1;
for(int j=0; j<graph.size; j++)
if(distance[j] != -1)
{
maxDistance = max(distance[j], maxDistance);
distanceDistrib[distance[j]]++;
} }
else
disconnected++;
#ifdef GET_BC
// Get the betweeness
double toBePushed[graph.size];
for(int j=0; j<n; j++)
toBePushed[j] = 1;
// TODO : change this into a true sort ?
// run accross the nodes in the right order
// we don't need to sort them since we will only run across them a few times
for(int d=maxDistance; d>=0; d--)
for(int j=0; j<graph.size; j++)
if(distance[j] == d)
{
int nMin, min = -1;
for(int neighbor : graph.adjacency[j])
{
if(distance[neighbor] < min || min == -1)
{
min = distance[neighbor];
nMin = 1;
}
else if(distance[neighbor] == min)
nMin++;
}
double singleScore = toBePushed[j]/nMin;
for(int neighbor : graph.adjacency[j])
if(distance[neighbor] == min)
toBePushed[neighbor] += singleScore;
betweeness[j] += toBePushed[j] - 1;
}
#endif
}
#ifdef GET_BC
// Get the betweeness distribution
for(int i=0; i<n; i++)
betweenessDistrib[min((int)betweeness[i]/betweenessDiv, 99)]++;
#endif
} }
cout << "\r \r"; cout << "\r \r";
results.Finalise();
// Display the parameters we have mesured // Display the parameters we have mesured
cout << "Arity :" << endl; cout << "Arity :" << endl;
for(int i=0; i<=maxPeer; i++) for(int i=0; i<=results.maxArity; i++)
if(arityDistrib[i] != 0) if(results.arityDistrib[i] != 0)
{ cout << i << " : " << results.arityDistrib[i] << endl;
arityDistrib[i] /= (double)(n*runs);
cout << i << " : " << arityDistrib[i] << endl;
}
cout << "Distance :" << endl; cout << "Distance :" << endl;
double nLinks = n*(n-1)*runs; double nLinks = n*(n-1)*runs;
for(int i=0; i<n; i++) for(int i=0; i<= results.maxDistance; i++)
if(distanceDistrib[i] != 0) if(results.distanceDistrib[i] != 0)
{ cout << i << " : " << results.distanceDistrib[i] << endl;
distanceDistrib[i] /= nLinks - disconnected;
cout << i << " : " << distanceDistrib[i] << endl;
}
cout << "Probability that a node is not reachable : " cout << "Probability that a node is not reachable : "
<< disconnected/nLinks << results.disconnectionProba
<< " (" << disconnected << " total)" << endl; << " (" << results.disconnected << " total)" << endl;
#ifdef GET_BC
cout << "Betweeness :" << endl;
double nNodes = n*runs;
for(int i=0; i<100; i++)
if(betweenessDistrib[i] != 0)
cout << betweenessDiv*i << " -> " << betweenessDiv*(i+1) << " : "
<< betweenessDistrib[i]/nNodes << endl;
#endif
cout << endl; cout << endl;
return 0; return 0;
......
...@@ -4,11 +4,6 @@ ...@@ -4,11 +4,6 @@
#include <queue> #include <queue>
#include <set> #include <set>
#define max(a,b) a>b?a:b
#define min(a,b) a<b?a:b
#define clamp(a,b,c) max(a,min(b, c))
#define array(name, size) name[size]; for(int i=0; i<size; i++) name[i]=0;
using namespace std; using namespace std;
class Graph class Graph
...@@ -26,3 +21,28 @@ private: ...@@ -26,3 +21,28 @@ private:
uniform_int_distribution<int> distrib; uniform_int_distribution<int> distrib;
}; };
class Results
{
public:
Results(int maxArity, int maxDistance);
~Results();
void UpdateArity(const Graph& graph);
void UpdateDistance(int* distance, int nSamples);
void Finalise();
double* arityDistrib;
double* distanceDistrib;
double disconnectionProba;
double arityTooBig;
double distanceTooBig;
int64_t disconnected;
int64_t nAritySample;
int64_t nDistanceSample;
int maxArity;
int maxDistance;
private:
void AddAritySample(int arity);
void AddDistanceSample(int distance);
};
#include "main.h"
Results::Results(int maxArity, int maxDistance) :
maxArity(maxArity), maxDistance(maxDistance)
{
arityDistrib = new double[maxArity+1];
for(int i=0; i<=maxArity; i++)
arityDistrib[i] = 0;
distanceDistrib = new double[maxDistance+1];
for(int i=0; i<=maxDistance; i++)
distanceDistrib[i] = 0;
nAritySample = 0;
nDistanceSample = 0;
arityTooBig = 0;
distanceTooBig = 0;
disconnected = 0;
}
Results::~Results()
{
delete[] arityDistrib;
delete[] distanceDistrib;
}
void Results::UpdateArity(const Graph& graph)
{
for(int i=0; i<graph.size; i++)
AddAritySample(graph.adjacency[i].size());
}
void Results::UpdateDistance(int* distance, int nSamples)
{
for(int i=0; i<nSamples; i++)
AddDistanceSample(distance[i]);
}
void Results::AddAritySample(int arity)
{
if(arity <= maxArity)
arityDistrib[arity]++;
else
distanceTooBig++;
nAritySample++;
}
void Results::AddDistanceSample(int distance)
{
if(distance == -1)
disconnected++;
else if(distance <= maxDistance)
distanceDistrib[distance]++;
else
distanceTooBig++;
nDistanceSample++;
}
void Results::Finalise()
{
for(int i=0; i<=maxArity; i++)
arityDistrib[i] /= nAritySample;
for(int i=0; i<=maxDistance; i++)
distanceDistrib[i] /= nDistanceSample;
disconnectionProba = ((double)disconnected)/nDistanceSample;
distanceTooBig/= nDistanceSample;
arityTooBig /= nAritySample;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment