1#ifndef FPMAS_GRAPH_ANALYSIS_H
2#define FPMAS_GRAPH_ANALYSIS_H
14namespace fpmas {
namespace graph {
42 std::size_t local_count = 0;
44 local_count += node.second->getOutgoingEdges().size();
71 std::unordered_map<DistributedId, std::vector<DistributedId>>
79 std::unordered_map<int, std::vector<DistributedId>> requests;
81 requests[node.second->location()].push_back(node.first);
82 requests = requests_mpi.
allToAll(requests);
88 std::unordered_map<int, std::vector<std::pair<DistributedId, std::vector<DistributedId>>>> results;
89 for(
auto request : requests) {
90 for(
auto node_id : request.second) {
92 auto edges = graph.
getNode(node_id)->getOutgoingEdges(layer);
94 std::vector<DistributedId> neighbors(edges.size());
95 auto it = neighbors.begin();
96 for(
auto edge : edges)
97 *it++ = edge->getTargetNode()->getId();
100 results[request.first].push_back({node_id, neighbors});
104 results = results_mpi.
allToAll(results);
107 std::unordered_map<DistributedId, std::vector<DistributedId>>
108 distant_nodes_neighbors;
109 for(
auto item : results)
110 for(
auto neighbors : item.second)
111 distant_nodes_neighbors[neighbors.first] = neighbors.second;
113 return distant_nodes_neighbors;
154 std::set<DistributedId> neighbors;
155 for(
auto edge : node.second->getIncomingEdges(layer)) {
156 neighbors.insert(edge->getSourceNode()->getId());
158 for(
auto edge : node.second->getOutgoingEdges(layer)) {
159 neighbors.insert(edge->getTargetNode()->getId());
162 neighbors.erase(node.first);
164 for(
auto node_id : neighbors) {
169 auto neighbor = graph.
getNode(node_id);
172 for(
auto edge : neighbor->getOutgoingEdges(layer)) {
173 auto id = edge->getTargetNode()->getId();
178 && neighbors.find(
id) != neighbors.end()) {
185 for(
auto id : distant_nodes_neighbors[node_id])
186 if(
id != node.first && neighbors.find(
id) != neighbors.end()) {
191 std::size_t k = neighbors.size();
193 c += (double) n / (k*(k-1));
198 std::size_t total_node_count =
200 if(total_node_count > 0)
201 return c/total_node_count;
207 void __explore_distances(
211 std::unordered_map<
DistributedId, std::unordered_map<DistributedId, float>>& distances,
214 std::unordered_map<
DistributedId, std::unordered_map<DistributedId, float>>
216 while(!node_queue.empty()) {
217 auto current_node = node_queue.front();
220 if(current_node.second < distances[current_node.first->getId()][source]) {
221 distances[current_node.first->getId()][source] = current_node.second;
222 for(
auto edge : current_node.first->getOutgoingEdges(layer))
223 node_queue.push({edge->getTargetNode(), current_node.second+1});
227 auto& current_node_requests = next_processes
228 [current_node.first->location()][current_node.first->getId()];
230 auto current_source_request = current_node_requests.find(source);
231 if(current_source_request == current_node_requests.end())
233 current_node_requests[source] = current_node.second;
234 else if(current_node.second < current_node_requests[source])
237 current_node_requests[source] = current_node.second;
253 std::vector<DistributedId> ids(
255 auto it = ids.begin();
280 std::unordered_map<DistributedId, std::unordered_map<DistributedId, float>>
284 const std::vector<DistributedId>& source_nodes
289 std::unordered_map<DistributedId, std::unordered_map<DistributedId, float>>
295 for(
auto node : local_nodes)
296 for(
auto id : all_source_nodes)
297 distances[node.first][id] = std::numeric_limits<float>::infinity();
299 std::unordered_map<int,
300 std::unordered_map<DistributedId, std::unordered_map<DistributedId, float>>
303 std::unordered_map<DistributedId, std::unordered_map<DistributedId, float>>>
305 for(
auto source : all_source_nodes) {
306 auto source_node = local_nodes.find(source);
307 if(source_node != local_nodes.end()) {
308 std::queue<std::pair<api::graph::DistributedNode<T>*,
float>>
310 node_queue.push({source_node->second, 0});
311 __explore_distances(source, node_queue, layer, distances, next_processes);
317 [](
const bool& b1,
const bool& b2) {
return b1 && b2;};
319 bool_mpi, next_processes.size() == 0, and_fct
322 auto requests = next_mpi.allToAll(next_processes);
323 next_processes.clear();
324 for(
auto proc : requests) {
325 for(
auto node : proc.second)
326 for(
auto source : node.second) {
328 std::queue<std::pair<api::graph::DistributedNode<T>*,
float>> node_queue;
329 node_queue.push({graph.
getNode(node.first), source.second});
331 source.first, node_queue, layer,
332 distances, next_processes
337 bool_mpi, next_processes.size() == 0, and_fct
375 const std::vector<DistributedId>& source_nodes
383 std::size_t num_pairs = 0;
384 for(
auto& source : distances)
385 for(
auto& distance : source.second) {
386 if(source.first != distance.first &&
387 distance.second < std::numeric_limits<float>::infinity()) {
388 local_sum+=distance.second;
394 return total_sum / num_pairs;
Definition: distributed_graph.h:169
virtual api::communication::MpiCommunicator & getMpiCommunicator()=0
virtual LocationManager< T > & getLocationManager()=0
Definition: distributed_id.h:89
Definition: distributed_node.h:28
virtual NodeType * getNode(NodeIdType id)=0
std::unordered_map< int, T > allToAll(std::unordered_map< int, T > export_map) override
Definition: communication.h:446
@ LOCAL
Definition: location_state.h:21
int LayerId
Definition: edge.h:13
typename graph::Graph< graph::DistributedNode< T >, graph::DistributedEdge< T > >::NodeMap NodeMap
Definition: load_balancing.h:25
T all_reduce(api::communication::TypedMpi< T > &mpi, const T &data, BinaryOp binary_op=BinaryOp())
Definition: communication.h:634
std::unordered_map< DistributedId, std::unordered_map< DistributedId, float > > shortest_path_lengths(fpmas::api::graph::DistributedGraph< T > &graph, fpmas::api::graph::LayerId layer, const std::vector< DistributedId > &source_nodes)
Definition: analysis.h:281
std::size_t edge_count(api::graph::DistributedGraph< T > &graph)
Definition: analysis.h:41
float characteristic_path_length(fpmas::api::graph::DistributedGraph< T > &graph, fpmas::api::graph::LayerId layer, const std::vector< DistributedId > &source_nodes)
Definition: analysis.h:372
double clustering_coefficient(fpmas::api::graph::DistributedGraph< T > &graph, fpmas::api::graph::LayerId layer)
Definition: analysis.h:142
std::unordered_map< DistributedId, std::vector< DistributedId > > distant_nodes_outgoing_neighbors(fpmas::api::graph::DistributedGraph< T > &graph, fpmas::api::graph::LayerId layer)
Definition: analysis.h:72
std::size_t node_count(api::graph::DistributedGraph< T > &graph)
Definition: analysis.h:25
std::vector< DistributedId > local_node_ids(fpmas::api::graph::DistributedGraph< T > &graph)
Definition: analysis.h:251
Definition: communication.h:585
Definition: functional.h:94