def adjust_threshold(threshold: float,
                     flag_imp: bool,
                     flag_explore: bool,
                     n_accepted: int,
                     n_improved: int,
                     num_exchanges: int,
                     improving_params: list,
                     exploring_params: list) -> tuple:
    """Calculate the new threshold based on the results of previous iteration

    :param threshold: the current threshold
    :param flag_imp: the flag indicating whether new best solution was found
    :param flag_explore: the flag indicating whether in exploration mode
    :param n_accepted: the number of accepted solution in the previous iteration
    :param n_improved: the number of new best solution found in previous iter.
    :param num_exchanges: the number of candidates considered from curr. design
    :param improving_params: The 2 parameters used in improving process phase
        (1) the cut-off value to decrease the threshold
        (2) the multiplier to decrease or increase the threshold
    :param exploring_params: The 4 parameters used in exploring process phase
        (1) the cut-off value of acceptance to start increasing the threshold
        (2) the cut-off value of acceptance to start decreasing the threshold
        (3) the cooling multiplier for the threshold
        (4) the warming multiplier for the threshold
    :return: tuple of the update flag_explore (whether still in explore mode)
        and the adjusted threshold
    """
    # Improve vs. Explore Phase and Threshold Update
    if flag_imp:    # Improve
        # New best solution found, carry out improvement process
        if (float(n_accepted/num_exchanges) > improving_params[0]) & \
                (n_accepted > n_improved):
            # Lots acceptance but not all of them is improvement,
            # reduce threshold, make it harder to accept a trial
            threshold *= improving_params[1]
        else:
            # Few acceptance or all trials are improvement, increase threshold
            # make it easier to accept a trial
            threshold /= improving_params[1]

    else:           # Explore, No new best solution found during last iteration
        # Exploring process, warming up vs. cooling down
        if n_accepted < exploring_params[0] * num_exchanges:
            # Reach below limit, increase threshold ("warming up")
            flag_explore = True
        elif n_accepted > exploring_params[1] * num_exchanges:
            # Reach above limit, decrease threshold ("cooling down")
            flag_explore = False

        if flag_explore:
            # Ramp up exploration and below upper limit, increase threshold
            threshold /= exploring_params[3]
        elif not flag_explore:
            # Slow down exploration and above lower limit, decrease threshold
            threshold *= exploring_params[2]

    return flag_explore, threshold