コード例 #1
0
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;
}
コード例 #2
0
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;
}
コード例 #3
0
ファイル: gal_combine.cpp プロジェクト: paddya/KaHIP
// 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;

        
}
コード例 #4
0
ファイル: query.cpp プロジェクト: renqHIT/Tale
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");
}