docs: def single_peaked_winners(self, profile, d=1, K=3, funcType='Borda', scoringVector=[]):
          """
          Returns a list that associates all the winners of a profile under The Chamberlin–Courant rule.
  
          :ivar Profile profile: A Profile object that represents an election profile.
          """
  
          # Currently, we expect the profile to contain complete ordering over candidates. Ties are
          # allowed however.
          elecType = profile.getElecType()
          if elecType != "soc" and elecType != "toc" and elecType != "csv":
              print("ERROR: unsupported election type")
              exit()
  
          # ------------------1. INITIALIZATION-----------------------------
          m = profile.numCands
          n = profile.numVoters
          cand = list(profile.candMap.keys())
          cand.append(cand[m - 1] + 1)
          theta = n - d
          if funcType == 'Borda':
              scoringVector = MechanismBorda().getScoringVector(profile)
          z = dict()
          for k in range(1, K + 2):  # k = 1,...,K + 1
              z[k] = dict()
              for j in range(1, m + 2):
                  z[k][j] = dict()
  
          for j in range(1, m + 2):
              for t in range(0, theta + 1):
                  z[1][j][t] = self.s(profile, 1, j, t, {cand[j - 1]}, scoringVector)
                  for k in range(1, K + 1):
                      z[k + 1][j][t] = float("-inf")
  
          # ------------------2. MAIN LOOP-----------------------------
          for k in range(1, K + 1):
              # Predecessors loop:
              for p in range(1, m + 1):
                  for u in range(0, theta + 1):
                      if z[k][p][u] != float("-inf"):
                          # Successors sub-loop:
                          for j in range(p + 1, m + 2):
                              for t in range(u, theta + 1):
                                  z[k + 1][j][t] = max(z[k + 1][j][t], z[k][p][u]
                                                       + self.s(profile, p + 1, j, t - u, {cand[p - 1], cand[j - 1]},
                                                                scoringVector))
  
          max_utility = z[K + 1][m + 1][theta]
          print("max_utility=", max_utility)
          # --------------------3. OUTPUT WINNERS---------------------------
          winners = []
          temp_max = max_utility
          j = m + 1
          t = theta
          for k in range(K + 1, 1, -1):
              z_k_j_t = array(
                  [[z[k - 1][p][u] + self.s(profile, p + 1, j, t - u, {cand[p - 1], cand[j - 1]}, scoringVector)
                    for u in range(0, theta + 1)] for p in range(1, m + 1)])
              p_ind = where(temp_max == z_k_j_t)[0][0]
              u_ind = where(temp_max == z_k_j_t)[0][0]
              p0 = list(range(1, m + 1))[p_ind]
              u0 = list(range(0, theta + 1))[u_ind]
              winners.append(p0)
              temp_max = z[k][p0][u0]
              j = p0
              t = u0
  
          return sorted(winners)