EnVisageOnline/Main/Source/Race/Race.cs

181 lines
5.6 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Iniphi.Calculations
{
public class Race
{
private decimal C_OU = 1.25M;
private Dictionary<int, RaceScore> RaceScores = new Dictionary<int, RaceScore>();
public decimal SCORE2MAX { get; set; }
public decimal SCORE1MAX { get; set; }
public Race(decimal cou)
{
C_OU = cou;
}
public void resetCalcModule()
{
RaceScores = new Dictionary<int, RaceScore>();
}
public string[] dumpScores()
{
string[] scores = new string[RaceScores.Keys.Count+1];
scores[0] = "Iteration,Score1,Score2,TotalScore,RawOver,RawUnder";
int indx = 1;
foreach (var s in RaceScores.Keys.OrderBy(x=>x))
{
scores[indx] = s.ToString()+","+ RaceScores[s].Score1.ToString() + "," + RaceScores[s].Score2.ToString() + "," + RaceScores[s].TotalScore.ToString() + ","+ RaceScores[s].RawOver.ToString() + "," + RaceScores[s].RawUnder.ToString();
indx++;
}
return scores;
}
public RaceScore GetBestMix()
{
decimal maxTotal = 0;
if (SCORE2MAX <= 0m)
SCORE2MAX = 100M;
if (SCORE1MAX <= 0m)
SCORE1MAX = 100M;
var rt = new RaceScore();
foreach (int weekOrd in RaceScores.Keys)
{
RaceScore r = RaceScores[weekOrd];
if (r != null)
{
if (weekOrd == 31)
{
}
r.Score1 = 1 - (r.Score1 / SCORE1MAX);
r.Score2 = (r.Score2 / SCORE2MAX);
r.TotalScore = ((r.Score1 *.66666m)+ (r.Score2*.33333m)) * 100;
if (r.TotalScore > maxTotal)
{
rt = r;
maxTotal = r.TotalScore;
}
}
}
return rt;
}
//Mix (key == week number, value= List of allocation totals for the week)
// SA
public void CalcIterationEx(List<decimal[]> Mix, int Iter, List<ProjectObj> projs)
{
try {
decimal rawO = 0m;
decimal rawU = 0m;
decimal score = Score1Ex(Mix, ref rawO, ref rawU);
decimal score2 = Score2Ex(projs);
RaceScore s = new RaceScore() { Score1 = score, Score2 = score2, MixIteration = Iter, RawUnder=rawU, RawOver=rawO };
RaceScores.Add(Iter, s);
}
catch(Exception dd)
{
}
}
// SA
private decimal Score2Ex(List<ProjectObj> Projects)
{
decimal Score2 = 0;
decimal S2_Proj = 0;
foreach (var p in Projects)
{
S2_Proj = Decimal.Divide(p.probability ,p.priority) * Decimal.Divide(p.score , p.weekOrdinal);
S2_Proj = S2_Proj * p.race2Multiple;
Score2 = Score2 + S2_Proj;
}
return Score2;
}
private decimal Score1Ex(List<decimal[]> Mix, ref decimal rawO, ref decimal rawU)
{
decimal S1_PerWeek = 0;
decimal S1 = 0;
int max = Mix.FirstOrDefault().Length;
for (int i = 0; i< max; i++) {
List<decimal> perweek = new List<decimal>();
foreach (var d in Mix)
{
perweek.Add(d[i]);
}
S1_PerWeek = Score1PerWeekEx(perweek,ref rawO, ref rawU);
S1 = S1 + S1_PerWeek;
}
return S1;
}
private decimal Score1PerWeekEx(List<decimal> AllocationTotals, ref decimal rawO, ref decimal rawU )
{
decimal O_Score = 0;
decimal U_Score = 0;
decimal Score1 = 0;
foreach(var A in AllocationTotals)
{
if (A < 0)
O_Score = O_Score + A;
else
U_Score = U_Score + A;
}
rawO += (0 - O_Score);
rawU += U_Score;
O_Score = 0 - O_Score;
O_Score = C_OU * O_Score;
Score1 = O_Score + U_Score;
return Score1;
}
}
public class ProjectObj
{
public int Position { get; set; }
public Dictionary<int,Hashtable> ProjectAllocation { get; set; }
public int probability { get; set; }
public int priority { get; set; }
public int score { get; set; }
public int weekOrdinal { get; set; }
public Guid Id { get; set; }
public int Score { get; set; }
public int StartPosition { get; set; }
public int Duration { get; set; }
public decimal race2Multiple { get; set; }
}
public class RaceScore
{
public decimal Score1 { get; set; }
public decimal Score2 { get; set; }
public decimal RawOver { get; set; }
public decimal RawUnder { get; set; }
public decimal TotalScore { get; set; }
public int MixIteration { get; set; }
public RaceScore clone()
{
return new RaceScore()
{
Score1 = this.Score1,
Score2 = this.Score2,
MixIteration = this.MixIteration,
TotalScore = this.TotalScore,
RawOver = this.RawOver,
RawUnder = this.RawUnder
};
}
}
}