docs: public static Cluster greedyShufflePartitions(final Cluster nextCandidateCluster,
                                                    final int greedyAttempts,
                                                    final int greedySwapMaxPartitionsPerNode,
                                                    final int greedySwapMaxPartitionsPerZone,
                                                    List<Integer> greedySwapZoneIds,
                                                    List<StoreDefinition> storeDefs) {
          List<Integer> zoneIds = null;
          if(greedySwapZoneIds.isEmpty()) {
              zoneIds = new ArrayList<Integer>(nextCandidateCluster.getZoneIds());
          } else {
              zoneIds = new ArrayList<Integer>(greedySwapZoneIds);
          }
  
          List<Integer> nodeIds = new ArrayList<Integer>();
          Cluster returnCluster = Cluster.cloneCluster(nextCandidateCluster);
          double currentUtility = new PartitionBalance(returnCluster, storeDefs).getUtility();
  
          for(int i = 0; i < greedyAttempts; i++) {
  
              // Iterate over zone ids to decide which node ids to include for
              // intra-zone swapping.
              // In future, if there is a need to support inter-zone swapping,
              // then just remove the
              // zone specific logic that populates nodeIdSet and add all nodes
              // from across all zones.
  
              int zoneIdOffset = i % zoneIds.size();
              Set<Integer> nodeIdSet = nextCandidateCluster.getNodeIdsInZone(zoneIds.get(zoneIdOffset));
              nodeIds = new ArrayList<Integer>(nodeIdSet);
  
              Collections.shuffle(zoneIds, new Random(System.currentTimeMillis()));
              Cluster shuffleResults = swapGreedyRandomPartitions(returnCluster,
                                                                  nodeIds,
                                                                  greedySwapMaxPartitionsPerNode,
                                                                  greedySwapMaxPartitionsPerZone,
                                                                  storeDefs);
  
              double nextUtility = new PartitionBalance(shuffleResults, storeDefs).getUtility();
              System.out.println("Swap improved max-min ratio: " + currentUtility + " -> "
                                 + nextUtility + " (swap attempt " + i + " in zone "
                                 + zoneIds.get(zoneIdOffset) + ")");
              returnCluster = shuffleResults;
              currentUtility = nextUtility;
          }
          return returnCluster;
      }