So, after spending a couple days battling my own SelectCoins algorithm, I came up with a decent idea for how to do this without thinking

**too** hard, but still maintain the ability to expand it, later. The magic is in defining the following method:

uint32_t

**ScoreSelectCoinsOutput**(vector<unspentTxOut> selectedCoins, uint64_t targetVal, uint64_t minFee)

The input to this function is a coin-selection, a target output value and a fee. By writing a method that assigns a score to a selection, you you can then randomly sort your input list 100 times, pick the top X inputs that satisfy your target+fee, and then keep the one with the best score. In my code, I am slowly adding smarter solutions and phasing out the randomly selected ones, but if you pick a high enough sample size, you're bound to get at least one

*good* solution in pot even with nothing but random selections in the search:

vector<unspentTxOut> finalSelection;

uint32_t bestScore = UINT32_MAX;

for(int i=0; i<100; i++)

{

random_shuffle(unspentTxOutList.begin(), unspentTxOutList.end())

uint64_t sum = 0;

uint32_t index=0

vector<unspentTxOut> selection;

while(sum < target+fee)

{

selection.push_back(selection[index]);

sum += selection[index].getValue();

index++

}

uint32_t score = ScoreSelectCoinsOutput(selection, target, fee);

if( score < bestScore)

{

finalSelection = selection;

bestScore = score;

}

}

// Now you have a pretty good selection!

Then, the entire SelectCoins algorithm is based on how you "score" a selectCoins solution. In my code, I evaluate a bunch of different "selection factors", such as how many input addresses it combines, if it includes zero-confirm txs, how many bytes, how obvious it is which output is change/recipient, etc. I make sure that each of these factors spits out a number between 0 and 1 (with 1 being favorable), and then multiply each score by a weight:

WEIGHT_NOZEROCONF = 1000

WEIGHT_ALLOWFREE = 100

WEIGHT_NUMADDR = 100

WEIGHT_TXSIZE = 50

WEIGHT_PRIORITY = 60

WEIGHT_OUTANONYM = 30

The weights are configurable (and completely arbitrary--only significant relative to each other), and gives you the option to modify them for your use-case: you can make "WEIGHT_NUMADDR=10000" and "WEIGHT_OUTANONYM=10000" to try to max-out anonymity at any expense.