예제 #1
0
파일: solver.c 프로젝트: xxyzzzq/open-wbo
int march_solve_rec()
{
	int branch_literal = 0, _result, _percentage_forced;
	int skip_left = 0, skip_right = 0, top_flag = 0;
#ifdef DISTRIBUTION
	int record_index = current_record;

	top_flag = TOP_OF_TREE;

	if( fix_recorded_literals(record_index) == UNSAT )
	    return UNSAT;

	if( record_index == 0 ) record_index = init_new_record( );
#endif
#ifdef SUPER_LINEAR
	if( depth < sl_depth ) subtree_size = 0;
	else if( subtree_size == SL_MAX ) return UNSAT;
	else	subtree_size++;
#endif
#ifdef TIMEOUT
	if( (int) clock() > CLOCKS_PER_SEC * TIMEOUT )
	    return UNKNOWN;
#endif
#ifdef SUBTREE_SIZE
	path_length++;
#endif
#ifdef CUT_OFF
	if( depth <= CUT_OFF ) last_SAT_bin = -1;

        if( solution_bin == last_SAT_bin )
	{
#ifdef DISTRIBUTION
	    records[ record_index ].UNSAT_flag = 1;
#endif
            return UNSAT;
	}
#endif
#ifdef DETECT_COMPONENTS
	determine_components();
#endif
#ifdef DISTRIBUTION
	branch_literal = records[record_index].branch_literal;

	if( branch_literal != 0 ) dist_acc_flag = 1;
	else
//	if( branch_literal == 0 )
#endif
	do
	{
#ifdef LOCAL_AUTARKY
	    int _depth;
	
	    _depth = analyze_autarky();
	    if( _depth == 0 )
	        printf("c global autarky found at depth %i\n", depth );
	    else if( _depth != depth )
	        printf("c autarky found at depth %i (from %i)\n", depth, _depth );
#endif
	    nodeCount++;

//	    printf("node %i @ depth %i\n", nodeCount, depth );

	    if( ConstructCandidatesSet() == 0 )
	    { 
	        if( depth > 0 )
	        {
		    if( checkSolution() == SAT ) return verifySolution();
	        }
	    	if( PreselectAll() == 0 )
		    return verifySolution();
	    }
	    else	ConstructPreselectedSet();

	    if( lookahead() == UNSAT )
	    {
	    	lookDead++;
	    	return UNSAT;
	    }

	    if( propagate_forced_literals() == UNSAT )
		return UNSAT;

	    branch_literal = get_signedBranchVariable();

//	    printf("c branch literal %i", branch_literal );
	}
	while( (percentage_forced > 50.0) || (branch_literal == 0) );
#ifdef PLOT
	if( plotCount++ >= 10000 )
	    return UNSAT;

	printf("\t%i\t%.3f\t%i\n", plotCount, sum_plot / count_plot, depth );
#endif
	_percentage_forced = percentage_forced;

#ifdef PARALLEL
	if( depth < para_depth )
	    if( para_bin & (1 << (para_depth - depth - 1) ) )
	    	branch_literal *= -1;
#endif
//	printf("branch_literal = %i at depth %i\n", branch_literal, depth );
#ifdef GLOBAL_AUTARKY
	if( depth == 0 )
	{
	    int i;
	    for( i = 1; i <= nrofvars; i++ )
	    {
		TernaryImpReduction[  i ] = 0;
		TernaryImpReduction[ -i ] = 0;
		
		if( kSAT_flag )
		{
		    btb_size[  i ] = 0;
		    btb_size[ -i ] = 0;
		}
	    }

	    if( kSAT_flag )
		for( i = 0; i < nrofbigclauses; ++i )
		    clause_reduction[ i ] = 0;

//	    branch_literal = 10;
	}
#endif
	NODE_START();
#ifdef BLOCK_PRESELECT
	set_block_stamps( branch_literal );
#endif

#ifdef DISTRIBUTION
	if( top_flag )
	{	
	    branch_literal *= -1;
	    current_rights++;
	    UPDATE_BIN();
	}
	skip_left = skip_node();
#endif
	if( (skip_left==0) && IFIUP( branch_literal, FIX_BRANCH_VARIABLE ) )
	{ 
#ifdef DISTRIBUTION
	    current_record = LEFT_CHILD;
#endif
	    _result = recursive_solve();
#ifdef DISTRIBUTION
	    LEFT_CHILD = current_record;
#endif
	    if( _result == SAT || _result == UNKNOWN ) return _result; }
	else {  
#ifdef DISTRIBUTION
		if( (LEFT_CHILD != 0)  && records[ LEFT_CHILD ].UNSAT_flag == 0 )
		{
		    records[ LEFT_CHILD ].UNSAT_flag = 1; 
//		    printf("c left child %i UNSAT by parent!\n", LEFT_CHILD );
		}
#endif
		PUSH( r, STACK_BLOCK );}

	NODE_END();

#ifdef BACKJUMP
	if( backjump_literal != 0 )
	  if( timeAssignments[ backjump_literal ] >= NARY_MAX )
	  {
//		printf("backjumping at depth %i due to literal %i\n", depth, backjump_literal );
		return UNSAT;
	  }
	backjump_literal = 0;
#endif

#ifdef DISTRIBUTION
	if( top_flag )
	{
	    current_rights--;
	    UPDATE_BIN();
	}
#endif
	percentage_forced = _percentage_forced;

#ifdef PARALLEL
	if( depth < para_depth ) goto parallel_skip_node;
#endif

#ifdef GLOBAL_AUTARKY
	if( depth == 0 )
	  if( kSAT_flag )
	  {
	    int i;
	    for( i = 1; i <= nrofvars; ++i )
	    {
		assert( TernaryImpReduction[  i ] == 0 );
		assert( TernaryImpReduction[ -i ] == 0 );

		assert( btb_size[  i ] == 0 );
		assert( btb_size[ -i ] == 0 );
	    }

	    for( i = 0; i < nrofbigclauses; ++i )
	    {
		clause_red_depth[ i ] = nrofvars;
		clause_SAT_flag[ i ]  = 0;
	    }
	  }

	  if( kSAT_flag )
	  {
	    int i;
	    for( i = 1; i <= nrofvars; ++i )
	    {
		assert( TernaryImpReduction[  i ] >= 0 );
		assert( TernaryImpReduction[ -i ] >= 0 );

		assert( btb_size[  i ] >= 0 );
		assert( btb_size[ -i ] >= 0 );
	    }
	  }

#endif
	NODE_START();
#ifdef BLOCK_PRESELECT
	set_block_stamps( branch_literal );
#endif
        if( top_flag == 0 )
	{
#ifdef DISTRIBUTION
	    current_rights++;
#endif
	    UPDATE_BIN();
	}
#ifdef DISTRIBUTION
	skip_right = skip_node();
#endif
	if( (skip_right == 0) && IFIUP( -branch_literal, FIX_BRANCH_VARIABLE ) )
	{
#ifdef DISTRIBUTION
	    current_record = RIGHT_CHILD;
#endif
	    _result = recursive_solve();
#ifdef DISTRIBUTION
	    RIGHT_CHILD = current_record;
#endif
	    if( _result == SAT || _result == UNKNOWN ) return _result;}
	else {  
#ifdef DISTRIBUTION
		if( (RIGHT_CHILD != 0) && records[ RIGHT_CHILD ].UNSAT_flag == 0 )
		{
		    records[ RIGHT_CHILD ].UNSAT_flag = 1; 
//		    printf("c right child %i UNSAT by parent!\n", RIGHT_CHILD );
		}
#endif
		PUSH( r, STACK_BLOCK );}
	NODE_END();

	if( top_flag == 0 )
	{	
#ifdef DISTRIBUTION
	    current_rights--;
#endif
	    UPDATE_BIN();
	}

#ifdef PARALLEL
	parallel_skip_node:;
#endif
//	printf("ended node %i at depth %i\n", nodeCount, depth );

	

#ifdef SUBTREE_SIZE
	if( (skip_flag == 0) && (jump_depth == 0)  && (current_rights == 0) )
	{
	    int subtree = path_length - depth;

//	    float cost = nodeCount * (CLOCKS_PER_SEC /  ((float)(clock() + 10 - first_time)));
//	    printf("c nodes per second = %.3f at level %i\n", cost, depth );

	    if( jump_depth >= 30 ) jump_depth = 999;

	    if( subtree >     SUBTREE_SIZE )
	    {
	        jump_depth = depth;

	        while( subtree > 2*SUBTREE_SIZE )
	        {
		   jump_depth++; 
		   subtree = subtree / 2;
	        }

	        if( jump_depth >= 20 ) jump_depth = 999;

	        skip_flag = 1;
	    }
	}
#endif
#ifdef DISTRIBUTION
	record_node( record_index, branch_literal, skip_left, skip_right );

	current_record = record_index;
#endif

#ifdef BACKJUMP
	if( kSAT_flag )
	{
	    int *_rstackp = rstackp, nrval;
	
	    while( --_rstackp > rstack )
	    {
		nrval = *_rstackp;
		if( (TernaryImpReduction[ nrval ] + TernaryImpReduction[ -nrval ]) != 0 )
		{
		    backjump_literal = nrval;
		    break;
		}
	    }
	}
#endif
#ifdef ADD_CONFLICT
	printConflict();
#endif
	return UNSAT;
}
예제 #2
0
CLOP_graph::CLOP_graph(
    const Epetra_CrsMatrix* A_,   // stiffness matrix
    const Epetra_IntVector* ND_,  // nodes for dofs
    const int overlap_,           // overlap
    const int partition_option_,  // partitioning option
    const int atype_,             // analysis type
    const int ndim_,              // spatial dimension
    int iwork1[],                 // integer work array
    int iwork2[],                 // integer work array
    int* & dofpart1,              // dofpart1[dofpart2[i]:dofpart2[i+1]-1] =
    int* & dofpart2,              //   dofs in overlapping subdomain i
    int & npart)                  // number of subdomains for processor
    : A(A_), ND(ND_), overlap(overlap_), partition_option(partition_option_),
      atype(atype_), ndim(ndim_), count1(iwork1), imap(iwork2)
{
    //
    // determine target number of dofs for each subdomain
    //
    int min_ndof_sub(10), ncdof_sub, nnode, ncomp, ndof_max, NumProc, MyPID;
    double scale_factor(1.5);
    if (atype == 1) ncdof_sub = 1;
    if (atype == 2) {
        if (ndim == 2) ncdof_sub = 3;
        if (ndim == 3) ncdof_sub = 6;
    }
    if (atype == 3) ncdof_sub = 3;
    ndof = A->NumMyRows();
    A->Comm().MaxAll(&ndof, &ndof_max, 1);
    MyPID = A->Comm().MyPID();
    NumProc = A->Comm().NumProc();
    ndof_target = int(sqrt(1.0*ndof_max*NumProc*ncdof_sub));
    ndof_target = ndof;
    if (ndof_target < min_ndof_sub) ndof_target = min_ndof_sub;
    //  cout << "MyPID, ndof, ndof_target = " << MyPID << " " << ndof << " "
    //       << ndof_target << endl;
    //
    // construct node graph and determine dofs for each node
    //   nnode = number of nodes
    //   node_con1[node_con2[i]:node_con2[i+1]-1] = nodes connected to node i
    //   dof_for_node1[dof_for_node2[i]:dof_for_node2[i+1]-1] = dofs for node i
    //
    int *node_con1, *node_con2, *dof_for_node1, *dof_for_node2;
    node_con1 = node_con2 = dof_for_node1 = dof_for_node2 = 0;
    construct_node_graph(node_con1, node_con2, dof_for_node1, dof_for_node2,
                         nnode);
    //
    // determine components
    //   ncomp = number of components for original node graph
    //   comp1[comp2[i]:comp2[i+1]-1] = nodes in component i
    //
    int *comp1, *comp2;
    comp1 = comp2 = 0;
    determine_components(node_con1, node_con2, nnode, comp1, comp2, ncomp);
    //  cout << "MyPID, ncomp = " << MyPID << " " << ncomp << endl;
    //
    // determine subdomains
    //   nsub = number of subdomains
    //   nsub1[nsub2[i]:nsub2[i+1]-1] = nodes in subdomain i
    //
    int *nsub1, *nsub2;
    nsub1 = nsub2 = 0;
    determine_subdomains(comp1, comp2, ncomp, node_con1, node_con2,
                         dof_for_node2, nnode, nsub1, nsub2);
    delete [] comp1;
    delete [] comp2;
    npart = nsub;
    //  cout << "MyPID, nsub = " << MyPID << " " << nsub << endl;
    //
    // determine overlapping subdomains
    //   nosub1[nosub2[i]:nosub2[i+1]-1] = nodes in overlapping subdomain i
    //
    int *nosub1, *nosub2;
    nosub1 = nosub2 = 0;
    determine_overlap(nsub1, nsub2, node_con1, node_con2, nnode,
                      nosub1, nosub2);
    delete [] node_con1;
    delete [] node_con2;
    delete [] nsub1;
    delete [] nsub2;
    //
    // determine dofs in overlapping subdomains
    //
    determine_dof_overlap(nosub1, nosub2, nnode, dof_for_node1, dof_for_node2,
                          dofpart1, dofpart2);
    delete [] nosub1;
    delete [] nosub2;
    delete [] dof_for_node1;
    delete [] dof_for_node2;
}