示例#1
0
// Search config in the hash table, if it is not there, this config will be 
// inserted. If inserted, *pCacheConfig will point to the location.
// return value
// 0 -- not found or can not be pruned
// 1 -- find a config that can be pruned in the cache
int TryFind(CConfig **arr, CConfig *pConfig, CConfig **pCacheConfig) 
{
	*pCacheConfig = NULL;
    //return 0;

    int index = pConfig->CalHashValue();
    CConfig *p = arr[index];

	if (!p) // the config is not found and insert this pConfig to it
	{ 
       
#ifdef USE_OWN_CACHE
        if (usedconfiglength>=MAXUSEDCONFIGSIZE) return 0;
		CConfig* pNewConfig = newCacheConfig(pConfig->len);
        if (!pNewConfig) return 0; // cache has been used up, just return;
#else
		if (usedconfiglength>=MAXUSEDCONFIGSIZE) return 0;
        CConfig* pNewConfig = new CConfig(pConfig->len);
		assert(pNewConfig);
#endif

        usedconfiglength++;
		pNewConfig->Copy(pConfig);
		arr[index] = pNewConfig;
		*pCacheConfig = pNewConfig;
		return 0;
	}

	if (p->ConfigCmp(pConfig)) return 0;
	
	// now the configs are the same
	if (p->depth <= pConfig->depth) 
	{
		// if a config hits the hash table with length no less than that in the 
		// table, it cannot be on the path of any optimal solutions not found
		// yet. Remember if an optimal solution is found, all configs along
		// the solution path stored in the hash table are released in 
		// Solution_Found() in solver.cpp
		return 1; 
	}
	else 
	{
		p->depth = pConfig->depth;
		*pCacheConfig = p;
		return 0;
	}
}
示例#2
0
// Solve the instance with the given config
// maxlen is the size of the maximum space allocated in pConfig
// return value:
//    -1: unsolvable
//     0: unsolved till the depth threshold
//   n>0: solved at depth of n
int CSolver::SolveConfig(CPCPInstance *pPCP, CConfig *pConfig, int maxlen)
{
	int i, j, k;
	
	// store the matched pairs and the lengths of resulting configs
	int arrRetValue[MAXSIZE];;
	int arrMatchedPair[MAXSIZE];
	int matchedPairNum;

	// ret value
	long int matchret;
	int solveret;
	int ret = -1;
	int succ;
    int newlen;

	// store the location of the config in the cache
	CConfig* pCacheConfig;
    CConfig *pNewConfig;

//	int lookaheadflag;
//   	long tmpret;

DEEP:
	//// Heuristic pruning
	if (IsPrunable(pPCP, pConfig)) 
		return 0;

    //// record all pairs which can be matched
	matchedPairNum = 0;  

/*
	if ( pConfig->up  && pPCP->maxdown*2<pConfig->len ||	
		 !pConfig->up && pPCP->maxup*2  <pConfig->len)
		lookaheadflag=1; // use traditional method
    else lookaheadflag=0;
*/	
	for (i=0;i<pPCP->size;i++)
	{
		matchret=pConfig->TestMatchingPair(&pPCP->arrPair[i]);

/*
		if (!lookaheadflag)
			matchret=pConfig->TestMatchingPair(&pPCP->arrPair[i]);
		else
		{
			matchret=2000000000;
			for (j=0;j<pPCP->size;j++)
			{
				tmpret = pConfig->TestMatchingPairs(pPCP, &pPCP->arrPair[i],
						                            &pPCP->arrPair[j]);
				if (tmpret>0 && tmpret<matchret) matchret = tmpret;
			}
			if (matchret==2000000000) matchret=-1;
		}
*/

		if (matchret==0) // find one solution
		{ 
			pConfig->depth++;
			arrSelection[pConfig->depth] = pPCP->arrPair[i].ID;
			succ = Solution_Found(pPCP, pConfig);
            if (succ>0) { return pConfig->depth; }
			else ret = 0;
			pConfig->depth--;	
		}
		else if (matchret>0) // find one match
		{
			// having exceeded the threshold, prune it
			if (pConfig->depth==iterative_depth_threshold-1) 
				ret=0; 
			else  // record the pair
			{
				arrRetValue[matchedPairNum] = matchret;
				arrMatchedPair[matchedPairNum++] = i;
			}
		}
	}

	//// no matched pair?
    if (matchedPairNum == 0) RETURNANDCLEAR;
        
	//// only one matched pair and the config can be reused? jump back!
	if (matchedPairNum==1  && arrRetValue[0]<=maxlen ) 
	{
		pConfig->MatchPair(&pPCP->arrPair[arrMatchedPair[0]], arrSelection);
		assert(pConfig->len <= maxlen);

		if (pConfig->up)
            if (pPCP->upmask) RETURNANDCLEAR;

		if (!pConfig->up)
            if (pPCP->downmask) RETURNANDCLEAR;

        succ = TryFind(hashTable, pConfig, &pCacheConfig);
        
		if (succ==1 || succ==2) // this configration is in the cache, prune it
		{ 
			Add_cutoff_node_number();
			//if (succ==2) ret = 0;
			RETURNANDCLEAR;
		}
	    goto DEEP;
	}

	//// sort the matched pair array according to its matchret value	
	for (i=0;i<matchedPairNum-1;i++)
		for (j=i+1;j<matchedPairNum;j++)
		{
			if (arrRetValue[i] > arrRetValue[j])
			{
				k = arrRetValue[i];
				arrRetValue[i] = arrRetValue[j];
				arrRetValue[j] = k;
				
				k = arrMatchedPair[i];
				arrMatchedPair[i] = arrMatchedPair[j];
				arrMatchedPair[j] = k;
			}
		}
	
	//// try the pair one by one		
	// count new length for config
	newlen = pConfig->len+pPCP->offset+MAXLOOPCOUNT*pPCP->offset;
	// create new config
#ifdef USE_CONFIG_POOL
    pNewConfig = newConfig(newlen);
#else
    pNewConfig = new CConfig(newlen);
#endif

    // try all matched pairs
	for (i=0;i<matchedPairNum;i++)
	{
		// the last matched pair and the config can be reused? Jump back!
		if (i+1==matchedPairNum && arrRetValue[i]<=maxlen )
        {

            pConfig->MatchPair(&pPCP->arrPair[arrMatchedPair[i]], arrSelection);
            if (pConfig->up)
                if (pPCP->upmask) continue;
            if (!pConfig->up)
                if (pPCP->downmask) continue;

#ifdef USE_CONFIG_POOL
            deleteConfig(newlen);
#else
            delete pNewConfig; 			
#endif                     
            succ = TryFind(hashTable, pConfig, &pCacheConfig);
                    
            if (succ==1 || succ==2) // this config is in the cache
            { 
                Add_cutoff_node_number();
                //if (succ==2) ret = 0; 
                RETURNANDCLEAR;
            }
            goto DEEP;
		}

        // duplicate pConfig to config
		pNewConfig->Copy(pConfig);

		// match it with the pair
		pNewConfig->MatchPair(&pPCP->arrPair[arrMatchedPair[i]], arrSelection);

		// test masks
		if (pNewConfig->up)
			if (pPCP->upmask) continue;
		if (!pNewConfig->up)
			if (pPCP->downmask) continue;

		// check cache
        succ = TryFind(hashTable, pNewConfig, &pCacheConfig);
		if (succ==1 || succ==2) // this config is in the cache
		{ 
			Add_cutoff_node_number();
			continue; 
		}
      
		// recursively call the SolveConfig routine
		solveret=SolveConfig(pPCP, pNewConfig, newlen);

		// check result
		if (solveret>0) // solve it
        { 
#ifdef USE_CONFIG_POOL
            deleteConfig(newlen);
#else
            delete pNewConfig;  
#endif
            return solveret; 
        }

		if (solveret==0) // cannot solve it to the iterative_depth_threshold
			ret=0; 
	}
#ifdef USE_CONFIG_POOL
    deleteConfig(newlen);
#else
    delete pNewConfig; 			
#endif

	RETURNANDCLEAR;
}