private OrgRank SingleRank(Matrix <double> matRanks, int rank_length, double[] awardNos, double[,] awards) { if (rank_length == 0) { //fill the top ranks of the length of awards as the last award double next_award = awardNos[0]; for (int i = 0; i < awardNos.Length; i++) { if (i < matRanks.RowCount) { matRanks[i, 1] = next_award; } } } OrgRank orgRank = new OrgRank(matRanks.ToArray(), awards); orgRank.AddSubRank(new Rank(matRanks.ToArray(), awards)); return(orgRank); }
private OrgRank SplitRank(Matrix <double> matRanks, int rank_length, double[] awardNos, double[,] awards) { Vector <double> vecAwardNos = CreateVector.DenseOfArray(awardNos); //fill the rest of ranks as the last award double next_award = vecAwardNos[rank_length]; for (int i = rank_length; i < matRanks.RowCount; i++) { if (i < matRanks.RowCount) { matRanks[i, 1] = next_award; } } OrgRank orgRank = new OrgRank(matRanks.ToArray(), awards); // split ranks into two groups Matrix <double> matRanks1 = matRanks.SubMatrix(0, rank_length, 0, matRanks.ColumnCount); // split award_numbers into two sub_awards double[,] awards1 = To2DAwards(vecAwardNos.SubVector(0, rank_length).ToArray()); Rank rank1 = new Rank(matRanks1.ToArray(), awards1); orgRank.AddSubRank(rank1); // split ranks into two groups int length = matRanks.RowCount - rank_length; Matrix <double> matRanks2 = matRanks.SubMatrix(rank_length, length, 0, matRanks.ColumnCount); // split award_numbers into two sub_awards length = awardNos.Length - rank_length; double[,] awards2 = To2DAwards(vecAwardNos.SubVector(rank_length, length).ToArray()); Rank rank2 = new Rank(matRanks2.ToArray(), awards2); orgRank.AddSubRank(rank2); return(orgRank); }
/// <summary> /// Rank the votes /// </summary> /// <param name="votes"> /// each row presents a project grains the number of votes per award /// int[P,A] /// P: Projects, A: the awards /// </param> /// <param name="awards"> /// each column presents a award's weight and number /// int[A,N] /// A: awards, N: the number per award /// </param> public OrgRank InitRank(int[] projects, double[,] votes, double[,] awards, bool isRevoted = false) { // matV(P,A) = actual votes to matrix PxW Matrix <double> matV = CreateMatrix.DenseOfArray(votes); // matA(W,N) = the awards's name and number Matrix <double> matA = CreateMatrix.DenseOfArray(awards); double[] scores = null; if (!isRevoted) { // vecA(W,1) = vector Ax1 // pick the award's weight into a single array double[] weights = matA.Column(0).ToArray(); weights = weights.Select(a => (double)Math.Pow(10, weights.Length - a)).ToArray(); Vector <double> vecA = CreateVector.DenseOfArray(weights); // S(P,1)=matV(P,A) X vecW(A,1) Vector <double> vecS = matV.Multiply(vecA.Conjugate()); scores = vecS.ToArray(); } else { scores = matV.Column(0).ToArray(); } // Sort and Rank // Sort by the scores Array.Sort(scores, projects, Comparer <double> .Create((a, b) => { if (a > b) { return(-1); } else if (a < b) { return(1); } return(0); })); // [1,2] // [2,2] => [1,1,2,2,3,3] // [3,2] double[] awardNos = To1DAwards(awards); // double[] awardItems = matA.Column(0).ToArray(); // column(0): projectId // column(1): actual rank // column(2): expected rank // column(3): score Matrix <double> matRanks = CreateMatrix.DenseOfColumnArrays(new double[][] { projects.Select(p => (double)p).ToArray(), new double[projects.Length], new double[projects.Length], scores }); //int rank_length = 0; int current = 0; while (true) { if (current >= projects.Length) { break; } if (current == 0) { matRanks[current, 1] = awardNos[current]; matRanks[current, 2] = awardNos[current]; } else if ((int)scores[current] == (int)scores[current - 1]) { matRanks[current, 1] = matRanks[current - 1, 1]; if (current < awardNos.Length) { matRanks[current, 2] = awardNos[current]; } } else if ((int)scores[current] < (int)scores[current - 1]) { //if (current >= awardNos.Length) // break; if (current < awardNos.Length) { matRanks[current, 1] = awardNos[current]; } if (current < awardNos.Length) { matRanks[current, 2] = awardNos[current]; } } else // (int) scores[current_score] > (int) scores[current_score - 1] { // won't be here // do nothing } current++; //rank_length++; } OrgRank orgRank = new OrgRank(matRanks.SubMatrix(0, matRanks.RowCount, 0, 2).ToArray(), awards); Stack <Rank> stack_Ranks = new Stack <Rank>(); int rank_length = matRanks.RowCount; for (int i = matRanks.RowCount - 1; i >= 0; i--) { if (i < matRanks.RowCount - 1) { // compare scores int cur = (int)matRanks[i, 3]; int last = (int)matRanks[i + 1, 3]; if (matRanks[i + 1, 1] > 0 && cur != last) // 0 rank means the project won't be involved into VoteVerify { int start_row = i + 1; int length = rank_length - (i + 1); // pick the [project,rank] double[,] ranks = matRanks.SubMatrix(start_row, length, 0, 2).ToArray(); // pick the [award] double[] sub_awardNos = matRanks.Column(2).SubVector(start_row, length).ToArray().Where(a => a > 0).ToArray(); double[,] sub_awards = this.To2DAwards(sub_awardNos); stack_Ranks.Push(new Rank(ranks, sub_awards)); // drop the part being picked above matRanks = matRanks.SubMatrix(0, start_row, 0, matRanks.ColumnCount); rank_length = matRanks.RowCount; } } if (i < matRanks.RowCount - 1 && (int)matRanks[i + 1, 1] <= 0) { // 0 rank means the project won't be involved into VoteVerify rank_length--; } // pick the last part if (i == 0) { int start_row = 0; int length = rank_length; // pick the [project,rank] double[,] ranks = matRanks.SubMatrix(start_row, length, 0, 2).ToArray(); // pick the [award] double[] sub_awardNos = matRanks.Column(2).SubVector(start_row, length).ToArray().Where(a => a > 0).ToArray(); double[,] sub_awards = this.To2DAwards(sub_awardNos); stack_Ranks.Push(new Rank(ranks, sub_awards)); } } while (stack_Ranks.Count > 0) { orgRank.AddSubRank(stack_Ranks.Pop()); } return(orgRank); }
public OrgRank InitRankOld(int[] projects, double[,] votes, double[,] awards, bool isRevoted = false) { // matV(P,A) = actual votes to matrix PxW Matrix <double> matV = CreateMatrix.DenseOfArray(votes); // matA(W,N) = the awards's name and number Matrix <double> matA = CreateMatrix.DenseOfArray(awards); double[] scores = null; if (!isRevoted) { // vecA(W,1) = vector Ax1 // pick the award's weight into a single array double[] weights = matA.Column(0).ToArray(); weights = weights.Select(a => (double)Math.Pow(10, weights.Length - a)).ToArray(); Vector <double> vecA = CreateVector.DenseOfArray(weights); // S(P,1)=matV(P,A) X vecW(A,1) Vector <double> vecS = matV.Multiply(vecA.Conjugate()); scores = vecS.ToArray(); } else { scores = matV.Column(0).ToArray(); } // Sort and Rank // Sort by the scores Array.Sort(scores, projects, Comparer <double> .Create((a, b) => { if (a > b) { return(-1); } else if (a < b) { return(1); } return(0); })); // [1,2] // [2,2] => [1,1,2,2,3,3] // [3,2] double[] awardNos = To1DAwards(awards); double[] awardItems = matA.Column(0).ToArray(); // Rank // Grain the rank denpending on the scores one by one // when the current score equals to the last, get the same level rank // when the current score is less than the last, get the next level rank int award_index = 0; // int award_no_index = 0; int rank_length = 0; int count_number = 0; int score_index = 0; // double last_score = 0.0d; Matrix <double> matRanks = CreateMatrix.DenseOfColumnArrays(new double[][] { projects.Select(p => (double)p).ToArray(), new double[projects.Length] }); while (true) { if (score_index == scores.Length) { break; } var current_score = scores[score_index]; if (current_score == 0) { rank_length += count_number; break; } if (score_index > 0 && current_score < scores[score_index - 1]) { var current_award_no = matA[award_index, 1]; if (count_number >= current_award_no) { award_index++; rank_length += count_number; count_number = 0; if (award_index == awardItems.Length) { break; } } } else if (score_index > 0 && current_score == scores[score_index - 1]) { // do nothing } matRanks[score_index, 1] = awardItems[award_index]; score_index++; count_number++; } OrgRank orgRank = new OrgRank(); if (rank_length == 0 || rank_length == awardNos.Length) { orgRank = SingleRank(matRanks, rank_length, awardNos, awards); } else if (rank_length > awardNos.Length) { int newRank_length = this.CalculateNearestLength(scores, rank_length, awardNos.Length); if (newRank_length < awardNos.Length) { // split again Vector <double> vecAwardNos = CreateVector.DenseOfArray(awardNos); orgRank = new OrgRank(matRanks.ToArray(), awards); // split ranks into two groups Matrix <double> matRanks1 = matRanks.SubMatrix(0, newRank_length, 0, matRanks.ColumnCount); // split award_numbers into two sub_awards double[,] awards1 = To2DAwards(vecAwardNos.SubVector(0, newRank_length).ToArray()); Rank rank1 = new Rank(matRanks1.ToArray(), awards1); orgRank.AddSubRank(rank1); // here rank_length must great than newRank_length // because it should always equals or less than rank_length // it should go to the first SingleRank() if rank_length==newRank_length if (rank_length > newRank_length) { // split ranks into two groups int length = rank_length - newRank_length; Matrix <double> matRanks2 = matRanks.SubMatrix(newRank_length, length, 0, matRanks.ColumnCount); // split award_numbers into two sub_awards length = awardNos.Length - newRank_length; double[,] awards2 = To2DAwards(vecAwardNos.SubVector(newRank_length, length).ToArray()); Rank rank2 = new Rank(matRanks2.ToArray(), awards2); orgRank.AddSubRank(rank2); } } else // newRank_length >= awardNos.Length { // reset other's rank as 0 for (int i = newRank_length; i < matRanks.RowCount; i++) { matRanks[i, 1] = 0; } orgRank = SingleRank(matRanks, newRank_length, awardNos, awards); } } else if (rank_length < awardNos.Length) { orgRank = SplitRank(matRanks, rank_length, awardNos, awards); } return(orgRank); }