コード例 #1
0
ファイル: cfg1.c プロジェクト: TakeScoop/node-glpk
int cfg_find_clique(void *P, CFG *G, int ind[], double *sum_)
{     int nv = G->nv;
      struct csa csa;
      int i, k, len;
      double sum;
      /* initialize common storage area */
      csa.P = P;
      csa.G = G;
      csa.ind = talloc(1+nv, int);
      csa.nn = -1;
      csa.vtoi = talloc(1+nv, int);
      csa.itov = talloc(1+nv, int);
      csa.wgt = talloc(1+nv, double);
      /* build induced subgraph */
      build_subgraph(&csa);
#ifdef GLP_DEBUG
      xprintf("nn = %d\n", csa.nn);
#endif
      /* if subgraph has less than two vertices, do nothing */
      if (csa.nn < 2)
      {  len = 0;
         sum = 0.0;
         goto skip;
      }
      /* find maximum weight clique in induced subgraph */
#if 1 /* FIXME */
      if (csa.nn <= 50)
#endif
      {  /* induced subgraph is small; use exact algorithm */
         len = find_clique(&csa, ind);
      }
      else
      {  /* induced subgraph is large; use greedy heuristic */
         len = find_clique1(&csa, ind);
      }
      /* do not report clique, if it has less than two vertices */
      if (len < 2)
      {  len = 0;
         sum = 0.0;
         goto skip;
      }
      /* convert indices of clique vertices from induced subgraph to
       * original conflict graph and compute clique weight */
      sum = 0.0;
      for (k = 1; k <= len; k++)
      {  i = ind[k];
         xassert(1 <= i && i <= csa.nn);
         sum += csa.wgt[i];
         ind[k] = csa.itov[i];
      }
skip: /* free working arrays */
      tfree(csa.ind);
      tfree(csa.vtoi);
      tfree(csa.itov);
      tfree(csa.wgt);
      /* return to calling routine */
      *sum_ = sum;
      return len;
}
コード例 #2
0
int build_subgraphs(deque<set<int> > & E, const deque<deque<int> > & member_matrix, deque<deque<int> > & member_list, 
                    deque<deque<int> > & link_list, const deque<int> & internal_degree_seq, const deque<int> & degree_seq, const bool excess, const bool defect) {
	
	
	
	E.clear();
	member_list.clear();
	link_list.clear();
	
	int num_nodes=degree_seq.size();
	
	//printm(member_matrix);
    
	
	
	
	{
    
    deque<int> first;
    for (int i=0; i<num_nodes; i++)
        member_list.push_back(first);
	
	}
	
	
	
	for (int i=0; i<member_matrix.size(); i++)
		for (int j=0; j<member_matrix[i].size(); j++)
			member_list[member_matrix[i][j]].push_back(i);
	
	
	//printm(member_list);
	
	for (int i=0; i<member_list.size(); i++) {
		
		deque<int> liin;
        
		
		for (int j=0; j<member_list[i].size(); j++) {
			
			compute_internal_degree_per_node(internal_degree_seq[i], member_list[i].size(), liin);
			liin.push_back(degree_seq[i] - internal_degree_seq[i]);
            
		}
		
		link_list.push_back(liin);
		
	}
    
	
	
    
	// now there is the check for the even node (it means that the internal degree of each group has to be even and we want to assure that, otherwise the degree_seq has to change) ----------------------------
    
	
	
	
	// ------------------------ this is done to check if the sum of the internal degree is an even number. if not, the program will change it in such a way to assure that. 
	
	
    
	for (int i=0; i<member_matrix.size(); i++) {
        
		
		int internal_cluster=0;
		for (int j=0; j<member_matrix[i].size(); j++) {
			
			int right_index= lower_bound(member_list[member_matrix[i][j]].begin(), member_list[member_matrix[i][j]].end(), i) - member_list[member_matrix[i][j]].begin();
			
            
			
			internal_cluster+=link_list[member_matrix[i][j]][right_index];
		}
		
		
		if(internal_cluster % 2 != 0) {
			
			
			
			bool default_flag=false;
			
			if(excess)
				default_flag=true;
			else if(defect)
				default_flag=false;
			else if (ran4()>0.5)
				default_flag=true;
			
			if(default_flag) {
				
				// if this does not work in a reasonable time the degree sequence will be changed
				
				for (int j=0; j<member_matrix[i].size(); j++) {		
					
					
					int random_mate=member_matrix[i][irand(member_matrix[i].size()-1)];
					
					int right_index= lower_bound(member_list[random_mate].begin(), member_list[random_mate].end(), i) - member_list[random_mate].begin();
					
					
					if ((link_list[random_mate][right_index]<member_matrix[i].size()-1) && (link_list[random_mate][link_list[random_mate].size()-1] > 0 )) {
						
						link_list[random_mate][right_index]++;
						link_list[random_mate][link_list[random_mate].size()-1]--;
                        
						break;
						
					}
                    
				}
                
                
			}
			
			
			else {
				
				for (int j=0; j<member_matrix[i].size(); j++) {
                    
					int random_mate=member_matrix[i][irand(member_matrix[i].size()-1)];
                    
					int right_index= lower_bound(member_list[random_mate].begin(), member_list[random_mate].end(), i) - member_list[random_mate].begin();
					
					if (link_list[random_mate][right_index] > 0 ) {
						
						link_list[random_mate][right_index]--;
						link_list[random_mate][link_list[random_mate].size()-1]++;
                        
						break;
						
					}
                    
				}
                
                
			}
			
			
			
            
		}
        
        
	}
	
	
	// ------------------------ this is done to check if the sum of the internal degree is an even number. if not, the program will change it in such a way to assure that. 
	
	
	
	
	{
	
    set<int> first;
    for(int i=0; i<num_nodes; i++)
        E.push_back(first);
	
	}
	
	for (int i=0; i<member_matrix.size(); i++) {
		
		
		deque<int> internal_degree_i;
		for (int j=0; j<member_matrix[i].size(); j++) {
            
            
			int right_index= lower_bound(member_list[member_matrix[i][j]].begin(), member_list[member_matrix[i][j]].end(), i) - member_list[member_matrix[i][j]].begin();
            
			internal_degree_i.push_back(link_list[member_matrix[i][j]][right_index]);
            
		}
		
		
		
		
		if(build_subgraph(E, member_matrix[i], internal_degree_i)==-1)
			return -1;
        
        
	}
    
    
    
    
	return 0;
	
}