// ヒントを与えた上でgreedy探索を行う // graph: 元となったグラフ構造 // parent_nodes, child_nodes: parent_nodesに含まれるnodeからchild_nodeに含まれるnodeにしか辺を張らない double learn_with_hint(graph_t& graph, std::vector<vertex_type> parent_nodes, std::vector<vertex_type> child_nodes) { // 子ノードの出現順序をランダムに std::shuffle(std::begin(child_nodes), std::end(child_nodes), engine_); // 最高評価値を保存しておく sampling_.make_cpt(graph); double eval_now = eval_(graph); // 親候補と子候補を全部回して様子見る for(auto const& child : child_nodes) { // 親ノードの出現順序をランダムに std::shuffle(std::begin(parent_nodes), std::end(parent_nodes), engine_); for(auto const& parent : parent_nodes) { if(auto edge = graph.add_edge(parent, child)) { // 辺が張れたならば,評価をする sampling_.make_cpt(graph); auto const eval_next = eval_(graph); if(eval_next < eval_now) // 良くなってるscore eval_now = eval_next; else // 変わらない or 悪い -> 元に戻す graph.erase_edge(edge); } } } return eval_now; }
void randomgraph_construction(graph_t &g, size_t vertex_num, size_t edge_num, gBenchPerf_event & perf, int perf_group) { vector<pair<size_t,size_t> > edges; for (size_t i=0;i<edge_num;i++) { edges.push_back(make_pair(rand()%vertex_num, rand()%vertex_num)); } perf.open(perf_group); perf.start(perf_group); for (size_t i=0;i<vertex_num;i++) { vertex_iterator vit = g.add_vertex(); vit->set_property(vertex_property(i)); } #ifdef SIM SIM_BEGIN(true); #endif for (size_t i=0;i<edge_num;i++) { edge_iterator eit; g.add_edge(edges[i].first, edges[i].second, eit); #ifndef SIM eit->set_property(edge_property(i)); #endif } #ifdef SIM SIM_END(true); #endif perf.stop(perf_group); }
double operator()(graph_t& graph, std::vector<vertex_type> vertexes) { std::shuffle(vertexes.begin(), vertexes.end(), engine_); // bestな構造を保持しておく sampling_.make_cpt(graph); double eval_now = eval_(graph); for(auto it = vertexes.begin(); it != vertexes.end();) { auto const child_iter = it; std::shuffle(++it, vertexes.end(), engine_); for(auto parent_iter = it; parent_iter != vertexes.end(); ++parent_iter) { if(auto edge = graph.add_edge(*parent_iter, *child_iter)) { // 辺を貼れたなら調べてみる sampling_.make_cpt(graph); auto const eval_next = eval_(graph); if(eval_next < eval_now) { // 良くなってる eval_now = eval_next; } else { // 変わらない,もしくは悪い == 元に戻す graph.erase_edge(edge); } } } } return eval_now; }
void parallel_randomgraph_construction(graph_t &g, size_t vertex_num, size_t edge_num) { vector<pair<size_t,size_t> > edges; for (size_t i=0;i<edge_num;i++) { edges.push_back(make_pair(rand()%vertex_num, rand()%vertex_num)); } for (size_t i=0;i<vertex_num;i++) { vertex_iterator vit = g.add_vertex(); vit->set_property(vertex_property(i)); } uint64_t chunk = (unsigned)ceil(edge_num/(double)threadnum); #pragma omp parallel num_threads(threadnum) { unsigned tid = omp_get_thread_num(); unsigned start = tid*chunk; unsigned end = start + chunk; if (end > edge_num) end = edge_num; #ifdef SIM SIM_BEGIN(true); #endif for (size_t i=start;i<end;i++) { edge_iterator eit; g.add_edge(edges[i].first, edges[i].second, eit); #ifndef SIM eit->set_property(edge_property(i)); #endif } #ifdef SIM SIM_END(true); #endif } }