include database php require vendor autoload php Подключаем класс для

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
include 'database.php';
require 'vendor/autoload.php';
// Подключаем класс для работы с api Vk
// описывать его его функции не имеет смысла я думаю
// просто вызовы доступных методов api и получение
// данных в удобном для нас виде
require_once('lib/VK.php');
// ID пользователя для анализа
// может быть любой, назовем его рутом
$user_id = '11851446';
// Создаем экземпляр через который будем все дергать
$vk_api = new VK();
// Получаем массив с id друзей рута
$friends = $vk_api->getUserFriends($user_id);
// Получаем n последних саписей со стены
// в данном случае 20
$feed = $vk_api->getFeedItems($user_id, 20);
// Узнаем кто и сколько лайкал последние n записей
$friends_likes = $vk_api->getLikesForUserByItems($feed, $user_id, $friends);
// Сохраняем в таблицу, чтоб при след. запуске не тратить время
Likes::create([
'user_id' => $user_id,
'likes' => serialize($friends_likes)
]);
// Добавляем в массив друзей рута его самого
$friends[] = $user_id;
// Оставляем только уникальные id друзей
$friends = array_unique($friends);
// Прохожим по всем участникам сети
foreach ($friends as $friend) {
// Если для текущего пользователя
// нет данных по его стене и количеству лайков
if (Likes::where('user_id', $friend)->count() == 0) {
// Берем n записей с его стены
$temp_feed = $vk_api->getFeedItems($friend, 20);
// Узнаем кто и сколько лайкал последние n записей
$temp_likes = $vk_api->getLikesForUserByItems($temp_feed, $friend, $friends);
// Сохраняем в таблицу, чтоб при след. запуске не тратить время
Likes::create([
'user_id' => $friend,
'likes' => serialize($temp_likes)
]);
}
}
// Теперь у нас есть данные о все участника сети
// кто и сколько раз лайкал последние n записей на стене
// из тех кто находится в друзьях у рута ну и сам рут
// Берем данные о все участниках сети
// и находим максимальное количество лайков
// кого то на какой то стене
$all_likes = Likes::all();
$max_score = 0;
foreach ($all_likes as $like) {
$other_users = unserialize($like->likes);
foreach ($other_users as $k => $v) {
if ($v > $max_score) $max_score = $v;
}
}
// Снова пробежимся по всем юзерам
// и запишем кто на кого и как влияет
foreach ($all_likes as $like) {
// Установим для каждого порог от 0 до 0.5
Thresholds::create([
'user_id' => $like->user_id,
'value' => mt_rand(1, 5) / 10
]);
$from = $like->user_id;
$other_users = unserialize($like->likes);
foreach ($other_users as $k => $v) {
if (Influences::where('from', $from)
->where('to', $k)->count() == 0) {
Influences::create([
// кто то
'from' => $from ,
// на кого то
'to' => $k,
// вот так
'score' => $v/$max_score
]);
}
}
}
// Получим все влияния
$influences = Influences::select('from')
->groupBy('from')->get()->toArray();
// Наполним массив данными
// на какое количество пользователей
// повлиял каждый юзер
$temp_data = [];
foreach ($influences as $i) {
$temp_data[$i['from']] = Influences::
where('from', $i['from'])->count();
}
// Отсортируем поубиванию
arsort($temp_data);
// На них уже повлияли
$already_affected = [];
// Кто повлиял
$who_influenced = [];
// На кого осталось повлиять
$should_affect = $temp_data;
// Кто может повлиять
$who_can_influence = $temp_data;
// Идем по всем кто может повлиять
foreach ($who_can_influence as $user => $v) {
// $user = id юзера
// $v = сколько человек может заразить один
// Берем всех кого может заразить
$temp_affected = Influences::where('from', $user)
->get()->toArray();
// пробегаемся по каждому
foreach ($temp_affected as $p) {
// для каждого получаем его порог
$thresholds = Thresholds::where('user_id', $p['to'])
->first()->value;
// если его порог меньше чем влияние юзера
if ($thresholds <= $p['score']) {
// удаляем его и того кто на него повлиял из списка
// нуждающихся в заражениии
unset($should_affect[$p['to']], $should_affect[$user]);
// Добавляем +1 к тому юзеру который заразил
if (isset($who_influenced[$user])) {
$who_influenced[$user] += 1;
} else {
$who_influenced[$user] = 1;
}
}
}
}
// Остались самые стойкие которых одному не заразить
// пробежимся по ним
foreach ($should_affect as $user_id => $v) {
// $user = id юзера
// $v = сколько человек может заразить один
// $summ_people = id пользователей которые пытаются влиять на юзера вместе
$summ_people = [];
// получаем порог стойкого юзера
$thresholds = Thresholds::where('user_id', $user_id)
->first()->value;
// получем всех кто на него пытался влиять
$temp_affected = Influences::where('to', $user_id)
->get()->toArray();
// Найдем их суммарное влияние
$sum_thresholds = 0;
foreach ($temp_affected as $a) {
// Если их сммарного влияния достаточно
// удаляем его и того кто на него повлиял из списка
// нуждающихся в заражениии
if ($sum_thresholds >= $thresholds) {
unset($should_affect[$user_id]);
foreach ($summ_people as $people) {
unset($should_affect[$people]);
if (isset($who_influenced[$people])) {
$who_influenced[$people] += 1;
} else {
$who_influenced[$people] = 1;
}
}
break;
}
$sum_thresholds += $a['score'];
$summ_people[] = $a['from'];
}
}