From c2f62836bed23a13d9079015de0bd5353384baca Mon Sep 17 00:00:00 2001 From: Dominic Date: Fri, 22 Nov 2024 16:39:44 +0800 Subject: [PATCH 1/6] Implemented Fast LSC. --- procedures/algo_cpp/lsc_core.cpp | 639 +++++++++++++++++++++++++ procedures/algo_cpp/lsc_standalone.cpp | 83 ++++ 2 files changed, 722 insertions(+) create mode 100644 procedures/algo_cpp/lsc_core.cpp create mode 100644 procedures/algo_cpp/lsc_standalone.cpp diff --git a/procedures/algo_cpp/lsc_core.cpp b/procedures/algo_cpp/lsc_core.cpp new file mode 100644 index 0000000000..bcdbbee628 --- /dev/null +++ b/procedures/algo_cpp/lsc_core.cpp @@ -0,0 +1,639 @@ +#include "LatinSquare.h" +#include "lgraph/olap_base.h" +#include "./algo.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace lgraph_api; +using namespace lgraph_api::olap; + +struct D_v{ + int no; + int nodeColor = -1; + // int cscore = 0; + int state = 0; + bool inList = false; + unordered_set D; +}; + +struct Pool_elment{ + int time = 0; + int poolConflictNum; + unordered_set nodes_in_conf_list; + vector> V_n; + vector pool_d_v_structs; +}; + +void loadInput(istream& is, szx::LatinSquare& lsc) { + is >> lsc.n; + lsc.fixedNums.reserve(lsc.n * lsc.n); + for (szx::Assignment a; is >> a.row >> a.col >> a.num; lsc.fixedNums.push_back(a)) {} +} + +void saveOutput(ostream& os, szx::Table& assignments) { + for (auto i = assignments.begin(); i != assignments.end(); ++i) { + for (auto j = i->begin(); j != i->end(); ++j) { os << *j << '\t'; } + os << endl; + } +} + +void test(istream& inputStream, ostream& outputStream, long long secTimeout, int randSeed, OlapBase& graph) { + cerr << "load input." << endl; + szx::LatinSquare lsc; + loadInput(inputStream, lsc); + + cerr << "solve." << endl; + std::chrono::steady_clock::time_point endTime = std::chrono::steady_clock::now() + std::chrono::seconds(secTimeout); + szx::Table assignments(lsc.n, std::vector(lsc.n)); + solveLatinSquare(assignments, lsc, [&]() { return std::chrono::duration_cast(endTime - std::chrono::steady_clock::now()).count(); }, randSeed,graph); + + cerr << "save output." << endl; + saveOutput(outputStream, assignments); +} +//void test(istream& inputStream, ostream& outputStream, long long secTimeout) { +// // return test(inputStream, outputStream, secTimeout, static_cast(time(nullptr) + clock())); +// return test(inputStream, outputStream, secTimeout, 20); +//} + +void LSCCore(OlapBase& graph) { + cerr << "load environment." << endl; + ifstream ifs("/tugraph-db/test_lsc/LSC.n50f750.00.txt"); // LSC.n60f2520.03.txt + ofstream ofs("solution.txt"); + test(ifs, ofs, 300, 20, graph); // for self-test. + // batchTest(ifs, 300, 10000); +} + +namespace szx { + + class Solver { + // random number generator. + mt19937 pseudoRandNumGen; + void initRand(int seed) { pseudoRandNumGen = mt19937(seed); } + int fastRand(int lb, int ub) { return (pseudoRandNumGen() % (ub - lb)) + lb; } + int fastRand(int ub) { return pseudoRandNumGen() % ub; } + int rand(int lb, int ub) { return uniform_int_distribution(lb, ub - 1)(pseudoRandNumGen); } + int rand(int ub) { return uniform_int_distribution(0, ub - 1)(pseudoRandNumGen); } + double real_rand(int lb, int ub) { return uniform_real_distribution(lb, ub)(pseudoRandNumGen);} + + int colorNum; + int nodeNum; + int fixedNums_size; + + vector> adjList; + unordered_set candSet; + // vector candSet; + // unordered_set V; // candSet := V; + + vector d_v_structs; + vector> V_n; + vector best_d_v_structs; + + int conflictNum; + int bestConflictNum; + vector> neighborColorTable; + int alpha; + int iter; + + vector> tabuList; + vector> tabu_pair; + vector> non_tabu_pair; + + int depth; + int maxScore; + int tabu_maxScore; + + int d_v_one_list[1000]; + int pos[1000]; + int ls_num; + + int conf_list[10000]; + int conf_list_best[10000]; + int conf_pos[10000]; + int conf_ls_num; + + vector pool; + const int pool_size = 20; + int bestPoolConflictNum; + const float theta = 0.2; + vector C; + + public: + void solve(Table& output, LatinSquare& input, function restMilliSec, int seed, OlapBase& graph) { + auto start = std::chrono::high_resolution_clock::now(); + + initRand(seed); + Construct(input, graph); + FastLSC(restMilliSec); + // int real_conflictNum = getNeighborColorTable(); + // cout << "real_conflictNum:" << real_conflictNum << endl; + + for (int node = 0; node < nodeNum; ++node) { + output[node / colorNum][node % colorNum] = d_v_structs[node].nodeColor; + } + auto stop = std::chrono::high_resolution_clock::now(); + auto duration = std::chrono::duration(stop - start); + std::cout << "Time taken by function: " << duration.count() << " seconds" << std::endl; + // cerr << input.n << endl; + // for (Num i = 0; (restMilliSec() > 0) && (i < input.n); ++i) { cerr << i << '\t' << output[i][i] << endl; } + } + + void graphtoadjlist(OlapBase& graph) { + size_t num = graph.NumVertices(); + // vector> adjList; + adjList.resize(num); + + for (size_t i = 0; i < num; i++) { + AdjList src_list = graph.OutEdges(i); + AdjUnit *vertex = src_list.begin(); + while (vertex != src_list.end()) { + adjList[i].push_back(vertex -> neighbour); + vertex++; + } + } + + } + + void Construct(const LatinSquare& input, OlapBase& graph){ + colorNum = input.n; + nodeNum = colorNum * colorNum; + fixedNums_size = input.fixedNums.size(); + ls_num = 0; + conf_ls_num = 0; + tabuList = neighborColorTable = vector>(nodeNum, vector(colorNum, 0)); + conflictNum = 0; + alpha = 100000; + pool = vector(20); + bestPoolConflictNum = INT_MAX; + C = vector(nodeNum); + // candSet = vector(nodeNum); + + adjList = vector>(nodeNum); + graphtoadjlist(graph); + // pre-allocate space for each node's adjacency list +// for (int i = 0; i < colorNum; ++i) { +// adjList[i].reserve(2*colorNum - 2); +// } + + // Create a vector of D_v structures. + d_v_structs.reserve(nodeNum); + best_d_v_structs.reserve(nodeNum); + + vector temp(colorNum); + iota(temp.begin(), temp.end(), 0); + unordered_set standard_D(temp.begin(), temp.end()); + + // line 2 + // V_n = vector>(colorNum); + + for(int i = 0; i < colorNum; ++i) { + for(int j = 0; j < colorNum; ++j){ + int currentIdx = i * colorNum + j; + + // line 1 + D_v dv; + dv.no = currentIdx; + dv.D = standard_D; + d_v_structs.push_back(dv); + + // line 3 + candSet.insert(currentIdx); + // candSet.push_back(currentIdx); + +// for (int k = 0; k < colorNum; ++k) { +// if (k != j) { +// adjList[currentIdx].emplace_back(i * colorNum + k); // neighbor in same row +// } +// if (k != i) { +// adjList[currentIdx].emplace_back(k * colorNum + j); // neighbor in same column +// } +// } + } + } + + // reduction rule 1 + for(int i = 0;i < fixedNums_size; ++i){ + int one_D_node_id = input.fixedNums[i].row * colorNum + input.fixedNums[i].col; + int fixed_color = input.fixedNums[i].num; + remove_d_v_one_nodes(one_D_node_id, fixed_color); + } + + while(ls_num > 0){ // if ls_num != 0, enter the loop + // try to print d_v_one_list +// for(int i = 0; i < ls_num; i++){ +// cout << d_v_one_list[i] << " "; +// } +// cout << endl; +// cout << ls_num << " "; + int temp_num = ls_num; + for(int i = 0; i < temp_num; ++i){ + int del_node = d_v_one_list[i]; // If not assigned, this value may change + int color = *(d_v_structs[del_node].D).begin(); + remove_d_v_one_nodes(d_v_one_list[i], color); + // delete_node(del_node); + // d_v_structs[del_node].inList = false; + } + } + + // V = candSet; // V means the uncertain nodes + + while(!candSet.empty()){ // random + int nodeIndex = fastRand(candSet.size()); + auto it = candSet.begin(); + advance(it, nodeIndex); + int selectedNode = *it; + + int color = fastRand(colorNum); + d_v_structs[selectedNode].nodeColor = color; + // V_n[color].insert(selectedNode); + candSet.erase(selectedNode); +// int nodeIndex = fastRand(candSet.size()); +// int selectedNode = candSet[nodeIndex]; +// int color = fastRand(colorNum); +// d_v_structs[selectedNode].nodeColor = color; +// +// swap(candSet[nodeIndex], candSet.back()); +// candSet.pop_back(); + } + } + + void remove_d_v_one_nodes(int one_D_node_id, int fixed_color){ + // remove node from candSet + // cout << one_D_node_id << " "; + candSet.erase(one_D_node_id); +// swap(candSet[one_D_node_id], candSet.back()); +// candSet.pop_back(); + // D = {} + if(d_v_structs[one_D_node_id].inList){ + delete_node(one_D_node_id); + d_v_structs[one_D_node_id].inList = false; + } + d_v_structs[one_D_node_id].D.clear(); + d_v_structs[one_D_node_id].nodeColor = fixed_color; + // put the fixed color to V_n + // V_n[fixed_color].insert(one_D_node_id); + // Impact on neighbors + for(auto &node : adjList[one_D_node_id]){ + auto& D = d_v_structs[node].D; + int pre_d_v_size = D.size(); + D.erase(fixed_color); + int current_d_v_size = D.size(); + + if(current_d_v_size == 1 && pre_d_v_size == 2){ + add_node(node); + d_v_structs[node].inList = true; + } else if(current_d_v_size == 0 && pre_d_v_size == 1){ + delete_node(node); + d_v_structs[node].inList = false; + } + } + } + + void add_node(int node){ + d_v_one_list[ls_num] = node; + pos[node]=ls_num++; + } + + void delete_node(int node) + { + ls_num--; // Point to the last element + d_v_one_list[pos[node]]=d_v_one_list[ls_num]; // In the list of elements, place the last element at the position where you want to delete the element + pos[d_v_one_list[ls_num]]=pos[node]; // In the position list, update the position of the last element + } + + int getNeighborColorTable(){ + conf_ls_num=0; + conflictNum = 0; + int flag; + for (int i = 0; i < nodeNum; ++i) { + flag = 0; + int color = d_v_structs[i].nodeColor; + for (auto j = 0u; j < adjList[i].size(); ++j) { + int neighbor = adjList[i][j]; + int neighbor_color = d_v_structs[neighbor].nodeColor; + ++neighborColorTable[i][neighbor_color]; + if(color == neighbor_color){ // conflict + ++conflictNum; + if (flag==0) + { + add_conf(i); // i has conflict with neighbor j , add the conflict i nodes in to conf + flag=1; // node i has been added + } + } + } + } + // cout << "conf_ls_num_begin:" << conf_ls_num << endl; + return conflictNum / 2; + } + + void FastLSC(function &restMilliSec){ + iter = 0; + tabuList = neighborColorTable = vector>(nodeNum, vector(colorNum, 0)); + best_d_v_structs.resize(nodeNum); + while(restMilliSec() > 0){ + for (int i = 0; i < nodeNum; ++i) { + fill(tabuList[i].begin(), tabuList[i].end(), 0); + fill(neighborColorTable[i].begin(), neighborColorTable[i].end(), 0); + // d_v_structs[i].cscore = 0; + } + + conflictNum = getNeighborColorTable(); + // cout << "conflictNum begin:" << conflictNum << endl; + bestConflictNum = conflictNum; + + depth = 0; + while(depth < alpha && conflictNum > 0){ + findMove(); + makeMove(); + ++depth; + ++iter; + if(conflictNum < 100 && conflictNum <= bestConflictNum){ + bestConflictNum = conflictNum; + for(int i = 0; i < conf_ls_num; ++i){ + conf_list_best[i] = conf_list[i]; + } + // best_d_v_structs = d_v_structs; + for(int i = 0; i < nodeNum; ++i){ + best_d_v_structs[i].nodeColor = d_v_structs[i].nodeColor; + best_d_v_structs[i].state = d_v_structs[i].state; + // best_d_v_structs[i].inList = d_v_structs[i].inList; + } + } + } + + // cout << "bestConflictNum:" << bestConflictNum << endl; + if(conflictNum == 0){ + break; + } + + if(iter == alpha){ + for(int i = 0; i < nodeNum; ++i){ + best_d_v_structs[i].D = d_v_structs[i].D; + } + } + + d_v_structs = Perturb(); + } + } + + void findMove(){ + maxScore = INT_MIN; // bigger is better + tabu_maxScore = INT_MIN; + double count = 0; + double tabu_count = 0; + pair point_and_color; + + non_tabu_pair.clear(); + tabu_pair.clear(); + + // cout << conf_ls_num << " "; + for (int p = 0; p < conf_ls_num; ++p) { + int i = conf_list[p]; + // ++d_v_structs[i].cscore; + const auto& nodeStruct = d_v_structs[i]; + int oldColor = nodeStruct.nodeColor; + if(nodeStruct.D.empty()){ // D is empty means we cannot change the color + continue; + } + + const vector& tempColorTable = neighborColorTable[i]; + for(const auto &i1 : nodeStruct.D) { + // Consider changing the color of vertex i + if (oldColor == i1) { + continue; + } else { + vector& tempTabuTable = tabuList[i]; + // 5-2 means conflicts reduce 3, so bigger is better + int currentScore = tempColorTable[oldColor] - tempColorTable[i1]; + + point_and_color = make_pair(i,i1); + + if (depth >= tempTabuTable[i1]) { + if (currentScore > maxScore) { + maxScore = currentScore; + count = 1; + non_tabu_pair.push_back(point_and_color); + } else if (currentScore == maxScore && real_rand(0, 1) < 1 / (++count)) { + non_tabu_pair.push_back(point_and_color); + } + } else { + if (currentScore > tabu_maxScore) { + tabu_maxScore = currentScore; + tabu_count = 1; + tabu_pair.push_back(point_and_color); + } else if (currentScore == tabu_maxScore && real_rand(0, 1) < 1 / (++tabu_count)) { + tabu_pair.push_back(point_and_color); + } + } + } + } + } + } + + void makeMove(){ + int bestPoint = 0, bestColor = 0; + if (tabu_pair.size() > 0 && tabu_maxScore > maxScore && conflictNum - tabu_maxScore < bestConflictNum){ // choose tabu + maxScore = tabu_maxScore; + bestPoint = tabu_pair.back().first; + bestColor = tabu_pair.back().second; + }else { + bestPoint = non_tabu_pair.back().first; + bestColor = non_tabu_pair.back().second; + } + + auto& bestNode = d_v_structs[bestPoint]; + int oldColor = bestNode.nodeColor; + tabuList[bestPoint][oldColor] = depth + conflictNum + rand(10) + 1; // cannot change the color back in the next beta iters + + // Neighboring nodes are also affected Original color -1, new color +1 + // neighborColorTable: Distribution of Neighborhood Colors + // color1 color2 ... colorNum-1 + // 0 + // 1 + // 2 + // 3 + int neighbor; + int temp_size = adjList[bestPoint].size(); + for (int i = 0; i < temp_size; i++) { + neighbor = adjList[bestPoint][i]; + --neighborColorTable[neighbor][oldColor]; + ++neighborColorTable[neighbor][bestColor]; + // for neighbor + // if cause new conflict, add it + // 1.if neighbor is bestColor, before change, it has no conflict, but change brings new conflict, then add it + if(d_v_structs[neighbor].nodeColor == bestColor && neighborColorTable[neighbor][bestColor]==1){ // before was 0, because ++ change 1 + add_conf(neighbor); + } + // if reduce conflict to 0, delete it + // 2.if neighbor is oldColor, but with the change of i, no conflict, then delete it + else if(d_v_structs[neighbor].nodeColor == oldColor && neighborColorTable[neighbor][oldColor]==0){ // before was 1, because -- change 0 + delete_conf(neighbor); + // d_v_structs[neighbor].cscore = 0; + } + } + + // for bestPoint, if no conflict, delete it + if(neighborColorTable[bestPoint][bestColor] == 0){ + delete_conf(bestPoint); + } + + d_v_structs[bestPoint].nodeColor = bestColor; + conflictNum -= maxScore; + + d_v_structs[bestPoint].state = iter; + } + + void add_conf(int v) + { + conf_list[conf_ls_num]=v; + conf_pos[v]=conf_ls_num++; + } + + void delete_conf(int v) + { + conf_ls_num--; + conf_list[conf_pos[v]]=conf_list[conf_ls_num]; + conf_pos[conf_list[conf_ls_num]]=conf_pos[v]; + } + + bool similar(Pool_elment pool_element1, Pool_elment pool_element2) { + if(pool_element1.poolConflictNum != pool_element2.poolConflictNum) { + return false; + } + + unordered_set set1; + set1.reserve(colorNum); + for(const auto &item : pool_element1.nodes_in_conf_list) { + set1.insert(d_v_structs[item].nodeColor); + } + + for(const auto &item : pool_element2.nodes_in_conf_list) { + if(set1.find(d_v_structs[item].nodeColor) == set1.end()) { + return false; + } + set1.erase(d_v_structs[item].nodeColor); + } + + return set1.empty(); + } + + vector Perturb(){ + // init + vector d_v_structs_perturb; + Pool_elment pool_element; + pool_element.poolConflictNum = bestConflictNum; + pool_element.pool_d_v_structs = best_d_v_structs; + for(int i = 0;i < conf_ls_num;++i){ + pool_element.nodes_in_conf_list.insert(conf_list_best[i]); + } + + bool similar_pair = false; + + // 1.updating phase of the solution pool + if(bestConflictNum < bestPoolConflictNum) { + pool.clear(); + bestPoolConflictNum = pool_element.poolConflictNum; + pool.push_back(pool_element); + d_v_structs_perturb = pool_element.pool_d_v_structs; + } else { + for(auto &p : pool) { + ++p.time; + if(similar(p, pool_element)) { + for(int j = 0; j < nodeNum; ++j) { + p.pool_d_v_structs[j].state = pool_element.pool_d_v_structs[j].state; + } + similar_pair = true; + } + } + + if(similar_pair){ + // cout << "similar!!!" << endl; + // random select + int r = rand(pool.size()); + d_v_structs_perturb = pool[r].pool_d_v_structs; + }else{ + // int pool_size_2 = 20; + if(pool.size() < 20){ + pool.push_back(pool_element); + }else{ + int oldest_time = -1; + int oldest_no = 0; + for(int i = 0; i < pool_size; ++i){ + if(pool[i].time > oldest_time){ + oldest_time = pool[i].time; + oldest_no = i; + } + } + pool[oldest_no] = pool_element; + } + d_v_structs_perturb = pool_element.pool_d_v_structs; + } + } + +// for(int i = 0;i < pool.size();++i){ +// ++pool[i].time; +// } + + // 2.the re-construction solution phase + int maxIter = INT_MIN; + int minIter = INT_MAX; + for(auto &node:d_v_structs_perturb){ + if(node.state > maxIter){ + maxIter = node.state; + } + if(node.state < minIter){ + minIter = node.state; + } + } + int RCL = (maxIter - minIter) * theta + minIter; +// cout << "maxIter:" << maxIter << endl; +// cout << "minIter:" << minIter << endl; +// cout << "RCL:" << RCL << endl; + C.clear(); + int pos_c = 0; + for(auto &node:d_v_structs_perturb){ + if(node.state <= RCL){ + // C[pos_c++] = node; + C.push_back(node); + pos_c++; + } + } + + // pos_c = C.size(); + int cnt = pos_c / 2; + // cout << cnt << endl; + while(cnt > 0){ + int rand_c = rand(pos_c); + unordered_set tempset = d_v_structs_perturb[C[rand_c].no].D; + if(!tempset.empty()) { + int index = rand(tempset.size()); + auto it = tempset.begin(); + advance(it, index); + d_v_structs_perturb[C[rand_c].no].nodeColor = *it; + // cout << C[rand_c].no << " "; + } + C[rand_c] = C[--pos_c]; + --cnt; + } + // cout << "pool.size:" << pool.size() << endl; + return d_v_structs_perturb; + } + }; + +// solver. + void solveLatinSquare(Table& output, LatinSquare& input, function restMilliSec, int seed, OlapBase& graph) { + Solver().solve(output, input, restMilliSec, seed, graph); + } + +} + + diff --git a/procedures/algo_cpp/lsc_standalone.cpp b/procedures/algo_cpp/lsc_standalone.cpp new file mode 100644 index 0000000000..886f7856be --- /dev/null +++ b/procedures/algo_cpp/lsc_standalone.cpp @@ -0,0 +1,83 @@ +/*copyright 2022 AntGroup CO., Ltd. + * + * 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. + */ + +#include "olap/olap_on_disk.h" +#include "tools/json.hpp" +#include "./algo.h" + +using namespace lgraph_api; +using namespace lgraph_api::olap; +using json = nlohmann::json; + +class MyConfig : public ConfigBase { + public: + // std::string root = "0"; + std::string name = std::string("lsc"); + void AddParameter(fma_common::Configuration& config) { + ConfigBase::AddParameter(config); + // config.Add(root, "root", true).Comment("the root of bfs"); + } + void Print() { + ConfigBase::Print(); + std::cout << " name: " << name << std::endl; + // std::cout << " root: " << root << std::endl; + } + + MyConfig(int& argc, char**& argv) : ConfigBase(argc, argv) { + fma_common::Configuration config; + AddParameter(config); + config.ExitAfterHelp(true); + config.ParseAndFinalize(argc, argv); + Print(); + } +}; + +int main(int argc, char** argv) { + double start_time; + MemUsage memUsage; + memUsage.startMemRecord(); + + // prepare + start_time = get_time(); + MyConfig config(argc, argv); + OlapOnDisk graph; + // size_t root_vid; + graph.Load(config, DUAL_DIRECTION); + memUsage.print(); + memUsage.reset(); + auto prepare_cost = get_time() - start_time; + printf("prepare_cost = %.2lf(s)\n", prepare_cost); + + // core + start_time = get_time(); + // auto parent = graph.AllocVertexArray(); + // size_t count = BFSCore(graph, root_vid, parent); + + LSCCore(graph); + memUsage.print(); + memUsage.reset(); + auto core_cost = get_time() - start_time; + printf("core_cost = %.2lf(s)\n", core_cost); + + // output + start_time = get_time(); + // TODO(any): write to file + // printf("found_vertices = %ld\n", count); + auto output_cost = get_time() - start_time; + printf("output_cost = %.2lf(s)\n", output_cost); + + printf("total_cost = %.2lf(s)\n", prepare_cost + core_cost + output_cost); + printf("DONE."); + + return 0; +} From c5c00f731c77b401005408132088ce1cf1915cb2 Mon Sep 17 00:00:00 2001 From: Dominic Date: Sat, 23 Nov 2024 12:13:33 +0800 Subject: [PATCH 2/6] Implemented K-hop alogrithm. --- procedures/CMakeLists.txt | 1 + procedures/algo_cpp/khop_core.cpp | 63 +++++++++++++++++++ procedures/algo_cpp/khop_standalone.cpp | 83 +++++++++++++++++++++++++ 3 files changed, 147 insertions(+) create mode 100644 procedures/algo_cpp/khop_core.cpp create mode 100644 procedures/algo_cpp/khop_standalone.cpp diff --git a/procedures/CMakeLists.txt b/procedures/CMakeLists.txt index 0a2852a309..423ecbff4c 100644 --- a/procedures/CMakeLists.txt +++ b/procedures/CMakeLists.txt @@ -81,6 +81,7 @@ add_standalone(wlpa) add_standalone(subgraph_isomorphism) add_standalone(sybilrank) add_standalone(leiden) +add_stanalone(khop) add_embed(apsp) add_embed(bfs) diff --git a/procedures/algo_cpp/khop_core.cpp b/procedures/algo_cpp/khop_core.cpp new file mode 100644 index 0000000000..b44f7f21ca --- /dev/null +++ b/procedures/algo_cpp/khop_core.cpp @@ -0,0 +1,63 @@ +/** + * @Function: Compute the k-hop algorithm. + * @param: + * + * + * + * + graph: + The graph to compute on. + root_vid: Identifier of root node. + result: + Set of reachable nodes in K-hop. + value_k: Number of search layers. + * @return: Number of nodes in K_hop. + */ +// #include +#include "lgraph/olap_base.h" +#include "./algo.h" + +using namespace lgraph_api; +using namespace lgraph_api::olap; +size_t k_hop(OlapBase& graph, size_t root_vid, ParallelVector&result, size_t k) +{ + size_t root = root_vid; + auto active_in = graph.AllocVertexSubset(); + active_in.Add(root); + auto active_out = graph.AllocVertexSubset(); + auto parent=graph.AllocVertexArray(); + parent.Fill(0); + parent[root]=root; + size_t num_activations = 1; + size_t discovered_vertices, j = 0; + for (size_t ii = 0; ii < k ; ii++) + { + active_out.Clear(); + num_activations = graph.ProcessVertexActive( + [&](size_t vi) { + size_t num_activations = 0; + for (auto& edge : graph.OutEdges(vi)) + { + size_t dst = edge.neighbour; + if (parent[dst] == 0) + { + auto lock = graph.GuardVertexLock(dst); + if(parent[dst] == 0) + { + parent[dst] = vi; + num_activations += 1; + active_out.Add(dst); + result[j++]=dst; + } + } + } + return num_activations; + }, + active_in + ); + printf("activates(%lu) <= %lu \n", ii+1, num_activations); + discovered_vertices += num_activations; + active_in.Swap(active_out); + } + return discovered_vertices; +} diff --git a/procedures/algo_cpp/khop_standalone.cpp b/procedures/algo_cpp/khop_standalone.cpp new file mode 100644 index 0000000000..887e1ae3ca --- /dev/null +++ b/procedures/algo_cpp/khop_standalone.cpp @@ -0,0 +1,83 @@ +#include "olap/olap_on_disk.h" +#include "tools/json.hpp" +#include "./algo.h" +using namespace lgraph_api; +using namespace lgraph_api::olap; +using json = nlohmann::json; + +class MyConfig : public ConfigBase +{ + public: + std::string root = "0"; + std::string name = std::string("khop"); + size_t value_k=3; + void AddParameter(fma_common::Configuration& config) + { + ConfigBase::AddParameter(config); + config.Add(root, "root", true).Comment("Identifier of the root node."); + config.Add(value_k, "value_k", true).Comment( + "Number of search layers(value of k in K-hop algorithm)." + ); + } + void Print() + { + ConfigBase::Print(); + std::cout << " name: " << name << std::endl; + std::cout << " root: " << name << std::endl; + std::cout << " value_k: " << value_k << std::endl; + } + MyConfig(int& argc, char**& argv) : ConfigBase(argc, argv) + { + fma_common::Configuration config; + AddParameter(config); + config.ExitAfterHelp(true); + config.ParseAndFinalize(argc, argv); + Print(); + } +}; + +extern size_t k_hop(OlapBase& graph, size_t root_vid, ParallelVector&result, size_t k); + +int main(int argc, char** argv){ + double start_time; + MemUsage memUsage; + memUsage.startMemRecord(); + start_time = get_time(); + MyConfig config(argc, argv); + OlapOnDisk graph; + graph.Load(config, INPUT_SYMMETRIC); + size_t root_vid; + auto result=graph.AllocVertexArray(); + result.Fill(0); + if(config.id_mapping) + root_vid = graph.hash_list_.find(config.root); + else + root_vid = std::stoi(config.root); + size_t value_k=config.value_k; + memUsage.print(); + memUsage.reset(); + auto prepare_cost = get_time()- start_time; + printf("prepare_cost = %.2lf(s)\n", prepare_cost); + + start_time = get_time(); + size_t count_result=k_hop(graph, root_vid, result, value_k); + memUsage.print(); + memUsage.reset(); + auto core_cost = get_time()- start_time; + + start_time = get_time(); + if (config.output_dir != "") + { + graph.Write(config, result, graph.NumVertices(), config.name); + } + printf("\n================\n"); + printf("Find %lu vertexes in %lu-hop from node NO.%lu", count_result, value_k, root_vid); + printf("\n================\n"); + auto output_cost = get_time()- start_time; + + printf("core_cost = %.2lf(s)\n", core_cost); + printf("output_cost = %.2lf(s)\n", output_cost); + printf("total_cost = %.2lf(s)\n", prepare_cost + core_cost + output_cost); + printf("DONE. \n"); + return 0; +} \ No newline at end of file From 6d35ef5dcc12aac9e690f29400e626096b0c669a Mon Sep 17 00:00:00 2001 From: Dominic Date: Sat, 23 Nov 2024 13:37:13 +0800 Subject: [PATCH 3/6] Delete lsc. --- procedures/algo_cpp/lsc_core.cpp | 639 ------------------------- procedures/algo_cpp/lsc_standalone.cpp | 83 ---- 2 files changed, 722 deletions(-) delete mode 100644 procedures/algo_cpp/lsc_core.cpp delete mode 100644 procedures/algo_cpp/lsc_standalone.cpp diff --git a/procedures/algo_cpp/lsc_core.cpp b/procedures/algo_cpp/lsc_core.cpp deleted file mode 100644 index bcdbbee628..0000000000 --- a/procedures/algo_cpp/lsc_core.cpp +++ /dev/null @@ -1,639 +0,0 @@ -#include "LatinSquare.h" -#include "lgraph/olap_base.h" -#include "./algo.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace std; -using namespace lgraph_api; -using namespace lgraph_api::olap; - -struct D_v{ - int no; - int nodeColor = -1; - // int cscore = 0; - int state = 0; - bool inList = false; - unordered_set D; -}; - -struct Pool_elment{ - int time = 0; - int poolConflictNum; - unordered_set nodes_in_conf_list; - vector> V_n; - vector pool_d_v_structs; -}; - -void loadInput(istream& is, szx::LatinSquare& lsc) { - is >> lsc.n; - lsc.fixedNums.reserve(lsc.n * lsc.n); - for (szx::Assignment a; is >> a.row >> a.col >> a.num; lsc.fixedNums.push_back(a)) {} -} - -void saveOutput(ostream& os, szx::Table& assignments) { - for (auto i = assignments.begin(); i != assignments.end(); ++i) { - for (auto j = i->begin(); j != i->end(); ++j) { os << *j << '\t'; } - os << endl; - } -} - -void test(istream& inputStream, ostream& outputStream, long long secTimeout, int randSeed, OlapBase& graph) { - cerr << "load input." << endl; - szx::LatinSquare lsc; - loadInput(inputStream, lsc); - - cerr << "solve." << endl; - std::chrono::steady_clock::time_point endTime = std::chrono::steady_clock::now() + std::chrono::seconds(secTimeout); - szx::Table assignments(lsc.n, std::vector(lsc.n)); - solveLatinSquare(assignments, lsc, [&]() { return std::chrono::duration_cast(endTime - std::chrono::steady_clock::now()).count(); }, randSeed,graph); - - cerr << "save output." << endl; - saveOutput(outputStream, assignments); -} -//void test(istream& inputStream, ostream& outputStream, long long secTimeout) { -// // return test(inputStream, outputStream, secTimeout, static_cast(time(nullptr) + clock())); -// return test(inputStream, outputStream, secTimeout, 20); -//} - -void LSCCore(OlapBase& graph) { - cerr << "load environment." << endl; - ifstream ifs("/tugraph-db/test_lsc/LSC.n50f750.00.txt"); // LSC.n60f2520.03.txt - ofstream ofs("solution.txt"); - test(ifs, ofs, 300, 20, graph); // for self-test. - // batchTest(ifs, 300, 10000); -} - -namespace szx { - - class Solver { - // random number generator. - mt19937 pseudoRandNumGen; - void initRand(int seed) { pseudoRandNumGen = mt19937(seed); } - int fastRand(int lb, int ub) { return (pseudoRandNumGen() % (ub - lb)) + lb; } - int fastRand(int ub) { return pseudoRandNumGen() % ub; } - int rand(int lb, int ub) { return uniform_int_distribution(lb, ub - 1)(pseudoRandNumGen); } - int rand(int ub) { return uniform_int_distribution(0, ub - 1)(pseudoRandNumGen); } - double real_rand(int lb, int ub) { return uniform_real_distribution(lb, ub)(pseudoRandNumGen);} - - int colorNum; - int nodeNum; - int fixedNums_size; - - vector> adjList; - unordered_set candSet; - // vector candSet; - // unordered_set V; // candSet := V; - - vector d_v_structs; - vector> V_n; - vector best_d_v_structs; - - int conflictNum; - int bestConflictNum; - vector> neighborColorTable; - int alpha; - int iter; - - vector> tabuList; - vector> tabu_pair; - vector> non_tabu_pair; - - int depth; - int maxScore; - int tabu_maxScore; - - int d_v_one_list[1000]; - int pos[1000]; - int ls_num; - - int conf_list[10000]; - int conf_list_best[10000]; - int conf_pos[10000]; - int conf_ls_num; - - vector pool; - const int pool_size = 20; - int bestPoolConflictNum; - const float theta = 0.2; - vector C; - - public: - void solve(Table& output, LatinSquare& input, function restMilliSec, int seed, OlapBase& graph) { - auto start = std::chrono::high_resolution_clock::now(); - - initRand(seed); - Construct(input, graph); - FastLSC(restMilliSec); - // int real_conflictNum = getNeighborColorTable(); - // cout << "real_conflictNum:" << real_conflictNum << endl; - - for (int node = 0; node < nodeNum; ++node) { - output[node / colorNum][node % colorNum] = d_v_structs[node].nodeColor; - } - auto stop = std::chrono::high_resolution_clock::now(); - auto duration = std::chrono::duration(stop - start); - std::cout << "Time taken by function: " << duration.count() << " seconds" << std::endl; - // cerr << input.n << endl; - // for (Num i = 0; (restMilliSec() > 0) && (i < input.n); ++i) { cerr << i << '\t' << output[i][i] << endl; } - } - - void graphtoadjlist(OlapBase& graph) { - size_t num = graph.NumVertices(); - // vector> adjList; - adjList.resize(num); - - for (size_t i = 0; i < num; i++) { - AdjList src_list = graph.OutEdges(i); - AdjUnit *vertex = src_list.begin(); - while (vertex != src_list.end()) { - adjList[i].push_back(vertex -> neighbour); - vertex++; - } - } - - } - - void Construct(const LatinSquare& input, OlapBase& graph){ - colorNum = input.n; - nodeNum = colorNum * colorNum; - fixedNums_size = input.fixedNums.size(); - ls_num = 0; - conf_ls_num = 0; - tabuList = neighborColorTable = vector>(nodeNum, vector(colorNum, 0)); - conflictNum = 0; - alpha = 100000; - pool = vector(20); - bestPoolConflictNum = INT_MAX; - C = vector(nodeNum); - // candSet = vector(nodeNum); - - adjList = vector>(nodeNum); - graphtoadjlist(graph); - // pre-allocate space for each node's adjacency list -// for (int i = 0; i < colorNum; ++i) { -// adjList[i].reserve(2*colorNum - 2); -// } - - // Create a vector of D_v structures. - d_v_structs.reserve(nodeNum); - best_d_v_structs.reserve(nodeNum); - - vector temp(colorNum); - iota(temp.begin(), temp.end(), 0); - unordered_set standard_D(temp.begin(), temp.end()); - - // line 2 - // V_n = vector>(colorNum); - - for(int i = 0; i < colorNum; ++i) { - for(int j = 0; j < colorNum; ++j){ - int currentIdx = i * colorNum + j; - - // line 1 - D_v dv; - dv.no = currentIdx; - dv.D = standard_D; - d_v_structs.push_back(dv); - - // line 3 - candSet.insert(currentIdx); - // candSet.push_back(currentIdx); - -// for (int k = 0; k < colorNum; ++k) { -// if (k != j) { -// adjList[currentIdx].emplace_back(i * colorNum + k); // neighbor in same row -// } -// if (k != i) { -// adjList[currentIdx].emplace_back(k * colorNum + j); // neighbor in same column -// } -// } - } - } - - // reduction rule 1 - for(int i = 0;i < fixedNums_size; ++i){ - int one_D_node_id = input.fixedNums[i].row * colorNum + input.fixedNums[i].col; - int fixed_color = input.fixedNums[i].num; - remove_d_v_one_nodes(one_D_node_id, fixed_color); - } - - while(ls_num > 0){ // if ls_num != 0, enter the loop - // try to print d_v_one_list -// for(int i = 0; i < ls_num; i++){ -// cout << d_v_one_list[i] << " "; -// } -// cout << endl; -// cout << ls_num << " "; - int temp_num = ls_num; - for(int i = 0; i < temp_num; ++i){ - int del_node = d_v_one_list[i]; // If not assigned, this value may change - int color = *(d_v_structs[del_node].D).begin(); - remove_d_v_one_nodes(d_v_one_list[i], color); - // delete_node(del_node); - // d_v_structs[del_node].inList = false; - } - } - - // V = candSet; // V means the uncertain nodes - - while(!candSet.empty()){ // random - int nodeIndex = fastRand(candSet.size()); - auto it = candSet.begin(); - advance(it, nodeIndex); - int selectedNode = *it; - - int color = fastRand(colorNum); - d_v_structs[selectedNode].nodeColor = color; - // V_n[color].insert(selectedNode); - candSet.erase(selectedNode); -// int nodeIndex = fastRand(candSet.size()); -// int selectedNode = candSet[nodeIndex]; -// int color = fastRand(colorNum); -// d_v_structs[selectedNode].nodeColor = color; -// -// swap(candSet[nodeIndex], candSet.back()); -// candSet.pop_back(); - } - } - - void remove_d_v_one_nodes(int one_D_node_id, int fixed_color){ - // remove node from candSet - // cout << one_D_node_id << " "; - candSet.erase(one_D_node_id); -// swap(candSet[one_D_node_id], candSet.back()); -// candSet.pop_back(); - // D = {} - if(d_v_structs[one_D_node_id].inList){ - delete_node(one_D_node_id); - d_v_structs[one_D_node_id].inList = false; - } - d_v_structs[one_D_node_id].D.clear(); - d_v_structs[one_D_node_id].nodeColor = fixed_color; - // put the fixed color to V_n - // V_n[fixed_color].insert(one_D_node_id); - // Impact on neighbors - for(auto &node : adjList[one_D_node_id]){ - auto& D = d_v_structs[node].D; - int pre_d_v_size = D.size(); - D.erase(fixed_color); - int current_d_v_size = D.size(); - - if(current_d_v_size == 1 && pre_d_v_size == 2){ - add_node(node); - d_v_structs[node].inList = true; - } else if(current_d_v_size == 0 && pre_d_v_size == 1){ - delete_node(node); - d_v_structs[node].inList = false; - } - } - } - - void add_node(int node){ - d_v_one_list[ls_num] = node; - pos[node]=ls_num++; - } - - void delete_node(int node) - { - ls_num--; // Point to the last element - d_v_one_list[pos[node]]=d_v_one_list[ls_num]; // In the list of elements, place the last element at the position where you want to delete the element - pos[d_v_one_list[ls_num]]=pos[node]; // In the position list, update the position of the last element - } - - int getNeighborColorTable(){ - conf_ls_num=0; - conflictNum = 0; - int flag; - for (int i = 0; i < nodeNum; ++i) { - flag = 0; - int color = d_v_structs[i].nodeColor; - for (auto j = 0u; j < adjList[i].size(); ++j) { - int neighbor = adjList[i][j]; - int neighbor_color = d_v_structs[neighbor].nodeColor; - ++neighborColorTable[i][neighbor_color]; - if(color == neighbor_color){ // conflict - ++conflictNum; - if (flag==0) - { - add_conf(i); // i has conflict with neighbor j , add the conflict i nodes in to conf - flag=1; // node i has been added - } - } - } - } - // cout << "conf_ls_num_begin:" << conf_ls_num << endl; - return conflictNum / 2; - } - - void FastLSC(function &restMilliSec){ - iter = 0; - tabuList = neighborColorTable = vector>(nodeNum, vector(colorNum, 0)); - best_d_v_structs.resize(nodeNum); - while(restMilliSec() > 0){ - for (int i = 0; i < nodeNum; ++i) { - fill(tabuList[i].begin(), tabuList[i].end(), 0); - fill(neighborColorTable[i].begin(), neighborColorTable[i].end(), 0); - // d_v_structs[i].cscore = 0; - } - - conflictNum = getNeighborColorTable(); - // cout << "conflictNum begin:" << conflictNum << endl; - bestConflictNum = conflictNum; - - depth = 0; - while(depth < alpha && conflictNum > 0){ - findMove(); - makeMove(); - ++depth; - ++iter; - if(conflictNum < 100 && conflictNum <= bestConflictNum){ - bestConflictNum = conflictNum; - for(int i = 0; i < conf_ls_num; ++i){ - conf_list_best[i] = conf_list[i]; - } - // best_d_v_structs = d_v_structs; - for(int i = 0; i < nodeNum; ++i){ - best_d_v_structs[i].nodeColor = d_v_structs[i].nodeColor; - best_d_v_structs[i].state = d_v_structs[i].state; - // best_d_v_structs[i].inList = d_v_structs[i].inList; - } - } - } - - // cout << "bestConflictNum:" << bestConflictNum << endl; - if(conflictNum == 0){ - break; - } - - if(iter == alpha){ - for(int i = 0; i < nodeNum; ++i){ - best_d_v_structs[i].D = d_v_structs[i].D; - } - } - - d_v_structs = Perturb(); - } - } - - void findMove(){ - maxScore = INT_MIN; // bigger is better - tabu_maxScore = INT_MIN; - double count = 0; - double tabu_count = 0; - pair point_and_color; - - non_tabu_pair.clear(); - tabu_pair.clear(); - - // cout << conf_ls_num << " "; - for (int p = 0; p < conf_ls_num; ++p) { - int i = conf_list[p]; - // ++d_v_structs[i].cscore; - const auto& nodeStruct = d_v_structs[i]; - int oldColor = nodeStruct.nodeColor; - if(nodeStruct.D.empty()){ // D is empty means we cannot change the color - continue; - } - - const vector& tempColorTable = neighborColorTable[i]; - for(const auto &i1 : nodeStruct.D) { - // Consider changing the color of vertex i - if (oldColor == i1) { - continue; - } else { - vector& tempTabuTable = tabuList[i]; - // 5-2 means conflicts reduce 3, so bigger is better - int currentScore = tempColorTable[oldColor] - tempColorTable[i1]; - - point_and_color = make_pair(i,i1); - - if (depth >= tempTabuTable[i1]) { - if (currentScore > maxScore) { - maxScore = currentScore; - count = 1; - non_tabu_pair.push_back(point_and_color); - } else if (currentScore == maxScore && real_rand(0, 1) < 1 / (++count)) { - non_tabu_pair.push_back(point_and_color); - } - } else { - if (currentScore > tabu_maxScore) { - tabu_maxScore = currentScore; - tabu_count = 1; - tabu_pair.push_back(point_and_color); - } else if (currentScore == tabu_maxScore && real_rand(0, 1) < 1 / (++tabu_count)) { - tabu_pair.push_back(point_and_color); - } - } - } - } - } - } - - void makeMove(){ - int bestPoint = 0, bestColor = 0; - if (tabu_pair.size() > 0 && tabu_maxScore > maxScore && conflictNum - tabu_maxScore < bestConflictNum){ // choose tabu - maxScore = tabu_maxScore; - bestPoint = tabu_pair.back().first; - bestColor = tabu_pair.back().second; - }else { - bestPoint = non_tabu_pair.back().first; - bestColor = non_tabu_pair.back().second; - } - - auto& bestNode = d_v_structs[bestPoint]; - int oldColor = bestNode.nodeColor; - tabuList[bestPoint][oldColor] = depth + conflictNum + rand(10) + 1; // cannot change the color back in the next beta iters - - // Neighboring nodes are also affected Original color -1, new color +1 - // neighborColorTable: Distribution of Neighborhood Colors - // color1 color2 ... colorNum-1 - // 0 - // 1 - // 2 - // 3 - int neighbor; - int temp_size = adjList[bestPoint].size(); - for (int i = 0; i < temp_size; i++) { - neighbor = adjList[bestPoint][i]; - --neighborColorTable[neighbor][oldColor]; - ++neighborColorTable[neighbor][bestColor]; - // for neighbor - // if cause new conflict, add it - // 1.if neighbor is bestColor, before change, it has no conflict, but change brings new conflict, then add it - if(d_v_structs[neighbor].nodeColor == bestColor && neighborColorTable[neighbor][bestColor]==1){ // before was 0, because ++ change 1 - add_conf(neighbor); - } - // if reduce conflict to 0, delete it - // 2.if neighbor is oldColor, but with the change of i, no conflict, then delete it - else if(d_v_structs[neighbor].nodeColor == oldColor && neighborColorTable[neighbor][oldColor]==0){ // before was 1, because -- change 0 - delete_conf(neighbor); - // d_v_structs[neighbor].cscore = 0; - } - } - - // for bestPoint, if no conflict, delete it - if(neighborColorTable[bestPoint][bestColor] == 0){ - delete_conf(bestPoint); - } - - d_v_structs[bestPoint].nodeColor = bestColor; - conflictNum -= maxScore; - - d_v_structs[bestPoint].state = iter; - } - - void add_conf(int v) - { - conf_list[conf_ls_num]=v; - conf_pos[v]=conf_ls_num++; - } - - void delete_conf(int v) - { - conf_ls_num--; - conf_list[conf_pos[v]]=conf_list[conf_ls_num]; - conf_pos[conf_list[conf_ls_num]]=conf_pos[v]; - } - - bool similar(Pool_elment pool_element1, Pool_elment pool_element2) { - if(pool_element1.poolConflictNum != pool_element2.poolConflictNum) { - return false; - } - - unordered_set set1; - set1.reserve(colorNum); - for(const auto &item : pool_element1.nodes_in_conf_list) { - set1.insert(d_v_structs[item].nodeColor); - } - - for(const auto &item : pool_element2.nodes_in_conf_list) { - if(set1.find(d_v_structs[item].nodeColor) == set1.end()) { - return false; - } - set1.erase(d_v_structs[item].nodeColor); - } - - return set1.empty(); - } - - vector Perturb(){ - // init - vector d_v_structs_perturb; - Pool_elment pool_element; - pool_element.poolConflictNum = bestConflictNum; - pool_element.pool_d_v_structs = best_d_v_structs; - for(int i = 0;i < conf_ls_num;++i){ - pool_element.nodes_in_conf_list.insert(conf_list_best[i]); - } - - bool similar_pair = false; - - // 1.updating phase of the solution pool - if(bestConflictNum < bestPoolConflictNum) { - pool.clear(); - bestPoolConflictNum = pool_element.poolConflictNum; - pool.push_back(pool_element); - d_v_structs_perturb = pool_element.pool_d_v_structs; - } else { - for(auto &p : pool) { - ++p.time; - if(similar(p, pool_element)) { - for(int j = 0; j < nodeNum; ++j) { - p.pool_d_v_structs[j].state = pool_element.pool_d_v_structs[j].state; - } - similar_pair = true; - } - } - - if(similar_pair){ - // cout << "similar!!!" << endl; - // random select - int r = rand(pool.size()); - d_v_structs_perturb = pool[r].pool_d_v_structs; - }else{ - // int pool_size_2 = 20; - if(pool.size() < 20){ - pool.push_back(pool_element); - }else{ - int oldest_time = -1; - int oldest_no = 0; - for(int i = 0; i < pool_size; ++i){ - if(pool[i].time > oldest_time){ - oldest_time = pool[i].time; - oldest_no = i; - } - } - pool[oldest_no] = pool_element; - } - d_v_structs_perturb = pool_element.pool_d_v_structs; - } - } - -// for(int i = 0;i < pool.size();++i){ -// ++pool[i].time; -// } - - // 2.the re-construction solution phase - int maxIter = INT_MIN; - int minIter = INT_MAX; - for(auto &node:d_v_structs_perturb){ - if(node.state > maxIter){ - maxIter = node.state; - } - if(node.state < minIter){ - minIter = node.state; - } - } - int RCL = (maxIter - minIter) * theta + minIter; -// cout << "maxIter:" << maxIter << endl; -// cout << "minIter:" << minIter << endl; -// cout << "RCL:" << RCL << endl; - C.clear(); - int pos_c = 0; - for(auto &node:d_v_structs_perturb){ - if(node.state <= RCL){ - // C[pos_c++] = node; - C.push_back(node); - pos_c++; - } - } - - // pos_c = C.size(); - int cnt = pos_c / 2; - // cout << cnt << endl; - while(cnt > 0){ - int rand_c = rand(pos_c); - unordered_set tempset = d_v_structs_perturb[C[rand_c].no].D; - if(!tempset.empty()) { - int index = rand(tempset.size()); - auto it = tempset.begin(); - advance(it, index); - d_v_structs_perturb[C[rand_c].no].nodeColor = *it; - // cout << C[rand_c].no << " "; - } - C[rand_c] = C[--pos_c]; - --cnt; - } - // cout << "pool.size:" << pool.size() << endl; - return d_v_structs_perturb; - } - }; - -// solver. - void solveLatinSquare(Table& output, LatinSquare& input, function restMilliSec, int seed, OlapBase& graph) { - Solver().solve(output, input, restMilliSec, seed, graph); - } - -} - - diff --git a/procedures/algo_cpp/lsc_standalone.cpp b/procedures/algo_cpp/lsc_standalone.cpp deleted file mode 100644 index 886f7856be..0000000000 --- a/procedures/algo_cpp/lsc_standalone.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/*copyright 2022 AntGroup CO., Ltd. - * - * 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. - */ - -#include "olap/olap_on_disk.h" -#include "tools/json.hpp" -#include "./algo.h" - -using namespace lgraph_api; -using namespace lgraph_api::olap; -using json = nlohmann::json; - -class MyConfig : public ConfigBase { - public: - // std::string root = "0"; - std::string name = std::string("lsc"); - void AddParameter(fma_common::Configuration& config) { - ConfigBase::AddParameter(config); - // config.Add(root, "root", true).Comment("the root of bfs"); - } - void Print() { - ConfigBase::Print(); - std::cout << " name: " << name << std::endl; - // std::cout << " root: " << root << std::endl; - } - - MyConfig(int& argc, char**& argv) : ConfigBase(argc, argv) { - fma_common::Configuration config; - AddParameter(config); - config.ExitAfterHelp(true); - config.ParseAndFinalize(argc, argv); - Print(); - } -}; - -int main(int argc, char** argv) { - double start_time; - MemUsage memUsage; - memUsage.startMemRecord(); - - // prepare - start_time = get_time(); - MyConfig config(argc, argv); - OlapOnDisk graph; - // size_t root_vid; - graph.Load(config, DUAL_DIRECTION); - memUsage.print(); - memUsage.reset(); - auto prepare_cost = get_time() - start_time; - printf("prepare_cost = %.2lf(s)\n", prepare_cost); - - // core - start_time = get_time(); - // auto parent = graph.AllocVertexArray(); - // size_t count = BFSCore(graph, root_vid, parent); - - LSCCore(graph); - memUsage.print(); - memUsage.reset(); - auto core_cost = get_time() - start_time; - printf("core_cost = %.2lf(s)\n", core_cost); - - // output - start_time = get_time(); - // TODO(any): write to file - // printf("found_vertices = %ld\n", count); - auto output_cost = get_time() - start_time; - printf("output_cost = %.2lf(s)\n", output_cost); - - printf("total_cost = %.2lf(s)\n", prepare_cost + core_cost + output_cost); - printf("DONE."); - - return 0; -} From 2ac9f6664a372fd5b20381f26b6c3ddbf6f55fbd Mon Sep 17 00:00:00 2001 From: Dominic Date: Sat, 23 Nov 2024 14:56:02 +0800 Subject: [PATCH 4/6] Fixed code format. --- procedures/algo_cpp/khop_core.cpp | 27 +++++++++++-------------- procedures/algo_cpp/khop_standalone.cpp | 23 +++++++++------------ 2 files changed, 21 insertions(+), 29 deletions(-) diff --git a/procedures/algo_cpp/khop_core.cpp b/procedures/algo_cpp/khop_core.cpp index b44f7f21ca..2b52d6b4b9 100644 --- a/procedures/algo_cpp/khop_core.cpp +++ b/procedures/algo_cpp/khop_core.cpp @@ -1,4 +1,6 @@ /** + * Copyright 2024 Yingqi Zhao + * * @Function: Compute the k-hop algorithm. * @param: * @@ -19,42 +21,37 @@ using namespace lgraph_api; using namespace lgraph_api::olap; -size_t k_hop(OlapBase& graph, size_t root_vid, ParallelVector&result, size_t k) -{ + +size_t k_hop(OlapBase& graph, size_t root_vid, ParallelVector& result, size_t k) { size_t root = root_vid; auto active_in = graph.AllocVertexSubset(); active_in.Add(root); auto active_out = graph.AllocVertexSubset(); - auto parent=graph.AllocVertexArray(); + auto parent = graph.AllocVertexArray(); parent.Fill(0); - parent[root]=root; + parent[root] = root; size_t num_activations = 1; size_t discovered_vertices, j = 0; - for (size_t ii = 0; ii < k ; ii++) - { + for (size_t ii = 0; ii < k; ii++) { active_out.Clear(); num_activations = graph.ProcessVertexActive( [&](size_t vi) { size_t num_activations = 0; - for (auto& edge : graph.OutEdges(vi)) - { + for (auto& edge : graph.OutEdges(vi)) { size_t dst = edge.neighbour; - if (parent[dst] == 0) - { + if (parent[dst] == 0) { auto lock = graph.GuardVertexLock(dst); - if(parent[dst] == 0) - { + if (parent[dst] == 0) { parent[dst] = vi; num_activations += 1; active_out.Add(dst); - result[j++]=dst; + result[j++] = dst; } } } return num_activations; }, - active_in - ); + active_in); printf("activates(%lu) <= %lu \n", ii+1, num_activations); discovered_vertices += num_activations; active_in.Swap(active_out); diff --git a/procedures/algo_cpp/khop_standalone.cpp b/procedures/algo_cpp/khop_standalone.cpp index 887e1ae3ca..91d370c2ec 100644 --- a/procedures/algo_cpp/khop_standalone.cpp +++ b/procedures/algo_cpp/khop_standalone.cpp @@ -1,3 +1,4 @@ +// Copyright 2024 Yingqi Zhao #include "olap/olap_on_disk.h" #include "tools/json.hpp" #include "./algo.h" @@ -5,29 +6,23 @@ using namespace lgraph_api; using namespace lgraph_api::olap; using json = nlohmann::json; -class MyConfig : public ConfigBase -{ +class MyConfig : public ConfigBase { public: std::string root = "0"; std::string name = std::string("khop"); - size_t value_k=3; - void AddParameter(fma_common::Configuration& config) - { + size_t value_k = 3; + void AddParameter(fma_common::Configuration& config) { ConfigBase::AddParameter(config); config.Add(root, "root", true).Comment("Identifier of the root node."); - config.Add(value_k, "value_k", true).Comment( - "Number of search layers(value of k in K-hop algorithm)." - ); + config.Add(value_k, "value_k", true).Comment("Number of search layers(value of k in K-hop algorithm)."); } - void Print() - { + void Print() { ConfigBase::Print(); std::cout << " name: " << name << std::endl; std::cout << " root: " << name << std::endl; std::cout << " value_k: " << value_k << std::endl; } - MyConfig(int& argc, char**& argv) : ConfigBase(argc, argv) - { + MyConfig(int& argc, char**& argv) : ConfigBase(argc, argv) { fma_common::Configuration config; AddParameter(config); config.ExitAfterHelp(true); @@ -36,7 +31,7 @@ class MyConfig : public ConfigBase } }; -extern size_t k_hop(OlapBase& graph, size_t root_vid, ParallelVector&result, size_t k); +extern size_t k_hop(OlapBase& graph, size_t root_vid, ParallelVector& result, size_t k); int main(int argc, char** argv){ double start_time; @@ -78,6 +73,6 @@ int main(int argc, char** argv){ printf("core_cost = %.2lf(s)\n", core_cost); printf("output_cost = %.2lf(s)\n", output_cost); printf("total_cost = %.2lf(s)\n", prepare_cost + core_cost + output_cost); - printf("DONE. \n"); + printf("DONE.\n"); return 0; } \ No newline at end of file From da103b6a61e5221e60e4536d5b1a2901cd764513 Mon Sep 17 00:00:00 2001 From: Dominic Date: Sat, 23 Nov 2024 15:21:02 +0800 Subject: [PATCH 5/6] Fixed code format. --- procedures/algo_cpp/khop_standalone.cpp | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/procedures/algo_cpp/khop_standalone.cpp b/procedures/algo_cpp/khop_standalone.cpp index 91d370c2ec..e9c401edbb 100644 --- a/procedures/algo_cpp/khop_standalone.cpp +++ b/procedures/algo_cpp/khop_standalone.cpp @@ -33,7 +33,7 @@ class MyConfig : public ConfigBase { extern size_t k_hop(OlapBase& graph, size_t root_vid, ParallelVector& result, size_t k); -int main(int argc, char** argv){ +int main(int argc, char** argv) { double start_time; MemUsage memUsage; memUsage.startMemRecord(); @@ -42,37 +42,36 @@ int main(int argc, char** argv){ OlapOnDisk graph; graph.Load(config, INPUT_SYMMETRIC); size_t root_vid; - auto result=graph.AllocVertexArray(); + auto result = graph.AllocVertexArray(); result.Fill(0); - if(config.id_mapping) + if (config.id_mapping) root_vid = graph.hash_list_.find(config.root); else root_vid = std::stoi(config.root); - size_t value_k=config.value_k; + size_t value_k = config.value_k; memUsage.print(); memUsage.reset(); auto prepare_cost = get_time()- start_time; printf("prepare_cost = %.2lf(s)\n", prepare_cost); start_time = get_time(); - size_t count_result=k_hop(graph, root_vid, result, value_k); + size_t count_result = k_hop(graph, root_vid, result, value_k); memUsage.print(); memUsage.reset(); auto core_cost = get_time()- start_time; - + start_time = get_time(); - if (config.output_dir != "") - { + if (config.output_dir != "") { graph.Write(config, result, graph.NumVertices(), config.name); } printf("\n================\n"); printf("Find %lu vertexes in %lu-hop from node NO.%lu", count_result, value_k, root_vid); printf("\n================\n"); auto output_cost = get_time()- start_time; - + printf("core_cost = %.2lf(s)\n", core_cost); printf("output_cost = %.2lf(s)\n", output_cost); printf("total_cost = %.2lf(s)\n", prepare_cost + core_cost + output_cost); printf("DONE.\n"); return 0; -} \ No newline at end of file +} From 10ac8323ba8a563785771a3dcc80a6ae2cfc8151 Mon Sep 17 00:00:00 2001 From: Dominic Date: Sat, 23 Nov 2024 15:28:40 +0800 Subject: [PATCH 6/6] Fix more format bugs. --- procedures/algo_cpp/khop_standalone.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/procedures/algo_cpp/khop_standalone.cpp b/procedures/algo_cpp/khop_standalone.cpp index e9c401edbb..e5d45ee2c9 100644 --- a/procedures/algo_cpp/khop_standalone.cpp +++ b/procedures/algo_cpp/khop_standalone.cpp @@ -14,7 +14,8 @@ class MyConfig : public ConfigBase { void AddParameter(fma_common::Configuration& config) { ConfigBase::AddParameter(config); config.Add(root, "root", true).Comment("Identifier of the root node."); - config.Add(value_k, "value_k", true).Comment("Number of search layers(value of k in K-hop algorithm)."); + config.Add(value_k, "value_k", true).Comment( + "Number of search layers(value of k in K-hop algorithm)."); } void Print() { ConfigBase::Print(); @@ -31,7 +32,8 @@ class MyConfig : public ConfigBase { } }; -extern size_t k_hop(OlapBase& graph, size_t root_vid, ParallelVector& result, size_t k); +extern size_t k_hop(OlapBase& graph, size_t root_vid, + ParallelVector& result, size_t k); int main(int argc, char** argv) { double start_time; @@ -53,7 +55,7 @@ int main(int argc, char** argv) { memUsage.reset(); auto prepare_cost = get_time()- start_time; printf("prepare_cost = %.2lf(s)\n", prepare_cost); - + start_time = get_time(); size_t count_result = k_hop(graph, root_vid, result, value_k); memUsage.print();