protected Solution makeHeuristicMove(
      Deadline deadline, Solution s, Random random, HeuristicStats heuristicStats) {
    Heuristic heuristic = heuristicStats.getHeuristic();
    long costBefore = s.getCost();
    long startTime = System.currentTimeMillis();
    s =
        heuristic.move(
            s,
            Deadline.min(new Deadline(heuristicMaxTimes[heuristicStats.getId()]), deadline),
            random);
    long timeDiff = System.currentTimeMillis() - startTime;
    long costDiff = costBefore - s.getCost();

    heuristicStats.saveUsage(timeDiff, costDiff);
    logger.info(
        String.format(
            "Heuristic # %d has improved the solution by %d (%f %%) in %d ms; its last performance = %f",
            heuristicStats.getId(),
            costDiff,
            (double) costDiff * 100 / costBefore,
            timeDiff,
            heuristicStats.getLastPerformance()));

    return s;
  }