示例#1
0
/*
 * is_maximal()
 *
 * Check whether a clique is maximal or not.
 *
 *   clique - set of vertices in clique
 *   g      - graph
 *
 * Returns TRUE is clique is a maximal clique of g, otherwise FALSE.
 */
static boolean is_maximal(set_t clique, graph_t *g) {
	int i,j;
	int *table;
	int len;
	boolean addable;

	if (temp_count) {
		temp_count--;
		table=temp_list[temp_count];
	} else {
		table=malloc(g->n * sizeof(int));
	}

	len=0;
	for (i=0; i < g->n; i++)
		if (SET_CONTAINS_FAST(clique,i))
			table[len++]=i;

	for (i=0; i < g->n; i++) {
		addable=TRUE;
		for (j=0; j<len; j++) {
			if (!GRAPH_IS_EDGE(g,i,table[j])) {
				addable=FALSE;
				break;
			}
		}
		if (addable) {
			temp_list[temp_count++]=table;
			return FALSE;
		}
	}
	temp_list[temp_count++]=table;
	return TRUE;
}
示例#2
0
//static void maximalize_clique(set_t s,graph_t *g) {
void maximalize_clique(set_t s,graph_t *g) {
	int i,j;
	boolean add;

	for (i=0; i < g->n; i++) {
		add=TRUE;
		for (j=0; j < g->n; j++) {
			if (SET_CONTAINS_FAST(s,j) && !GRAPH_IS_EDGE(g,i,j)) {
				add=FALSE;
				break;
			}
		}
		if (add) {
			SET_ADD_ELEMENT(s,i);
		}
	}
	return;
}
示例#3
0
/*
 * graph_test()
 *
 * Tests graph g to be valid.  Checks that g is non-NULL, the edges are
 * symmetric and anti-reflexive, and that all vertex weights are positive.
 * If output is non-NULL, prints a few lines telling the status of the graph
 * to file descriptor output.
 * 
 * Returns TRUE if the graph is valid, FALSE otherwise.
 */
boolean graph_test(graph_t *g,FILE *output) {
	int i,j;
	int edges=0;
	int asymm=0;
	int nonpos=0;
	int refl=0;
	int extra=0;
	unsigned int weight=0;
	boolean weighted;

	ASSERT((sizeof(setelement)*8)==ELEMENTSIZE);

	if (g==NULL) {
		if (output)
			fprintf(output,"   WARNING: Graph pointer is NULL!\n");
		return FALSE;
	}

	weighted=graph_weighted(g);
	
	for (i=0; i < g->n; i++) {
		if (g->edges[i]==NULL) {
			if (output)
				fprintf(output,"   WARNING: Graph edge set "
					"NULL!\n"
					"   (further warning suppressed)\n");
			return FALSE;
		}
		if (SET_MAX_SIZE(g->edges[i]) < g->n) {
			if (output)
				fprintf(output,"   WARNING: Graph edge set "
					"too small!\n"
					"   (further warnings suppressed)\n");
			return FALSE;
		}
		for (j=0; j < g->n; j++) {
			if (SET_CONTAINS_FAST(g->edges[i],j)) {
				edges++;
				if (i==j) {
					refl++;
				}
				if (!SET_CONTAINS_FAST(g->edges[j],i)) {
					asymm++;
				}
			}
		}
		for (j=g->n; j < SET_ARRAY_LENGTH(g->edges[i])*ELEMENTSIZE;
		     j++) {
			if (SET_CONTAINS_FAST(g->edges[i],j))
				extra++;
		}
		if (g->weights[i] <= 0)
			nonpos++;
		if (weight<INT_MAX)
			weight += g->weights[i];
	}
	
	edges/=2;  /* Each is counted twice. */
	
	if (output) {
		/* Semi-weighted means all weights are equal, but not 1. */
		fprintf(output,"%s graph has %d vertices, %d edges "
			"(density %.2f).\n",
			weighted?"Weighted":
			((g->weights[0]==1)?"Unweighted":"Semi-weighted"),
			g->n,edges,(float)edges/((float)(g->n - 1)*(g->n)/2));
		
		if (asymm)
			fprintf(output,"   WARNING: Graph contained %d "
				"asymmetric edges!\n",asymm);
		if (refl)
			fprintf(output,"   WARNING: Graph contained %d "
				"reflexive edges!\n",refl);
		if (nonpos)
			fprintf(output,"   WARNING: Graph contained %d "
				"non-positive vertex weights!\n",nonpos);
		if (extra)
			fprintf(output,"   WARNING: Graph contained %d edges "
				"to non-existent vertices!\n",extra);
		if (weight>=INT_MAX)
			fprintf(output,"   WARNING: Total graph weight >= "
				"INT_MAX!\n");
		if (asymm==0 && refl==0 && nonpos==0 && extra==0 &&
		    weight<INT_MAX)
			fprintf(output,"Graph OK.\n");
	}
	
	if (asymm || refl || nonpos || extra || weight>=INT_MAX)
		return FALSE;

	return TRUE;
}
示例#4
0
/*
 * graph_print()
 *
 * Prints a representation of the graph g to stdout (along with any errors
 * noticed).  Mainly useful for debugging purposes and trivial output.
 *
 * The output consists of a first line describing the dimensions and then
 * one line per vertex containing the vertex number (numbered 0,...,n-1),
 * the vertex weight (if the graph is weighted), "->" and then a list
 * of all vertices it is adjacent to.
 */
