
- •Реферат
- •Определения, обозначения, сокращения
- •Содержание
- •Введение
- •1 Аналитический обзор и постановка задачи
- •1.1 Постановка задачи
- •1.2 Структурные характеристики случайных графов
- •1.3 Модель графа с нппс
- •1.4 Обзор аналогов
- •1.4.1 Ускоренный метод генерации графа ба и графа с нппс
- •1.4.2 Метод сепарабельной реконфигурации по коэффициенту кластеризации
- •2 Разработка алгоритма
- •2.1 Обоснование необходимости разрабатываемого алгоритма
- •2.2 Описание алгоритма
- •2.3 Тестирование алгоритма
- •3 Реализации алгоритма
- •Заключение
- •Список использованных источников
- •Приложение а
- •Код программы
Приложение а
(обязательное)
Код программы
//правило предпочтительного связывания, используемое при генерации графа
class prefRuleLow implements PrefferentialAttachment {
public double f(int k) {
return m[k];
}
public int getM() {
return Integer.MAX_VALUE;
}
// для короткой выборки
double m[] = new double[] { 0, 0.027899243, 0.034518196, 0.007896482,
0.003227629, 3.876857749, 6.184930884, 7.215752698, 8.246574512,
9.277396326, 10.30821814, 11.33903995, 12.36986177, 13.40068358,
14.4315054, 15.46232721, 16.49314902, 17.52397084, 18.55479265,
19.58561447, 20.61643628, 21.64725809, 22.67807991, 23.70890172,
24.73972354, 25.77054535, 26.80136716, 27.83218898, 28.86301079,
29.89383261, 30.92465442, 31.95547623, 32.98629805, 34.01711986,
35.04794168, 36.07876349, 37.1095853, … , 2867.746287, 68.777108,
2869.80793, 2870.838752, 2871.869574, 2872.900396, 0 };
};
class prefRuleHigh implements PrefferentialAttachment {
public double f(int k) {
return m[k];
}
public int getM() {
return Integer.MAX_VALUE;
}
// для длинной выборки
double m[] = new double[] { 0, 0.295833424, 0.32163041, 0.405955373,
0.839941752, 1.481087861, 2.181159018, 2.787359496, 2.722090052,
2.818003275, 2.50672057, 2.231672154, 2.752611375, 3.312184943,
11.64285714, 15.49474669, 16.5277298, 17.56071292, 18.59369603,
19.62667914, 20.65966226, 21.69264537, 22.72562848, 23.75861159,
24.79159471, 25.82457782, 26.85756093, 27.89054405, 28.92352716,
29.95651027, 30.98949338, …, 2857.23129, 2858.264273, 59.297256,
2860.330239, 2861.363222, 2862.396206, 2863.429189, 2864.462172,
2865.495155, 2866.528138, 2867.561121, 2868.594104, 2869.627087,
2870.660071, 2871.693054, 2872.726037, 2873.75902, 2874.792003,
2875.824986, 2876.857969, 0 };
};
public class Main {
// карта слоев вершин
static Map<Integer, List<Object>> mapVertecies = new HashMap<Integer, List<Object>>();
static Map<Integer, Double> mapVilks = new HashMap<Integer, Double>();
static Random mRand = new Random();
static Factory<Object> vertexFactory = new Factory<Object>() {
public Object create() {
return new Object();
}
};
static Factory<Object> edgeFactory = new Factory<Object>() {
public Object create() {
return new Object();
}
};
// загрузка графа
static Graph getNet(String fileName) {
System.out.println(fileName);
Graph graph = new SparseGraph();
PajekNetReader<Graph<Object, Object>, Object, Object> pnr;
try {
pnr = new PajekNetReader<Graph<Object, Object>, Object, Object>(
vertexFactory, edgeFactory);
File file = new File(fileName);
pnr.load(fileName, graph);
} catch (IOException e5) {System.out.println("IOException!!!!!!!!!!!!!!!!!!");
}
System.out.println("Nodes num=" + graph.getVertexCount());
System.out.println("Edges num=" + graph.getEdgeCount());
return graph;
}
// добавление узла в соответствующий слой
static void addToLayer(Object n, int i) {
List<Object> list = mapVertecies.get(i);
if (list == null) {
list = new LinkedList<Object>();
mapVertecies.put(i, list);
}
if (!list.contains(n))
list.add(n);
}
// выбор случайного слоя
private static int getLayer() {
double tr = 0.;
int k = 0;
double rand = mRand.nextDouble();
for (int l : mapVilks.keySet()) {
tr = tr + mapVilks.get(l);
if (rand < tr) {
k = l;
break;
}
}
return k;
}
// короткая
//static double[] r= new double[]{0.0,0.35094413,0.427474478,0.082815651,0.038862743,0.099902998};
// длинная
static double[] r = new double[] { 0.00, 0.442421898, 0.457278271, 0,
0.033445638, 0.01771394, 0.009795921, 0.005440743, 0.003764738,
0.001439483, 0.001057483, 0.001174982, 0.00129248, 0.001409978,
0.023764444 };
// static double[] r=new double[]{0.0000000, 0.342114833, 0.432056333,
// 0.095997833, 0.129831,0.};
public static void main(String[] args) {
PrefferentialAttachment pa = new prefRuleHigh();
int size=80000;
System.out.println("size:"+size);
for (int i = 0; i < 100; i++) {
m5_PowerOrtGenerator gen = new m5_PowerOrtGenerator(vertexFactory, edgeFactory, r, pa);
Graph gr= gen.evolve(22961-5);
PajekNetWriter<Object, Object> gm = new PajekNetWriter<Object,
Object>(); try { gm.save(gr, new
System.out.println(i);
} catch
(IOException e) { e.printStackTrace(); }
}
}
public static void main22(String[] args) {
// генерация или загрузка графа
Graph gr = getNet("myAS.net");
System.out.println("кря");
double distances = DistanceStatistics.diameter(gr, new nweightedShortestPath(gr));
System.out.println("d="+distances);
writeNodesDegrees(gr,20);
if (true)
return;
// предпочтительного связывания
// передаются фабрики узлов и ребер, вероятности числа ребер в
// приращении 0. - что без ребер
// 0.- что 1 ребро, 1.- что 2 ребра, сумма вероятностей равна 1, также
// передается правило предпочтения
// для ускорения выбора вершин при переборе формирую слои вершин
long t0 = System.currentTimeMillis(); // засекаем время, алгоритм
// начинает работать
double sumProb = 0.;
for (Iterator<Object> iterator = gr.getVertices().iterator(); iterator
.hasNext();) {
Object v = iterator.next();
int k = gr.degree(v);
sumProb = sumProb + (k * (k - 1) / 2);// (k * (k - 1) / 2) – число сочетаний из addToLayer(v, gr.degree(v));
}
// вычисляю вероятности попадания в слой
for (int k : mapVertecies.keySet()) {
double prob = (k * (k - 1) / 2) / sumProb;
mapVilks.put(k, prob * mapVertecies.get(k).size());
}
// Точное значение коэффициента кластеризации
long t1 = System.currentTimeMillis();
int[] res = getTriAndVilk2(gr);
long dt2 = (System.currentTimeMillis() - t1);
System.out.println("С(точное)=" + 3 * res[0] / (double) res[1] + "; время расчета (мс): " + dt2);
}
public static void writeNodesDegrees(Graph<Object, Object> graph, int length) {
System.out.println("выводим степени связности");
Iterator<Object> it = graph.getVertices().iterator();
long c1 = 1;
int[] distr0 = new int[length];
int[] distr1 = new int[length];
while (it.hasNext()) {
Object node = it.next();
{
int mass[] = { graph.degree(node), 0 };
if (mass[0] < length)
distr0[mass[0]] = distr0[mass[0]] + 1;
if (mass[1] < length)
distr1[mass[1]] = distr1[mass[1]] + 1;
}
}
for (int i = 0; i < distr0.length; i++)
System.out.println(distr0[i]/((double)graph.getVertexCount()));
}
// подсчет числа вилок и треугольников
public static int[] getTriAndVilk2(Graph<Object, Object> graph) {
// перебираем все вершины
int count = 0;
int count2 = 0;
Collection<Object> list = graph.getVertices();
for (Object node : list) {
int k = 0;
for (Object link : graph.getIncidentEdges(node)) {
// if (!graph.getOpposite(node, link).isMark())
k++;
}
count2 = count2 + k * (k - 1) / 2;
Collection neig_s = graph.getNeighbors(node);
Iterator it1 = neig_s.iterator();
while (it1.hasNext()) {
Object node1 = it1.next();
Iterator it2 = neig_s.iterator();
while (it2.hasNext()) {
Object node2 = it2.next();
if ((node1 != node2) && graph.isNeighbor(node1, node2))
count++;
}
}
}
return new int[] { count / 6, count2 };
}
// генерация графа затравки, создаю неориентированный граф
static private Graph seed_graph() {
Graph gr = new UndirectedSparseMultigraph<Integer, Integer>();
for (int i = -1; i > -6; i--) {
Integer n = new Integer(i);
gr.addVertex(n);
}
int l = -1;
Object[] mass = gr.getVertices().toArray();
for (int i = 0; i < mass.length - 1; i++)
for (int j = i + 1; j < mass.length; j++)
if (i != j)
gr.addEdge(new Integer(l--), (Integer) mass[i],
(Integer) mass[j], EdgeType.UNDIRECTED);
return gr;
}
}
public class GenNonIntBA<V,E> {
private Map<Integer, List<V>> map = new HashMap<Integer, List<V>>();
protected PrefferentialAttachment attachRule;
protected Factory<V> vertexFactory;
protected Factory<E> edgeFactory;
protected double numEdgesToAttach[];
private Random mRand;
boolean parallel = false;
public GenNonIntBA(Factory<V> vertexFactory,
Factory<E> edgeFactory, double[] probEdgesToAttach, PrefferentialAttachment attachRule)
{
double s=0.;
for (double d : probEdgesToAttach) {
s=s+d;
}
assert Math.abs(s-1.)<0.000000001 : "Сумма вероятностей по различным значениям "
+ "числа добавляемых на шаге ребер должна равняться 1";
this.vertexFactory = vertexFactory;
this.edgeFactory = edgeFactory;
this.numEdgesToAttach= probEdgesToAttach;
this.attachRule =attachRule;
mRand = new Random();
}
public GenNonIntBA(Factory<V> vertexFactory,
Factory<E> edgeFactory, double[] numEdgesToAttach, boolean parallel, int seed, PrefferentialAttachment attachRule)
{
this(vertexFactory,
edgeFactory, numEdgesToAttach,attachRule);
this.parallel=parallel;
mRand = new Random(seed);
}
public Graph<V, E> evolve(int step, Graph<V, E> graph) {
maxlayer=0;
graph.getEdgeCount();
for (Iterator<V> iterator = graph.getVertices().iterator(); iterator.hasNext();) {
V v = iterator.next();
addToLayer(v, graph.degree(v));
}
for (int i = 0; i < step; i++) {
V new_n = vertexFactory.create();
Map<V, Integer> set = new HashMap<V, Integer>();
List<V> list = new ArrayList<V>();
// разыгрываю случайную величину
double s=0.;
double r=mRand.nextDouble();
int addEd =0;
for (int j = 0; j < numEdgesToAttach.length; j++) {
s=s+numEdgesToAttach[j];
if(s>r)
{
addEd = j;
break;
}
}
if(addEd>0)
do {
int k = getLayer();
V n = map.get(k).get(mRand.nextInt(map.get(k).size()));
set.put(n, new Integer(k));
list.add(n);
} while (list.size() != addEd);
graph.addVertex(new_n);
for (V n : list) {
graph.addEdge(edgeFactory.create(), new_n, n);
// переношу в соответв слой новую вершину
int tec = set.get(n);
map.get(tec).remove(n);
addToLayer(n, tec + 1);
set.put(n, tec + 1);
}
addToLayer(new_n, addEd);
}
return graph;
}
public int maxlayer=0;
private void addToLayer(V n, int i) {
List<V> list = map.get(i);
if (list == null) {
list = new LinkedList<V>();
if(maxlayer<i)maxlayer=i;
map.put(i, list);
}
if (!list.contains(n))
list.add(n);
}
private int getLayer() {
// разыгрываем
int k = 0;
double rand = mRand.nextDouble();
double tr = 0;
// считаем знаменатель
double sum = 0.0;
for (int op : map.keySet())
sum = sum + attachRule.f(op) * map.get(op).size();
for (int l : map.keySet()) {
int A = map.get(l).size();
tr = tr + ((double) A * attachRule.f(l)) / sum;
if (rand < tr) {
k = l;
break;
}
}
if(k==0){
new Exception("Big numbers");
}
return k;
}
}
class Para {
private int _n1, _n2;
Para(int n1, int n2) {
_n1 = n1;
_n2 = n2;
}
public int hashCode() {
return _n2 + _n1;
}
public boolean equals(Object o) {
return (o instanceof Para) && (_n1 == ((Para) o)._n1)
&& (_n2 == ((Para) o)._n2);
}
public Para setKK(int k1, int k2) {
_n1 = k1;
_n2 = k2;
return this;
}
}
public class m5_PowerOrtGenerator<V,E> {
Para temp = new Para(0, 0);
Map<Para, List<E>> pair_matrix = new HashMap();
Map<Integer, List<V>> map = new HashMap();
int initN = 4, addEd1 = 3;
int countN = 0, avEd = 0, avCount = 0;
Graph<V, E> graph;
int[] massMaxK = new int[100];;
int[] massVilki = new int[100];;
protected PrefferentialAttachment attachRule;
protected Factory<V> vertexFactory;
protected Factory<E> edgeFactory;
protected double numEdgesToAttach[];
public m5_PowerOrtGenerator(Factory<V> vertexFactory,
Factory<E> edgeFactory, double[] probEdgesToAttach,PrefferentialAttachment attachRule) //, PrefferentialAttachment attachRule)
{
double s=0.;
for (double d : probEdgesToAttach) {
s=s+d;
}
assert Math.abs(s-1.)<0.000000001 : "Сумма вероятностей по различным значениям "
+ "числа добавляемых на шаге ребер должна равняться 1";
this.vertexFactory = vertexFactory;
this.edgeFactory = edgeFactory;
this.numEdgesToAttach= probEdgesToAttach;
this.attachRule =attachRule;
mRand = new Random();
}
public Graph<V, E> evolve(int step){//, int m, double lyamda, Graph<V, E> graph) {
graph = new UndirectedSparseMultigraph();
int m =3;double lyamda=1;
initN = m + 1;
addEd1 = m;// количество начальных вершин
// инициализация полносвязный граф
map.put(addEd1, new LinkedList());
for (int i = 0; i < initN; i++) {
V n = vertexFactory.create();
graph.addVertex(n);
List<V> list = map.get(addEd1);
list.add(n);
++countN;
}
Object[] mass = graph.getVertices().toArray();
for (int i = 0; i < mass.length - 1; i++)
for (int j = i + 1; j < mass.length; j++) {
E link = edgeFactory.create();
graph.addEdge(link, (V) mass[i], (V) mass[j],
EdgeType.UNDIRECTED);
}
mRand = new Random();
//поместить в матрицу ребер
for (E l0 : graph.getEdges()) {
Pair<V> pa = graph.getEndpoints(l0);
int min = graph.degree(pa.getFirst());
int max = graph.degree(pa.getSecond());
Para temp = null;
if (min > max)
add2pair(max, min, l0);
else
add2pair(min, max, l0);
}
// обращаюсь к матрице и нахожу одно из рёбер, тем самым и требуемых два
// и требуемых два узла остальные узлы беру случайно.
for (int i = 0; i < step; i++) {
Map<V, Integer> set = new HashMap();
// разыгрываю две случайные величины, определяющие номера слоёв
int k1 = 0, k2 = 0;
double r = mRand.nextDouble();
E p = null;
V n1, n2;
boolean b = true;
// массив выбранных индексов
double s=0.;
double r1=mRand.nextDouble();
int addEd =0;
for (int j = 0; j < numEdgesToAttach.length; j++) {
s=s+numEdgesToAttach[j];
if(s>r1)
{
addEd = j;
break;
}
}
if(addEd==0)System.out.println("нулевая вершин");
int[] indexes = new int[addEd];
do {
for (int j = 0; j < indexes.length; j++) {
indexes[j] = getKLogT();
}
Arrays.sort(indexes);
// на основе индексов обращаюсь к матрице и формирую список
// ребер для выбора
List<E> listLink_ = new LinkedList();
for (int j = 0; j < indexes.length - 1; j++) {
for (int k = j + 1; k < indexes.length; k++) {
Para pr = new Para(indexes[j], indexes[k]);
if (pair_matrix.get(pr) != null
&& pair_matrix.get(pr).size() > 0)
listLink_.addAll(pair_matrix.get(pr));
}
}
n1 = null;
n2 = null;
if ((mRand.nextDouble()<=lyamda)&&(listLink_.size() > 0)) {
// if ((listLink_.size() > 0)) {
p = listLink_.get(mRand.nextInt(listLink_.size()));
if (p == null)
System.out.println("ff");
Pair<V> par = graph.getEndpoints(p);
int i1 = graph.degree(par.getFirst());
int i2 = graph.degree(par.getSecond());
boolean b1 = true, b2 = true;
for (int j = 0; j < indexes.length; j++) {
if (indexes[j] == i1 && b1) {
k1 = j;
b1 = false;
continue;
}
if (indexes[j] == i2 && b2) {
k2 = j;
b2 = false;
continue;
}
}
} else {
int i1 = mRand.nextInt(indexes.length);
int i2 = i1;
do
i2 = mRand.nextInt(indexes.length);
while (i2 == i1&&(indexes.length>1));//пока они равны и длина >1
k1 = i1;
k2 = i2;
n1 = map.get(indexes[i1]).get(
mRand.nextInt(map.get(indexes[i1]).size()));
n2 = map.get(indexes[i2]).get(
mRand.nextInt(map.get(indexes[i2]).size()));
}
listLink_.clear();
} while ((p == null) && (n1 == n2));
Pair<V> pair;
if (p != null) {
pair = graph.getEndpoints(p);
} else
pair = new Pair(n1, n2);
Set<E> setLink = new HashSet();
List<V> listNodes = new LinkedList();
listNodes.add(pair.getFirst());
if(indexes.length>1)listNodes.add(pair.getSecond());
// формирую список узлов
for (int j = 0; j < indexes.length; j++) {
if (j != k1 && j != k2)
listNodes.add(map.get(indexes[j]).get(
mRand.nextInt(map.get(indexes[j]).size())));
}
// формирую список рёбер
for (Iterator iterator = listNodes.iterator(); iterator.hasNext();) {
V myNode = (V) iterator.next();
Collection<E> list_j = graph.getIncidentEdges(myNode);
for (Iterator<E> it = list_j.iterator(); it.hasNext();) {
E link = it.next();
setLink.add(link);
}
}
// удаляю из списка вершин
for (Iterator iterator = listNodes.iterator(); iterator.hasNext();) {
V myNode = (V) iterator.next();
map.get(graph.degree(myNode)).remove(myNode);
}
// удаляю из списка рёбер
for (E l0 : setLink) {
Pair<V> pa = graph.getEndpoints(l0);
int min = graph.degree(pa.getFirst());
int max = graph.degree(pa.getSecond());
Para temp = null;
if (min > max)
temp = new Para(max, min);
else
temp = new Para(min, max);
pair_matrix.get(temp).remove(l0);
}
// добавить цикл по всему списку новых рёбер
V new_n = vertexFactory.create();
// добавляю рёбра
Map<E, V> newEdges = new HashMap<E, V>();
for (Iterator iterator = listNodes.iterator(); iterator.hasNext();) {
V myNode = (V) iterator.next();
E l1 = edgeFactory.create();
newEdges.put(l1, myNode);
graph.addEdge(l1, new_n, myNode);
}
// переношу в соответв слой новую вершину
// добавить цикл по всему списку новых вершин
listNodes.add(new_n);
for (Iterator iterator = listNodes.iterator(); iterator.hasNext();) {
V myNode = (V) iterator.next();
addToLayer(myNode, graph.degree(myNode));
}
// добавить цикл по всему списку новых вершин
for (E li : newEdges.keySet()) {
int min = addEd;
int max = graph.degree(newEdges.get(li));
if (min > max)
add2pair(max, min, li);
else
add2pair(min, max, li);
}
for (E l0 : setLink) {
Pair<V> pa = graph.getEndpoints(l0);
int min = graph.degree(pa.getFirst());
int max = graph.degree(pa.getSecond());
if (min > max)
add2pair(max, min, l0);
else
add2pair(min, max, l0);
}
}
return graph;
}
private void add2pair(int min, int max, E link) {
Para para = new Para(min, max);
List<E> p = pair_matrix.get(para);
if (p == null) {
p = new ArrayList();
pair_matrix.put(para, p);
}
p.add(link);
}
Random mRand = new Random();
private int getKLog() {
// разыгрываем
int k = 0;
double rand = mRand.nextDouble();
double tr = 0;
for (int l : map.keySet()) {
int A = map.get(l).size();
tr = tr + (A / (double) avCount) * l/ ((double) 2 * avEd / (double) avCount);
if (rand < tr) {
k = l;
break;
}
}
return k;
}
double f(int k) {
return attachRule.f(k);
}
private int getKLogT() {
// разыгрываем
int k = 0;
double rand = mRand.nextDouble();
double tr = 0;
// считаем знаменатель
double sum = 0.0;
for (int op : map.keySet())
sum = sum + f(op) * map.get(op).size();
double sum2 = 0.0;
// находим k
for (int l : map.keySet()) {
int A = map.get(l).size();
// if((A*f(l))/sum<0)System.out.println("отриц");
tr = tr + ((double) A * f(l)) / sum;
if (rand < tr) {
k = l;
break;
}
}
if (k == 0)
System.out.println("косяк" + tr);
return k;
}
private void addToLayer(V n, int i) {
List<V> list = map.get(i);
if (list == null) {
list = new LinkedList();
map.put(i, list);
}
if (!list.contains(n))
list.add(n);
}
public static void main77(String[] args) {
Factory<Integer> edgeFactory = new Factory<Integer>() {
int i = 0;
public Integer create() {
return new Integer(i++);
}
};
Factory<UndirectedSparseMultigraph<Integer, Integer>> gFactory = new Factory<UndirectedSparseMultigraph<Integer, Integer>>() {
public UndirectedSparseMultigraph<Integer, Integer> create() {
return new UndirectedSparseMultigraph<Integer, Integer>();
}
};
Factory<Integer> nodeFactory = new Factory<Integer>() {
int i = 0;
public Integer create() {
return new Integer(i++);
}
};
double [] mass =new double[]{0,0,1};
m5_PowerOrtGenerator gen = new m5_PowerOrtGenerator<Integer,Integer>(nodeFactory, edgeFactory, mass,null);
gen.evolve(1000);
gen.step_svyaz(100);
}
void step_svyaz(int length){
System.out.println("выводим степени связности");
Iterator<V> it = graph.getVertices().iterator();
long c1 = 1;
int[] distr0= new int[length];
int[] distr1= new int[length];
while (it.hasNext()) {
V node = it.next();
//int[] mass = getR2R2(node);
int mass[]={graph.degree(node),0};
if(mass[0]<length)distr0[mass[0]]=distr0[mass[0]]+1;
if(mass[1]<length)distr1[mass[1]]=distr1[mass[1]]+1;
}
for(int i=0; i<distr0.length; i++)
System.out.println(distr0[i]);
}
int[] getMassMaxK() {
return massMaxK;
}
int[] getVilki() {
return massVilki;
}
public int getVilk() {
int vilk = 0;
// считаем во скольких вилках центом является узел заданной связности
// как число перестановок из k по
for (Map.Entry<Integer, List<V>> set : map.entrySet()) {
int k = set.getKey();
vilk = vilk + (int) set.getValue().size() * k * (k - 1) / 2;
}
return vilk;
}
}