Skip to content
Snippets Groups Projects
Commit 56a37278 authored by Abd Errahmane Kiouche's avatar Abd Errahmane Kiouche :speech_balloon:
Browse files

Upload New File

parent f18e5224
No related branches found
No related tags found
No related merge requests found
//
// Created by Kiouche on 1/20/2020.
//
#include "p_k_compression.h"
#include <chrono>
#include <map>
#include <list>
#include <iostream>
#include <algorithm>
#include <random>
#include <queue>
#include "hash.h"
namespace std {
bool test_insert(edge &e, bool directed,graph &constructed_graph,graph &compressed_graph ,int k, vector<double> &p){
uint32_t first, second;
first = e.first;
second = e.second;
if(!directed) {
if (constructed_graph[e.first].size() > constructed_graph[e.second].size()) {
first = e.second;
second = e.first;
}
}
bool insert = BFS(first,compressed_graph,constructed_graph,p,k);
if ( insert){
return true;
}
else if (!directed) {
return BFS(second,compressed_graph,constructed_graph,p,k);
}
else return insert;
}
void get_neighbors(uint32_t node, graph &g,unordered_map<int,unordered_set<uint32_t>> &neighbors,
int &maxDepth){
// Mark all the vertices as not visited
unordered_map<uint32_t , int> node_visited;
// Create a queue for BFS
deque<uint32_t> queue;
// array_queue *queue = new array_queue();
// Mark the current node as visited and enqueue it
node_visited[node]= 1;
queue.push_back(node);
int currentDepth = 1,
elementsToDepthIncrease = 1,
nextElementsToDepthIncrease = 0;
while(!queue.empty()) {
// Dequeue a vertex from queue and print it
uint32_t s = queue.front();
queue.pop_front();
// node_visited[s] = 1;
for (auto &v : g[s]){
if (node_visited[v]==0) {
nextElementsToDepthIncrease++;
node_visited[v]=1;
queue.push_back(v);
for (int i = currentDepth; i <= maxDepth; i++) neighbors[i].insert(v);
}
}
if (--elementsToDepthIncrease == 0) {
if (++currentDepth > maxDepth) break;
elementsToDepthIncrease = nextElementsToDepthIncrease;
nextElementsToDepthIncrease = 0;
}
}
}
bool check_constraints(graph &original_graph,graph &compressed_graph,vector<double> p, int k){
for (auto v : original_graph){
unordered_map<int,unordered_set<uint32_t>> n_v;
get_neighbors(v.first,compressed_graph,n_v,k);
for (int i=1;i<= k;i++){
unordered_set<uint32_t> nghs = intersection( n_v[i],original_graph[v.first]);
if ((double) nghs.size() < v.second.size()*p.at(i)){
cout << i << "---" << v.first << " " << nghs.size() << " "
<< v.second.size() << endl;
return false;
}
}
}
return true;
}
bool BFS(uint32_t node, graph &g,graph &constructed_graph,vector<double> &p,int &maxDepth){
unordered_map<int,unordered_set<uint32_t>> neighbors;
// Mark all the vertices as not visited
unordered_map<uint32_t , int> node_visited;
// Create a queue for BFS
deque<uint32_t> queue;
// Mark the current node as visited and enqueue it
node_visited[node]= 1;
queue.push_back(node);
int currentDepth = 1,
elementsToDepthIncrease = 1,
nextElementsToDepthIncrease = 0;
while(!queue.empty()) {
// Dequeue a vertex from queue and print it
uint32_t s = queue.front();
queue.pop_front();
for (auto &v : g[s]){
if (node_visited[v]==0) {
nextElementsToDepthIncrease++;
node_visited[v]=1;
queue.push_back(v);
for (int i = currentDepth; i <= maxDepth; i++) neighbors[i].insert(v);
}
}
if (--elementsToDepthIncrease == 0) {
double nb_nghrs = constructed_graph[node].size();
unordered_set<uint32_t> s_neighbors = intersection( neighbors[currentDepth],constructed_graph[node]);
if ((double) s_neighbors.size() < nb_nghrs * p.at(currentDepth)) return true;
if (++currentDepth > maxDepth) break;
elementsToDepthIncrease = nextElementsToDepthIncrease;
nextElementsToDepthIncrease = 0;
}
}
if (currentDepth <= maxDepth){
for (int i= currentDepth;i<=maxDepth;i++){
double nb_nghrs = constructed_graph[node].size();
unordered_set<uint32_t> s_neighbors = intersection( neighbors[i],constructed_graph[node]);
if ((double) s_neighbors.size() < nb_nghrs * p.at(i)) return true;
}
}
return false;
}
graph compress_graph_LP(graph &initial_graph, unordered_map<edge,double> edges_scores, int k, vector<double> p,bool directed){
double compression_rate;
vector<edge> inserted_edges;
vector<pair<edge,double>> es_vec;
for ( auto & e : edges_scores ) es_vec.push_back(make_pair(e.first,e.second));
sort(es_vec.begin(), es_vec.end(), // sort by PL scores
[](const pair<edge,double> & l, const pair<edge,double>& r) {
return l.second > r.second;
});
cout << es_vec.size() << endl;
graph compressed_graph,constructed_graph;
int number_edges = 0;
int i=0;
for (auto e_s : es_vec){
edge e = e_s.first;
if (i%10000==0) cout << i<< endl;
i++;
constructed_graph[e.first].insert(e.second);
if(!directed) constructed_graph[e.second].insert(e.first);
bool insert =test_insert(e,directed,constructed_graph,compressed_graph,k,p);
if ( insert) {
inserted_edges.push_back(e);
number_edges++;
compressed_graph[e.first].insert(e.second);
if (!directed) compressed_graph[e.second].insert(e.first);
}
}
cout << "number of edges " << number_edges << endl;
if (check_constraints(initial_graph,compressed_graph,p,k)) cout << "feasible compression!"<< endl;
return compressed_graph;
}
graph compress_graph_basic(graph &initial_graph, int k, vector<double> p,bool directed){
double compression_rate;
vector<edge> inserted_edges;
vector<edge> s = get_edges(initial_graph,directed);
std::mt19937 g(rand());
std::shuffle(s.begin(), s.end(), g);
graph compressed_graph,constructed_graph;
int number_edges = 0;
int i=0;
for (auto e : s){
if (i%10000==0) cout << i<< endl;
i++;
constructed_graph[e.first].insert(e.second);
if(!directed) constructed_graph[e.second].insert(e.first);
bool insert =test_insert(e,directed,constructed_graph,compressed_graph,k,p);
if (insert){
inserted_edges.push_back(e);
number_edges++;
compressed_graph[e.first].insert(e.second);
if(!directed) compressed_graph[e.second].insert(e.first);
}
}
cout << "number of edges " << number_edges << endl;
if (check_constraints(initial_graph,compressed_graph,p,k)) cout << "feasible compression!"<< endl;
return compressed_graph;
}
vector<edge> perturbate_solution(vector<edge> &s){
vector<edge> s2;
for (auto e : s ) s2.push_back(e);
int max_perturbations = 2; //s.size()/100;
std::mt19937 gen(rand());
std::uniform_int_distribution<> dis(0, s.size()-1);
for (int i=0;i<max_perturbations;i++){
int r1,r2;
r1 = dis(gen);
r2 = dis(gen);
edge e = s2.at(r1);
s2.at(r1).first= s2.at(r2).first;
s2.at(r1).second= s2.at(r2).second;
s2.at(r2).first = e.first;
s2.at(r2).second = e.second;
}
return s2;
}
tuple<double,graph> evaluate_permutation ( vector<edge> &permutation,bool directed, vector<double> &p,
int k,graph &g){
//double compression_rate;
graph compressed_graph,constructed_graph;
int inserted_edges = 0;
for (auto e : permutation){
// update constructed graph
constructed_graph[e.first].insert(e.second);
if (!directed) constructed_graph[e.second].insert(e.first);
bool insert =test_insert(e,false,constructed_graph,compressed_graph,k,p);
if (insert){
inserted_edges++;
compressed_graph[e.first].insert(e.second);
if (!directed) compressed_graph[e.second].insert(e.first);
}
}
return make_tuple(inserted_edges,compressed_graph);
}
graph Simulated_annealing ( int max_iterations,
double initial_temperature,
double decrease_factor,
graph &initial_graph,
bool directed,
int k,vector<double> p){
auto start = chrono::steady_clock::now();
graph gr;
vector<edge> best_permutation;
/// generate initial solution
vector<edge> s = get_edges(initial_graph,false);
best_permutation = s;
std::mt19937 g(rand());
std::shuffle(s.begin(), s.end(), g);
double cost_s,cost_s2,T,best;
T= initial_temperature;
cost_s = get<0> (evaluate_permutation(s,directed,p,k,initial_graph));
gr = get<1> (evaluate_permutation(s,directed,p,k,initial_graph));
best = cost_s;
for (int i = 0;i<max_iterations;i++){
vector<edge> s2 = perturbate_solution(s);
cost_s2 = get<0> (evaluate_permutation(s2,directed, p,k,initial_graph));
if (cost_s2 < best){
best_permutation = s2;
gr = get<1> (evaluate_permutation(s2,directed,p,k,initial_graph));
best = cost_s2;
auto finish = chrono::steady_clock::now();
double elapsed_time= chrono::duration_cast<chrono::duration<double>>(finish - start).count();
//cout <<i<< '\t'<<best<< '\t' << elapsed_time << endl;
}
if (cost_s2 < cost_s){
s = s2;
cost_s = cost_s2;
}
else {
double r = ((double) rand() /(RAND_MAX));
if (std::exp( (cost_s -cost_s2) / T) > r ){
s = s2;
cost_s = cost_s2;
}
}
T = decrease_factor*T;
}
if ( check_constraints(initial_graph,gr,p,k)) {
cout << "feasible solution ! " << endl;
}
return gr;
}
graph compress_graph_greedy(graph &initial_graph, int k, vector<double> p,bool directed){
double compression_rate;
vector<edge> inserted_edges;
vector<edge> s = greedy_edges_order(initial_graph,directed,k);
graph compressed_graph,constructed_graph;
int number_edges = 0;
int i=0;
for (auto e : s){
if (i%10000==0) cout << i<< endl;
i++;
constructed_graph[e.first].insert(e.second);
if(!directed) constructed_graph[e.second].insert(e.first);
bool insert =test_insert(e,directed,constructed_graph,compressed_graph,k,p);
if (insert){
inserted_edges.push_back(e);
number_edges++;
compressed_graph[e.first].insert(e.second);
if(!directed) compressed_graph[e.second].insert(e.first);
}
}
cout << "number of edges " << number_edges << endl;
if (check_constraints(initial_graph,compressed_graph,p,k)) cout << "feasible compression!"<< endl;
return compressed_graph;
}
vector<edge> greedy_edges_order(graph &g,bool directed,int k){
vector<edge> edges = get_edges(g,directed);
map<pair<uint32_t ,uint32_t >,int> edge_score;
for (auto e : edges ){
unordered_set<uint32_t > neighbors_u;
unordered_set<uint32_t> neighbors_v;
neighbors_u = neighbors(g,k-1,e.first,e.second);
neighbors_v = neighbors(g,k-1,e.second,e.first);
for (auto n : neighbors_u){
if (g[n].find(e.second)!=g[n].end()) edge_score[e]=edge_score[e]+1;
}
for (auto n : neighbors_v){
if (g[n].find(e.first)!=g[n].end()) edge_score[e]=edge_score[e]+1;
}
}
sort(edges.begin(),edges.end(),[&]( const edge &e1, const edge &e2 )
{ return edge_score[e1] > edge_score[e2];} );
return edges;
}
unordered_set<uint32_t> neighbors(graph &g,int max_depth,uint32_t u,uint32_t v){
unordered_set<uint32_t> nghrs;
// Mark all the vertices as not visited
unordered_map<uint32_t , int> node_visited;
// Create a queue for BFS
deque<uint32_t> queue;
// array_queue *queue = new array_queue();
// Mark the current node as visited and enqueue it
node_visited[u]= 1;
node_visited[v] = 1;
queue.push_back(u);
int currentDepth = 1,
elementsToDepthIncrease = 1,
nextElementsToDepthIncrease = 0;
while(!queue.empty()) {
// Dequeue a vertex from queue and print it
uint32_t s = queue.front();
queue.pop_front();
// node_visited[s] = 1;
for (auto &v : g[s]){
if (node_visited[v]==0) {
node_visited[v]=1;
queue.push_back(v);
nghrs.insert(v);
}
}
if (--elementsToDepthIncrease == 0) {
if (++currentDepth > max_depth) break;
elementsToDepthIncrease = nextElementsToDepthIncrease;
nextElementsToDepthIncrease = 0;
}
}
return nghrs;
}
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment