usando el sistema;
utilizando System.Collections.Generic;
utilizando System.Linq;
usando System.Text;
usando System.Threading.Tasks;
namespace testDemo1
{ /// <summary> /// Algoritmo de sobre rojo, la relación de fluctuación está entre 0-1 /// </summary> class Program {
static void Main (string [] args) { Program p = new Program (); // Al distribuir la cantidad, asegúrese de prestar atención a la planificación razonable de la cantidad total, la cantidad de distribución y la cantidad máxima List <decimal> lists = p.createBonusList (500,500, decimal .Parse ("0.01"), 10, decimal.Parse ("0.5")); decimal Count = 0; foreach (var elemento en listas) { Count + = elemento; Console.WriteLine (elemento); } Console.WriteLine ( "Total:" + Recuento); }
Random ra = new Random ();
Lista <decimal> bonusList = nueva Lista <decimal> (); while (sendedNum <totalNum)
{ bonificación decimal = randomBonusWithSpecifyBound (totalBonus, totalNum, sendedBonus, sendedNum, rdMin, rdMax, bigRate); bonus = Convert.ToDecimal (bonus.ToString ("# 0.00")); bonusList.Add (bonificación); sendedNum ++; sendedBonus + = bonificación; } return bonusList; }
/// <summary>
/// 随机 分配 第 n 个 红包
/// </summary>
/// <param name = "totalBonus"> </param>
/// <param name = "totalNum"> </ param>
/// <param name = "sendedBonus"> </param>
/// <param name = "sendedNum"> </param>
/// <param name = "rdMin"> </param>
/// <param name = "rdMax"> </param>
/// <param name = "bigRate"> 平衡 度 0-1 </param>
/// <returns> </returns>
decimal privado randomBonusWithSpecifyBound (decimal totalBonus, decimal totalNum, decimal sendedBonus,
decimal sendedNum, decimal rdMin, decimal rdMax, decimal bigRate)
{
decimal avg = totalBonus / totalNum; // promedio 值
decimal leftLen = avg --rdMin;
decimal rightLen = rdMax --avg;
decimal boundMin = 0, boundMax = 0;
// Establecer una probabilidad pequeña en un rango grande
si (leftLen.Equals (rightLen))
{ boundMin = Math.Max ((totalBonus-sendedBonus- (totalNum-sendedNum-1) * rdMax), rdMin); boundMax = Math.Min ((totalBonus -sendedBonus- (totalNum-sendedNum-1) * rdMin), rdMax); } else if (rightLen.CompareTo (leftLen)> 0) { // desviación del límite superior decimal standardRdMax = avg + leftLen; // decimal simétrico del punto del límite superior derecho _rdMax = canReward (bigRate)? rdMax: standardRdMax; boundMin = Math.Max ((totalBonus-sendedBonus- (totalNum-sendedNum-1) * standardRdMax), rdMin);
boundMax = Math.Min ((totalBonus - sendedBonus - (totalNum - sendedNum - 1) * rdMin), _rdMax);
}
else
{ // 下限 偏离 decimal standardRdMin = avg - rightLen; // 左侧 对称 下限 点 decimal _rdMin = canReward (bigRate)? rdMin: standardRdMin; boundMin = Math.Max ((totalBonus - sendedBonus - (totalNum - sendedNum - 1) * rdMax), _rdMin); boundMax = Math.Min ((totalBonus - sendedBonus - (totalNum - sendedNum - 1) * standardRdMin), rdMax); }
// Escala dinámica de corrección de desplazamiento promedio enviada
if (boundMin.Equals (boundMax))
{ return getRandomVal (boundMin, boundMax); } decimal currAvg = sendedNum == 0? Avg: (sendedBonus / sendedNum); // actual Enviado medio decimal medio = (boundMin + boundMax) / Convert.ToDecimal (2.0); decimal subMin = boundMin, subMax = boundMax; // valor esperado decimal exp = avg- (currAvg-avg) * sendedNum / (totalNum-sendedNum) ; if (medio> exp) { subMax = Math.Round ((boundMin + exp) / Convert.ToDecimal (2.0)); } else
{ subMin = Math.Round ((exp + boundMax) / Convert.ToDecimal (2.0)); } decimal expBound = (boundMin + boundMax) / 2; expSub decimal = (subMin + subMax) / 2; subRate decimal = (exp - expBound) / (expSub - expBound); return getRandomValWithSpecifySubRate (boundMin, boundMax, subMin, subMax, subRate); }
/// <summary>
/// 下限 随机
/// </summary>
/// <param name = "rate"> </param>
/// <returns> </returns>
private bool canReward (tasa decimal)
{ return Convert.ToDecimal (ra.NextDouble (). ToString ()) <= tasa; }
/ **
* Devuelve un número aleatorio en el rango min ~ max, incluyendo min y max
* @param min
* @param max
* @return
* /
private decimal getRandomVal (decimal min, decimal max)
{ decimal v = Convert.ToDecimal (ra. NextDouble ()) * max; v = Convert.ToDecimal (v.ToString ("# 0.00")); return v> = min? V: min; }
/// <summary>
/// Algoritmo aleatorio con sesgo de probabilidad, el sesgo de probabilidad en el intervalo subMin ~ subMax devuelve un número aleatorio en el intervalo boundMin ~ boundMax (incluidos boundMin y boundMax), y al mismo tiempo, puede especificar la probabilidad de prioridad de subMin ~ subMax. Ejemplo: Pase los parámetros (10, 50, 20, 30, 0.8) y el resultado aleatorio se devolverá aleatoriamente de 20 a 30 con 80% de probabilidad, y se devolverá aleatoriamente de 10 a 50 con 20% de probabilidad
/// </summary>
// / <param name = "boundMin"> </param>
/// <param name = "boundMax"> </param>
/// <param name = "subMin"> </param>
/// <param name = "subMax"> </param>
/// <param name = "subRate"> </param>
/// <returns> </returns>
decimal privado getRandomValWithSpecifySubRate (decimal límiteMin, decimal límite máximo, decimal subMin, decimal subMáximo,subRate decimal)
{ if (canReward (subRate)) {
return getRandomVal (subMin, subMax);
}
return getRandomVal (boundMin, boundMax);
}
}
}