int max_matching(){ memset(left, -1, sizeof(left)); memset(right, -1, sizeof(right)); int i, counter = 0; for (i = 0; i < n; i++){ clr(visited); if (bipartite_matching(i)) counter++; } return counter; }
bool bipartite_matching(int u){ int v = 0, j = 0; for (j = 0; j < len[u]; j++){ v = adj[u][j]; if (visited[v]) continue; visited[v] = true; if (right[v] == -1 || bipartite_matching(right[v])){ left[u] = v; right[v] = u; return true; } } return false; }
// implements our version of gal combine // compute a matching between blocks (greedily) // extend to partition // apply our refinements and tabu search void gal_combine::perform_gal_combine( PartitionConfig & config, graph_access & G) { //first greedily compute a matching of the partitions std::vector< std::unordered_map<PartitionID, unsigned> > counters(config.k); forall_nodes(G, node) { //boundary_pair bp; if(counters[G.getPartitionIndex(node)].find(G.getSecondPartitionIndex(node)) != counters[G.getPartitionIndex(node)].end()) { counters[G.getPartitionIndex(node)][G.getSecondPartitionIndex(node)] += 1; } else { counters[G.getPartitionIndex(node)][G.getSecondPartitionIndex(node)] = 1; } } endfor std::vector< PartitionID > permutation(config.k); for( unsigned i = 0; i < permutation.size(); i++) { permutation[i] = i; } random_functions::permutate_vector_good_small(permutation); std::vector<bool> rhs_matched(config.k, false); std::vector<PartitionID> bipartite_matching(config.k); for( unsigned i = 0; i < permutation.size(); i++) { PartitionID cur_partition = permutation[i]; PartitionID best_unassigned = config.k; NodeWeight best_value = 0; for( std::unordered_map<PartitionID, unsigned>::iterator it = counters[cur_partition].begin(); it != counters[cur_partition].end(); ++it) { if( rhs_matched[it->first] == false && it->second > best_value ) { best_unassigned = it->first; best_value = it->second; } } bipartite_matching[cur_partition] = best_unassigned; if( best_unassigned != config.k ) { rhs_matched[best_unassigned] = true; } } std::vector<bool> blocked_vertices(G.number_of_nodes(), false); forall_nodes(G, node) { if( bipartite_matching[G.getPartitionIndex(node)] == G.getSecondPartitionIndex(node) ){ blocked_vertices[node] = true; } else { // we will reassign this vertex since the partitions do not agree on it G.setPartitionIndex(node, config.k); } } endfor construct_partition cp; cp.construct_starting_from_partition( config, G ); refinement* refine = new mixed_refinement(); double real_epsilon = config.imbalance/100.0; double epsilon = random_functions::nextDouble(real_epsilon+0.005,real_epsilon+config.kabaE_internal_bal); PartitionConfig copy = config; copy.upper_bound_partition = (1+epsilon)*ceil(config.largest_graph_weight/(double)config.k); complete_boundary boundary(&G); boundary.build(); tabu_search ts; ts.perform_refinement( copy, G, boundary); //now obtain the quotient graph complete_boundary boundary2(&G); boundary2.build(); copy = config; copy.upper_bound_partition = (1+epsilon)*ceil(config.largest_graph_weight/(double)config.k); refine->perform_refinement( copy, G, boundary2); copy = config; cycle_refinement cr; cr.perform_refinement(config, G, boundary2); delete refine; }
void Query::mcb_matching( HashGraph* Gdb, ImpNodeMatches& nmmatches, GraphMatch* gm) { int Asize=nmmatches.size(); int Bsize=0; vector<int> dbnodes; hash_map<int, int> dbnodes_index_map; for(int i=0; i<Asize; i++) { debug(37, "-- query node: "<<nmmatches[i]->qnode<<"\n"); for(unsigned int j=0; j<nmmatches[i]->dbnodes->size(); j++) { DBNodeMapping dbnm=(*(nmmatches[i]->dbnodes))[j]; NodeMapping mp; mp.source=i; mp.score=dbnm.score; //debug(37, dbnode); hash_map<int, int>::iterator iter=dbnodes_index_map.find(dbnm.dbnode); if(iter==dbnodes_index_map.end()) { mp.target=Bsize; dbnodes.push_back(dbnm.dbnode); dbnodes_index_map.insert(hash_map<int, int>::value_type(dbnm.dbnode, Bsize)); Bsize++; }else { mp.target=iter->second; debug(37, " ("<<iter->second+Asize<<")\n"); } gm->mappings.insert(mp); } } //prepare for the input of MAX_CARD_BIPARTITE_MATCHING int numMappings=gm->mappings.size(); NodeMappingTwin* mappings=new NodeMappingTwin[numMappings]; int i=0; for(NodeMappingSet::iterator iter=gm->mappings.begin(); iter!=gm->mappings.end(); iter++) { mappings[i].source=iter->source; mappings[i].target=iter->target; mappings[i].score=iter->score; i++; } gm->mappings.clear(); bipartite_matching(Asize, Bsize, numMappings, mappings); for(int i=0; i<numMappings; i++) { int Ai=mappings[i].source; int Bi=mappings[i].target; NodeMapping mp; mp.source=nmmatches[Ai]->qnode; mp.target=dbnodes[Bi]; gm->mappings.insert(mp); } delete [] mappings; debug(37, "-- ending of mcb_matching\n"); }