forked from alibaba/GraphScope
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add closeness_centrality app and test case of duplicated mode modific…
…ation (alibaba#336)
- Loading branch information
Showing
20 changed files
with
677 additions
and
102 deletions.
There are no files selected for viewing
143 changes: 143 additions & 0 deletions
143
analytical_engine/apps/centrality/closeness/closeness_centrality.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
/** Copyright 2020 Alibaba Group Holding Limited. | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
#ifndef ANALYTICAL_ENGINE_APPS_CENTRALITY_CLOSENESS_CLOSENESS_CENTRALITY_H_ | ||
#define ANALYTICAL_ENGINE_APPS_CENTRALITY_CLOSENESS_CLOSENESS_CENTRALITY_H_ | ||
|
||
#include <limits> | ||
#include <map> | ||
#include <queue> | ||
#include <utility> | ||
#include <vector> | ||
|
||
#include "grape/grape.h" | ||
|
||
#include "apps/centrality/closeness/closeness_centrality_context.h" | ||
|
||
#include "core/utils/app_utils.h" | ||
|
||
namespace gs { | ||
|
||
/** | ||
* @brief Compute the closeness centrality of vertices. | ||
* Closeness centrality 1 of a node u is the reciprocal of the average shortest | ||
* path distance to u over all n-1 reachable nodes. | ||
* */ | ||
template <typename FRAG_T> | ||
class ClosenessCentrality | ||
: public grape::ParallelAppBase<FRAG_T, ClosenessCentralityContext<FRAG_T>>, | ||
public grape::ParallelEngine { | ||
public: | ||
INSTALL_PARALLEL_WORKER(ClosenessCentrality<FRAG_T>, | ||
ClosenessCentralityContext<FRAG_T>, FRAG_T) | ||
static constexpr grape::MessageStrategy message_strategy = | ||
grape::MessageStrategy::kSyncOnOuterVertex; | ||
static constexpr grape::LoadStrategy load_strategy = | ||
grape::LoadStrategy::kBothOutIn; | ||
using vertex_t = typename fragment_t::vertex_t; | ||
using vid_t = typename fragment_t::vid_t; | ||
using edata_t = typename fragment_t::edata_t; | ||
|
||
void PEval(const fragment_t& frag, context_t& ctx, | ||
message_manager_t& messages) { | ||
auto inner_vertices = frag.InnerVertices(); | ||
auto vertices = frag.Vertices(); | ||
ctx.length.resize(thread_num()); | ||
for (auto& unit : ctx.length) { | ||
unit.Init(vertices); | ||
} | ||
|
||
ForEach(inner_vertices, [&frag, &ctx, this](int tid, vertex_t v) { | ||
ctx.length[tid].SetValue(std::numeric_limits<double>::max()); | ||
this->reversedDijkstraLength(frag, v, ctx, tid); | ||
this->compute(frag, v, ctx, tid); | ||
}); | ||
} | ||
|
||
void IncEval(const fragment_t& frag, context_t& ctx, | ||
message_manager_t& messages) { | ||
return; | ||
} | ||
|
||
private: | ||
// sequential single source Dijkstra length algorithm. | ||
void reversedDijkstraLength(const fragment_t& frag, vertex_t& s, | ||
context_t& ctx, int tid) { | ||
{ | ||
auto vertices = frag.Vertices(); | ||
std::priority_queue<std::pair<double, vertex_t>> heap; | ||
typename FRAG_T::template vertex_array_t<bool> modified(vertices, false); | ||
ctx.length[tid][s] = 0.0; | ||
heap.emplace(0, s); | ||
|
||
double distu, distv, ndistv; | ||
vertex_t v, u; | ||
while (!heap.empty()) { | ||
u = heap.top().second; | ||
distu = -heap.top().first; | ||
heap.pop(); | ||
|
||
if (modified[u]) { | ||
continue; | ||
} | ||
modified[u] = true; | ||
|
||
auto es = frag.directed() ? frag.GetIncomingAdjList(u) | ||
: frag.GetOutgoingAdjList(u); | ||
for (auto& e : es) { | ||
v = e.get_neighbor(); | ||
distv = ctx.length[tid][v]; | ||
double edata = 1.0; | ||
static_if<!std::is_same<edata_t, grape::EmptyType>{}>( | ||
[&](auto& e, auto& data) { | ||
data = static_cast<double>(e.get_data()); | ||
})(e, edata); | ||
ndistv = distu + edata; | ||
if (distv > ndistv) { | ||
ctx.length[tid][v] = ndistv; | ||
heap.emplace(-ndistv, v); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
void compute(const fragment_t& frag, vertex_t& u, context_t& ctx, int tid) { | ||
double tot_sp = 0.0; | ||
int connected_nodes_num = 0; | ||
int total_node_num = 0; | ||
auto vertices = frag.Vertices(); | ||
double closeness_centrality = 0.0; | ||
for (auto& v : vertices) { | ||
if (ctx.length[tid][v] < std::numeric_limits<double>::max()) { | ||
tot_sp += ctx.length[tid][v]; | ||
++connected_nodes_num; | ||
} | ||
++total_node_num; | ||
} | ||
if (tot_sp > 0 && total_node_num > 1) { | ||
closeness_centrality = (connected_nodes_num - 1.0) / tot_sp; | ||
if (ctx.wf_improve) { | ||
closeness_centrality *= | ||
((connected_nodes_num - 1.0) / (total_node_num - 1)); | ||
} | ||
} | ||
ctx.centrality[u] = closeness_centrality; | ||
} | ||
}; | ||
|
||
} // namespace gs | ||
|
||
#endif // ANALYTICAL_ENGINE_APPS_CENTRALITY_CLOSENESS_CLOSENESS_CENTRALITY_H_ |
63 changes: 63 additions & 0 deletions
63
analytical_engine/apps/centrality/closeness/closeness_centrality_context.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
/** Copyright 2020 Alibaba Group Holding Limited. | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
#ifndef ANALYTICAL_ENGINE_APPS_CENTRALITY_CLOSENESS_CLOSENESS_CENTRALITY_CONTEXT_H_ | ||
#define ANALYTICAL_ENGINE_APPS_CENTRALITY_CLOSENESS_CLOSENESS_CENTRALITY_CONTEXT_H_ | ||
|
||
#include <limits> | ||
#include <map> | ||
#include <queue> | ||
#include <utility> | ||
#include <vector> | ||
|
||
#include "grape/grape.h" | ||
|
||
namespace gs { | ||
|
||
template <typename FRAG_T> | ||
class ClosenessCentralityContext | ||
: public grape::VertexDataContext<FRAG_T, double> { | ||
public: | ||
using oid_t = typename FRAG_T::oid_t; | ||
using vid_t = typename FRAG_T::vid_t; | ||
using vertex_t = typename FRAG_T::vertex_t; | ||
|
||
explicit ClosenessCentralityContext(const FRAG_T& fragment) | ||
: grape::VertexDataContext<FRAG_T, double>(fragment), | ||
centrality(this->data()) {} | ||
|
||
void Init(grape::ParallelMessageManager& messages, bool wf) { | ||
auto& frag = this->fragment(); | ||
auto vertices = frag.Vertices(); | ||
wf_improve = wf; | ||
centrality.SetValue(0.0); | ||
} | ||
|
||
void Output(std::ostream& os) override { | ||
auto& frag = this->fragment(); | ||
auto inner_vertices = frag.InnerVertices(); | ||
|
||
for (auto& u : inner_vertices) { | ||
os << frag.GetId(u) << "\t" << centrality[u] << std::endl; | ||
} | ||
} | ||
|
||
bool wf_improve; // use Wasserman-Faust improved formula. | ||
std::vector<typename FRAG_T::template vertex_array_t<double>> length; | ||
typename FRAG_T::template vertex_array_t<double>& centrality; | ||
}; | ||
} // namespace gs | ||
|
||
#endif // ANALYTICAL_ENGINE_APPS_CENTRALITY_CLOSENESS_CLOSENESS_CENTRALITY_CONTEXT_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.