
- •Бакалаврская работа
- •Пояснительная записка
- •Аннотация
- •Определения, обозначения, сокращения
- •1 Аналитический обзор и постановка задачи
- •1.1 Структурные характеристики случайных графов
- •1.2 Некоторые модели случайных графов
- •1.2.1 Модель графа Барабаши ‑ Альберт
- •1.2.2 Модель графа Уаттса – Строгатца
- •1.2.3 Модель графа Эрдеша-Реньи
- •1.3 Модель графа с нппс
- •1.4 Обзор аналогов
- •1.4.1 Ускоренный метод генерации графа ба и графа с нппс
- •1.4.2 Метод сепарабельной реконфигурации по коэффициенту кластеризации
- •1.5 Выводы по главе и постановка задачи вкр
- •2 Разработка алгоритма генератора графа с нппс с возможностью калибровки по коэффициенту кластеризации
- •2.1 Алгоритм генерации графа с нппс с возможностью калибровки по коэффициенту кластеризации
- •2.2. Модификация разработанного алгоритма
- •2.3 Демонстрация работы алгоритма
- •3 Аспекты программной реализации в системе имитационного моделирования Simbigraph
- •Заключение
- •Список использованных источников
- •Приложение а
Приложение а
(обязательное)
Листинг алгоритма с гарантированным появлением хотя бы одного треугольника при присоединении новой вершины.
import edu.uci.ics.jung.algorithms.generators.random.BarabasiAlbertGenerator;
import edu.uci.ics.jung.graph.DirectedSparseMultigraph;
import edu.uci.ics.jung.graph.Graph;
import edu.uci.ics.jung.graph.UndirectedSparseMultigraph;
import edu.uci.ics.jung.graph.util.EdgeType;
import edu.uci.ics.jung.graph.util.Pair;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
public class m6_PowerOrtGenerator<V,E> {
Para temp = new Para(0, 0);
Map<Para, List<E>> pair_matrix = new HashMap();
Map<Integer, List<V>> mapLayers = new HashMap();
int initN = 4;// addEd1 = 3;
Graph<V, E> graph;
protected PrefferentialAttachment attachRule;
protected Factory<V> vertexFactory;
protected Factory<E> edgeFactory;
protected double numEdgesToAttach[];
public m6_PowerOrtGenerator(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 Graph<V, E> evolve(int step){//, int m, double lyamda, Graph<V, E> graph)
graph = new UndirectedSparseMultigraph();
int m =3;
initN = m + 1;
// инициализация полносвязного графа и добавление в слои
mapLayers.put(m, new LinkedList());
for (int i = 0; i < initN; i++) {
V n = vertexFactory.create();
graph.addVertex(n);
List<V> list = mapLayers.get(m);
list.add(n);
}
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);
}
//поместить все рёбра в матрицу рёбер
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;
add2pair(max, min, l0);
}
// Обращаемся к матрице. Находим одно из рёбер и, тем самым,
// находим два требуемых узла. Остальные берём случайно
for (int i = 0; i < step; i++)
{
// разыгрываем две случайные величины, определяющие номера слоёв
int addEd= getNumAttachToAttach();
if(addEd==0)System.out.println("нельзя вершин без узлов");
// массив выбранных индексов
int[] indexes = new int[addEd];
Set<E> setLink = new HashSet();
List<V> listNodes = new LinkedList();
Map<Pair<V>,Pair<Integer>> mapPairs = new HashMap();
formConPairVert(indexes,mapPairs);
Pair<V> pair= mapPairs.keySet().iterator().next();
// получаем список узлов для присоединения
listNodes.add(pair.getFirst());
if(indexes.length>1)listNodes.add(pair.getSecond());
for (int j = 0; j < indexes.length; j++)
{
//из тех, чьи индексы не вошли в Map
Iterator<Pair<Integer>> it=mapPairs.values().iterator();
boolean isUse= false;
while (it.hasNext()){
Pair<Integer> pairK= it.next();
int k1=pairK.getFirst(), k2=pairK.getSecond();
if (j ==k1||j ==k2 )isUse = true;
}
if(!isUse)
listNodes.add(mapLayers.get(indexes[j]).get(
mRand.nextInt(mapLayers.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();
mapLayers.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));
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());
add2pair(min, max, l0);
}
}
return graph;
}
private void formConPairVert(int[] indexes, Map<Pair<V>,Pair<Integer>> map) {
int k1 = 0, k2 = 0;
V n1 = null, n2 = null;
E p = null;
do {
for (int j = 0; j < indexes.length; j++) {
indexes[j] = getK();
}
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 ((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 = mapLayers.get(indexes[i1]).get(
mRand.nextInt(mapLayers.get(indexes[i1]).size()));
n2 = mapLayers.get(indexes[i2]).get(
mRand.nextInt(mapLayers.get(indexes[i2]).size()));
}
listLink_.clear();
} while ((p == null) && (n1 == n2));
Pair<V> pair1;
if (p != null) {
pair1 = graph.getEndpoints(p);
} else
pair1 = new Pair(n1, n2);
Pair<Integer> pair2 =new Pair(k1, k2);
map.put(pair1, pair2);
}
private int getNumAttachToAttach() {
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;
}
}
return addEd;
}
private void add2pair(int min, int max, E link) {
if (min > max)
{
int temp= max;
max=min;
min=temp;
}
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();
double f(int k) {
return attachRule.f(k);
}
private int getK() {
// разыгрываем
int k = 0;
double rand = mRand.nextDouble();
double tr = 0;
// считаем знаменатель
double sum = 0.0;
for (int op : mapLayers.keySet())
sum = sum + f(op) * mapLayers.get(op).size();
double sum2 = 0.0;
for (int l : mapLayers.keySet()) {
int A = mapLayers.get(l).size();
tr = tr + ((double) A * f(l)) / sum;
if (rand < tr) {
k = l;
break;
}
}
return k;
}
private void addToLayer(V n, int i) {
List<V> list = mapLayers.get(i);
if (list == null) {
list = new LinkedList();
mapLayers.put(i, list);
}
if (!list.contains(n))
list.add(n);
}
}
Листинг алгоритма с разбиением вершин для присоединения на пары, из которых производится поиск двух связных вершин (что обеспечивает образование треугольника при присоединении).
import edu.uci.ics.jung.algorithms.generators.random.BarabasiAlbertGenerator;
import edu.uci.ics.jung.graph.DirectedSparseMultigraph;
import edu.uci.ics.jung.graph.Graph;
import edu.uci.ics.jung.graph.UndirectedSparseMultigraph;
import edu.uci.ics.jung.graph.util.EdgeType;
import edu.uci.ics.jung.graph.util.Pair;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
public class m7_PowerOrtGenerator<V,E> {
Para temp = new Para(0, 0);
Map<Para, List<E>> pair_matrix = new HashMap();
Map<Integer, List<V>> mapLayers = new HashMap();
int initN = 4;// addEd1 = 3;
Graph<V, E> graph;
protected PrefferentialAttachment attachRule;
protected Factory<V> vertexFactory;
protected Factory<E> edgeFactory;
protected double numEdgesToAttach[];
int maxlayer=0;
public m7_PowerOrtGenerator(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 Graph<V, E> evolve(int step){//, int m, double lyamda, Graph<V, E> graph)
maxlayer=0;
graph = new UndirectedSparseMultigraph();
int m =3;
initN = m + 1;
// Инициализация полносвязного графа. Добавление в слои
mapLayers.put(m, new LinkedList());
for (int i = 0; i < initN; i++) {
V n = vertexFactory.create();
graph.addVertex(n);
List<V> list = mapLayers.get(m);
list.add(n);
}
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);
}
//Помещаем все рёбра в матрицу рёбер
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;
add2pair(max, min, l0);
}
// Обращаемся к матрице. Находим одно из рёбер и, тем самым,
// находим два требуемых узла. Остальные берём случайно
for (int i = 0; i < step; i++) {
// разыгрываем две случайные величины, определяющие номера слоёв
int addEd= getNumAttachToAttach();
if(addEd==0)System.out.println("нельзя вершин без узлов");
// массив выбранных индексов
int[] indexes = new int[addEd];
Set<E> setLink = new HashSet();
List<V> listNodes = new LinkedList();
Map<Pair<V>,Para> mapPairs = new HashMap<Pair<V>,Para>();
for (int j = 0; j < indexes.length; j++) {
indexes[j] = getK();
if(indexes[j]>maxlayer)maxlayer =indexes[j];
}
formConPairVert(indexes,listNodes);
// формируем список рёбер, которых затронут изменения
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();
mapLayers.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));
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());
add2pair(min, max, l0);
}
}
System.out.println("^^"+count);
return graph;
} int count=0;
private void formConPairVert(int[] m, List<V> listNodes) {
int k1,k2;
Set<E> set = new HashSet();
if(m.length>1){
for (int i = 0; i < m.length/2; i++) {
if(m[i]>m[m.length/2+i]) {k1 = m[ m.length/2+i]; k2= m[i];}
else {k1 = m[i]; k2= m[ m.length/2+i];}
Para pr = new Para(k1, k2);
List<E> list =pair_matrix.get(pr);
E edge = null;
if(list!=null){
count++;
for (E e : list) {
if(!set.contains(e))
edge = e;
set.add(edge);
break;
}
}
if (edge != null) {
Pair<V> pair2= graph.getEndpoints(edge);
listNodes.add(pair2.getFirst());
listNodes.add(pair2.getSecond());
} else
{
V n1 = mapLayers.get(k1).get(
mRand.nextInt(mapLayers.get(k1).size()));
V n2 = mapLayers.get(k2).get(
mRand.nextInt(mapLayers.get(k2).size()));
listNodes.add(n1);
listNodes.add(n2);
}
}
// если есть нечётное ребро
if(m.length%2==1)
listNodes.add(mapLayers.get(m[m.length-1]).get( mRand.nextInt(mapLayers.get(m[m.length-1]).size())));
}
//если ребро одно
else {
listNodes.add(mapLayers.get(m[0]).get(
mRand.nextInt(mapLayers.get(m[0]).size())));
}
}
private int getNumAttachToAttach() {
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;
}
}
return addEd;
}
private void add2pair(int min, int max, E link) {
if (min > max)
{
int temp= max;
max=min;
min=temp;
}
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();
double f(int k) {
return attachRule.f(k);
}
private int getK() {
// разыгрываем
int k = 0;
double rand = mRand.nextDouble();
double tr = 0;
// считаем знаменатель
double sum = 0.0;
for (int op : mapLayers.keySet())
sum = sum + f(op) * mapLayers.get(op).size();
double sum2 = 0.0;
for (int l : mapLayers.keySet()) {
int A = mapLayers.get(l).size();
tr = tr + ((double) A * f(l)) / sum;
if (rand < tr) {
k = l;
break;
}
}
return k;
}
private void addToLayer(V n, int i) {
List<V> list = mapLayers.get(i);
if (list == null) {
list = new LinkedList();
mapLayers.put(i, list);
}
if (!list.contains(n))
list.add(n);
}
}
1Аналогично, на основе анализа BGP таблиц можно получить граф, представляющий собой мгновенный снимок сети автономных систем Интернет