int Parameter::PickValue()

in api/parameter.cpp [59:141]


int Parameter::PickValue()
{
    assert(!m_bound);

    int maxComplete    = 0;
    int maxTotal       = 0;
    int bestValue      = 0;
    int bestValueCount = 0;

    m_bound = true; // a white lie to facilitate Combination::Feasible()

    for (int value = 0; value < m_valueCount; ++value)
    {
        int totalZeros = 0;
        int complete   = 0;
        // try binding that value and see how feasible it is
        m_currentValue = value;

        for (ComboCollection::iterator iter = m_combinations.begin(); iter != m_combinations.end(); ++iter)
        {
            int zeros = (*iter)->Feasible();
            totalZeros += zeros;
            if ((*iter)->GetBoundCount() >= (*iter)->GetParameterCount() - 1)
            {
                if (zeros)
                    ++complete;

                if ((*iter)->ViolatesExclusion())
                {
                    // make sure we don't pick this value, and move on
                    totalZeros = -1;
                    complete   = -1;
                    break;
                }
            }
        }
        if (complete > maxComplete)
        {
            maxComplete    = complete;
            bestValue      = value;
            maxTotal       = totalZeros;
            bestValueCount = 1;
        }
        else if (complete == maxComplete)
        {
            if (totalZeros > maxTotal)
            {
                bestValue      = value;
                maxTotal       = totalZeros;
                bestValueCount = 1;
            }
            else if (!m_valueWeights.empty() && 0 == totalZeros && 0 == maxTotal)
            {
                // Arbitrary choice - we already have this parameter covered
                // Use weights if they exist
                bestValueCount += GetWeight(value);
                if (rand() % bestValueCount < GetWeight(value))
                {
                    bestValue = value;
                }
            }
            else if (totalZeros == maxTotal && !(rand() % ++bestValueCount))
            {
                bestValue = value;
                maxTotal  = totalZeros;
            }
        }
    }
    m_bound = false;

    // What if bestValueCount is 0 here due to exclusions?
    // That would be a bug, but better put in a check.
    if( m_task->GetGenerationMode() != GenerationMode::Preview )
    {
        assert( bestValueCount > 0 );
        if( bestValueCount <= 0 )
        {
            throw GenerationError( __FILE__, __LINE__, ErrorType::GenerationFailure );
        }
    }

    return bestValue;
}