code: @Override
      public SubsetMove getRandomMove(SubsetSolution solution, Random rnd) {
          // get set of candidate IDs for removal and addition (possibly fixed IDs are discarded)
          Set<Integer> removeCandidates = getRemoveCandidates(solution);
          Set<Integer> addCandidates = getAddCandidates(solution);
          // check if swap is possible
          if(removeCandidates.isEmpty() || addCandidates.isEmpty()){
              // impossible to perform a swap
              return null;
          }
          // select random ID to remove from selection
          int del = SetUtilities.getRandomElement(removeCandidates, rnd);
          // select random ID to add to selection
          int add = SetUtilities.getRandomElement(addCandidates, rnd);
          // create and return swap move
          return new SwapMove(add, del);
      }
docs: Generates a random swap move for the given subset solution that removes a single ID from the set of currently selected IDs,
  and replaces it with a random ID taken from the set of currently unselected IDs. Possible fixed IDs are not considered to be
  swapped. If no swap move can be generated, <code>null</code> is returned.
  
  @param solution solution for which a random swap move is generated
  @param rnd source of randomness used to generate random move
  @return random swap move, <code>null</code> if no swap move can be generated