Description:
            Takes in a set of rankings and computes the
            Plackett-Luce model aggregate ranking.
        Parameters:
            rankings: set of rankings to aggregate
            breaking: type of breaking to use
            k:        number to be used for top, bottom, and position breakings

def aggregate(self, rankings, breaking="full", k=None):
        """
        Description:
            Takes in a set of rankings and computes the
            Plackett-Luce model aggregate ranking.
        Parameters:
            rankings: set of rankings to aggregate
            breaking: type of breaking to use
            k:        number to be used for top, bottom, and position breakings
        """

        breakings = { "full":     self._full,
                      "top":      self._top,
                      "bottom":   self._bot,
                      "adjacent": self._adj,
                      "position": self._pos }

        if (k == None and (breaking != "full" != breaking != "position")):
            raise ValueError("k cannot be None for non-full or non-position breaking")

        break_mat = breakings[breaking](k)
        P = np.zeros((self.m, self.m))
        for ranking in rankings:
            localP = np.zeros((self.m, self.m))
            for ind1, alt1 in enumerate(self.alts):
                for ind2, alt2 in enumerate(self.alts):
                    if ind1 == ind2:
                        continue
                    alt1_rank = util.get_index_nested(ranking, alt1)
                    alt2_rank = util.get_index_nested(ranking, alt2)
                    if alt1_rank < alt2_rank: # alt 1 is ranked higher
                        localP[ind1][ind2] = 1
            for ind, alt in enumerate(self.alts):
                localP[ind][ind] = -1*(np.sum(localP.T[ind][:ind]) +
                                       np.sum(localP.T[ind][ind+1:]))
            localP *= break_mat
            P += localP/len(rankings)
        #epsilon = 1e-7
        #assert(np.linalg.matrix_rank(P) == self.m-1)
        #assert(all(np.sum(P, axis=0) <= epsilon))
        U, S, V = np.linalg.svd(P)
        gamma = np.abs(V[-1])
        gamma /= np.sum(gamma)
        #assert(all(np.dot(P, gamma) < epsilon))
        alt_scores = {cand: gamma[ind] for ind, cand in enumerate(self.alts)}
        self.P = P
        self.create_rank_dicts(alt_scores)
        return gamma