示例#1
0
        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);
        }
示例#2
0
        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);
        }
示例#3
0
        /// <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);
        }
示例#4
0
        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);
        }