void graph_print(graph_t *g) {
	int i,j;
	int asymm=0;
	int refl=0;
	int nonpos=0;
	int extra=0;
	unsigned int weight=0;
	boolean weighted;
	
	ASSERT((sizeof(setelement)*8)==ELEMENTSIZE);

	if (g==NULL) {
		printf("   WARNING: Graph pointer is NULL!\n");
		return;
	}
	if (g->n <= 0) {
		printf("   WARNING: Graph has %d vertices "
		       "(should be positive)!\n",g->n);
		return;
	}
	
	weighted=graph_weighted(g);

	printf("%s graph has %d vertices, %d edges (density %.2f).\n",
	       weighted?"Weighted":((g->weights[0]==1)?
				    "Unweighted":"Semi-weighted"),
	       g->n,graph_edge_count(g),
	       (float)graph_edge_count(g)/((float)(g->n - 1)*(g->n)/2));

	for (i=0; i < g->n; i++) {
		printf("%2d",i);
		if (weighted) {
			printf(" w=%d",g->weights[i]);
			if (g->weights[i] <= 0) {
				printf("*NON-POSITIVE*");
				nonpos++;
			}
		}
		if (weight < INT_MAX)
			weight+=g->weights[i];
		printf(" ->");
		for (j=0; j < g->n; j++) {
			if (SET_CONTAINS_FAST(g->edges[i],j)) {
				printf(" %d",j);
				if (i==j) {
					printf("*REFLEXIVE*");
					refl++;
				}
				if (!SET_CONTAINS_FAST(g->edges[j],i)) {
					printf("*ASYMMERTIC*");
					asymm++;
				}
			}
		}
		for (j=g->n; j < SET_ARRAY_LENGTH(g->edges[i])*ELEMENTSIZE;
		     j++) {
			if (SET_CONTAINS_FAST(g->edges[i],j)) {
				printf(" %d*NON-EXISTENT*",j);
				extra++;
			}
		}
		printf("\n");
	}

	if (asymm)
		printf("   WARNING: Graph contained %d asymmetric edges!\n",
		       asymm);
	if (refl)
		printf("   WARNING: Graph contained %d reflexive edges!\n",
		       refl);
	if (nonpos)
		printf("   WARNING: Graph contained %d non-positive vertex "
		       "weights!\n",nonpos);
	if (extra)
		printf("   WARNING: Graph contained %d edges to "
		       "non-existent vertices!\n",extra);
	if (weight>=INT_MAX)
		printf("   WARNING: Total graph weight >= INT_MAX!\n");
	return;
}
  void
  multibinpacking(Home home, 
         int n, int m, int k,
         const IntVarArgs& y, 
         const IntVarArgs& x, 
         const IntSharedArray& D,
         const IntSharedArray& B,
         IntConLevel) 
   {
      /// Check input sizes
      if (n*k != D.size() )
         throw ArgumentSizeMismatch("Int::multibinpacking");      

      if (k != B.size() )
         throw ArgumentSizeMismatch("Int::multibinpacking");      
    
      if (n != x.size() )
         throw ArgumentSizeMismatch("Int::multibinpacking");      
      
      if (m*k != y.size() )
         throw ArgumentSizeMismatch("Int::multibinpacking");      
      
      for (int i=B.size(); i--; )
         Limits::nonnegative(B[i],"Int::multibinpacking");

      if (home.failed()) return;

      /// Post first each single binpacking constraint
      /// Capacity constraint for each dimension
      for ( int j = 0; j < m; ++j )
         for ( int l = 0; l < k; ++l ) {
            IntView yi(y[j*k+l]);
            GECODE_ME_FAIL(yi.lq(home,B[l]));
         }

      /// Post a binpacking constraints for each dimension
      for ( int l = 0; l < k; ++l ) {
         ViewArray<OffsetView> yv(home,m);
         for (int j=m; j--; )
            yv[j] = OffsetView(y[j*k+l],0);

         ViewArray<BinPacking::Item> xs(home,x.size());
         for (int i=xs.size(); i--; )
            xs[i] = BinPacking::Item(x[i],D[i*k+l]);

         Support::quicksort(&xs[0], xs.size());

         GECODE_ES_FAIL(Int::BinPacking::Pack::post(home,yv,xs));
      }

      /// Clique Finding and Alldifferent posting
      {
         /// Firt construct the conflict graph
         graph_t* g = graph_new(n);
         for ( int a = 0; a < n-1; ++a ) {
            for ( int b = a+1; b < n; ++b ) {
               int v = a;  /// The variable with smaller domain
               int w = b;
               unsigned int nl = 0;
               if ( x[a].size() > x[b].size() ) {
                  v = b;
                  w = a;
               }
               IntVarValues i(x[v]);
               IntVarValues j(x[w]);
               while ( i() ) {
                  if ( i.val() != j.val() ) {
                     if ( i.val() < j.val() )
                        break;
                     else
                        ++i;
                  } else {
                     for ( int l = 0; l < k; ++l )
                        if ( D[a*k+l] + D[b*k+l] > B[l] ) {
                           nl++;
                           break;
                        }
                     ++i; ++j;
                  }
               }
               if ( nl >= x[v].size() )
                  GRAPH_ADD_EDGE(g,a,b);
            }
         }
         /// Consitency cheking: look for the maximum clique
         clique_options* opts;
         opts = (clique_options*) malloc (sizeof(clique_options));
         opts->time_function=NULL;
         opts->reorder_function=reorder_by_default;
         opts->reorder_map=NULL;
         opts->user_function=NULL;
         opts->user_data=NULL;
         opts->clique_list=NULL;
         opts->clique_list_length=0;
         set_t s;
         s = clique_find_single ( g, 0, 0, TRUE, opts);
         if ( s != NULL ) {
            if ( set_size(s) > m ) {
                set_free(s);
                free(opts);
                graph_free(g);
                GECODE_ES_FAIL(ES_FAILED);
            }
            if ( true ) { //option == 1 ) {  FIXING
               for ( int a = 0, j = 0; a < n; ++a ) {
                  if ( SET_CONTAINS_FAST(s,a) ) {
                     assert( x[a].in(j) );
                     IntView xi(x[a]);
                     GECODE_ME_FAIL(xi.eq(home,j++));
                  }
               }
            }
         }
         if ( s!=NULL )
            set_free(s);
         /// List every maximal clique in the conflict graph
         opts->user_function=record_clique_func;
         clique_find_all ( g, 2, 0, TRUE, opts);
         for ( int c = 0; c < clique_count; c++ ) {
            ViewArray<IntView> xv(home, set_size(clique_list[c]));
            for ( int a = 0, idx = 0; a < n; ++a )
               if ( SET_CONTAINS_FAST(clique_list[c],a) )
                  xv[idx++] = x[a];
            GECODE_ES_FAIL(Distinct::Dom<IntView>::post(home,xv));
            set_free(clique_list[c]);
         }
         free(opts);
         graph_free(g);
      }
   }