模拟退火算法
模拟退火算法流程图
- 初始温度 
  
- 新温度值 
    
- 进入循环 
      
- 生成新的解 
        
- 按照 bound
 - 按照 constraint
 
 - 计算新解与当前解的目标差异
 - 判断是否接受解
 - 判断是否更新解
 
 - 生成新的解 
        
 - 循环结束
 
 - 进入循环 
      
 - 按照温度降低率降低温度
 
 - 新温度值 
    
 - 温度小于最低温度
 - 输出结果
 
模拟退火算法示例代码1
import numpy as np
def objective_function(x):
    return x[0]**2 + 2*x[0] - 15 + 4*4*2*x[1] + 4*x[1]**2
def simulated_annealing(objective_func, initial_solution = np.array([0, 0]), \
                        temperature = 100, min_temperature = 0.1, \
                        cooling_rate = 0.90, iter_max = 100, seed = 0):
    np.random.seed(seed)
    current_solution = initial_solution
    best_solution = current_solution
    while temperature > min_temperature:
        for j in range(iter_max):
            # 生成新的解
            new_solution = current_solution + np.random.uniform(-1, 1, len(current_solution))
            
            # 计算新解与当前解之间的目标函数值差异
            current_cost = objective_func(current_solution)
            new_cost = objective_func(new_solution)
            cost_diff = new_cost - current_cost
            
            # 判断是否接受新解
            if cost_diff < 0 or np.exp(-cost_diff / temperature) > np.random.random():
                current_solution = new_solution
            
            # 更新最优解
            if objective_func(current_solution) < objective_func(best_solution):
                best_solution = current_solution
        
        # 降低温度
        temperature *= cooling_rate
    
    return best_solution
# 调用退火算法求解最小值
best_solution = simulated_annealing(objective_function)
print(f"函数最小值: {objective_function(best_solution)} 自变量取值:{best_solution}")
 
- 运行结果
 

模拟退火算法示例代码2
import numpy as np
global x_bound 
global x_up 
x_bound = 3
x_up = 10
def fun1(p0, p1):
    return (x_up**2 - x_bound**2)/3 - p0 - p1 
def fun2(p2):
    return p2 + (x_up**2 + x_bound**2 + x_bound**3)/3
def fun3(p2):
    return (x_up**2 * x_bound**2)*p2
   
def cons(try_solution):
    return 5 < np.sum(try_solution) < 10
    
def objective_function(params):
    return params[0]*fun1(params[0], params[1]) + fun2(params[2])*(params[1] + params[2]) - fun3(params[2])*(params[0] + params[2])
def simulated_annealing(objective_func, initial_solution = np.array([0, 0, 9]), \
                        temperature = 100, min_temperature = 0.1, \
                        cooling_rate = 0.90, iter_max = 100, seed = 0):
    np.random.seed(seed)
    current_solution = initial_solution
    best_solution = current_solution
    while temperature > min_temperature:
        for j in range(iter_max):
            # 生成新的解
            FLAG = True
            
            for k in range(iter_max):
                try_solution = current_solution + np.random.uniform(-1, 1, len(current_solution))
                if cons(try_solution):
                    new_solution = try_solution
                    FLAG = False
                    break
            if FLAG:
                print(f"找不到满足约束的解 在温度{temperature}")
                break
            
            # 计算新解与当前解之间的目标函数值差异
            current_cost = objective_func(current_solution)
            new_cost = objective_func(new_solution)
            cost_diff = new_cost - current_cost
            
            # 判断是否接受新解
            if cost_diff < 0 or np.exp(-cost_diff / temperature) > np.random.random():
                current_solution = new_solution
            
            # 更新最优解
            if objective_func(current_solution) < objective_func(best_solution):
                best_solution = current_solution
        
        # 降低温度
        temperature *= cooling_rate
    
    return best_solution
# 调用退火算法求解最小值
best_solution = simulated_annealing(objective_function)
print(f"函数最小值: {objective_function(best_solution)} 自变量取值:{best_solution}") 

模拟退火算法的可视化
import numpy as np
 import matplotlib.pyplot as plt
global x_bound 
 global x_up 
x_bound = 3
 x_up = 10
def fun1(p0, p1):
     return (x_up**2 - x_bound**2)/3 - p0 - p1 
def fun2(p0, p1):
     return p1 + (p0**2 + x_bound**(p1-p0))/3
   
 def cons(try_solution):
     return 5 < np.sum(try_solution) < 10
     
 def objective_function(params):
     return params[0]*fun1(params[0], params[1]) + (params[0] + params[1])*fun2(params[0], params[1])
def simulated_annealing(objective_func, initial_solution = np.array([4, 4]), \
                         temperature = 100, min_temperature = 0.1, \
                         cooling_rate = 0.90, iter_max = 100, seed = 0):
    np.random.seed(seed)
     current_solution = initial_solution
     best_solution = current_solution
     RECODE_temp,RECODE_sol = [],[]
     raw_temperature = temperature
     
     while temperature > min_temperature:
         RECODE_temp.append(temperature)
         for j in range(iter_max):
             # 生成新的解
             FLAG = True
             
             for k in range(iter_max):
                 try_solution = current_solution + np.random.uniform(-1, 1, len(current_solution))
                 if cons(try_solution):
                     new_solution = try_solution
                     FLAG = False
                     break
             if FLAG:
                 print(f"找不到满足约束的解 在温度{temperature}")
                 break
             
             # 计算新解与当前解之间的目标函数值差异
             current_cost = objective_func(current_solution)
             new_cost = objective_func(new_solution)
             cost_diff = new_cost - current_cost
             
             # 判断是否接受新解
             if cost_diff < 0 or np.exp(-cost_diff / temperature) > np.random.random():
                 current_solution = new_solution
             
             # 更新最优解
             if objective_func(current_solution) < objective_func(best_solution):
                 best_solution = current_solution
         
         # 降低温度
         temperature *= cooling_rate
         RECODE_sol.append(best_solution)
    RECODE_temp = [raw_temperature - i for i in RECODE_temp]
     RECODE_sol = [objective_function(i) for i in RECODE_sol] 
     plt.plot(RECODE_temp, RECODE_sol)
     plt.title("sol-temp")
     plt.xlabel("temp count")
     plt.ylabel("sol")
     plt.pause(0.01)
     return best_solution
# 调用退火算法求解最小值
 best_solution = simulated_annealing(objective_function)
print(f"函数最小值: {objective_function(best_solution)} 自变量取值:{best_solution}")
  

example 2sin(x)+cos(x)
import numpy as np
import matplotlib.pyplot as plt
def objective_function(params):
    return 2*np.sin(params[0]) + np.cos(params[0])
def cons(try_solution):
    return True
def simulated_annealing(objective_func, initial_solution = np.array([4, ]), \
                        temperature = 100, min_temperature = 0.1, \
                        cooling_rate = 0.90, iter_max = 100, seed = 0):
    np.random.seed(seed)
    current_solution = initial_solution
    best_solution = current_solution
    RECODE_temp,RECODE_sol = [],[]
    raw_temperature = temperature
    
    while temperature > min_temperature:
        RECODE_temp.append(temperature)
        for j in range(iter_max):
            # 生成新的解
            FLAG = True
            
            for k in range(iter_max):
                try_solution = current_solution + np.random.uniform(-1, 1, len(current_solution))
                if cons(try_solution):
                    new_solution = try_solution
                    FLAG = False
                    break
            if FLAG:
                print(f"找不到满足约束的解 在温度{temperature}")
                break
            
            # 计算新解与当前解之间的目标函数值差异
            current_cost = objective_func(current_solution)
            new_cost = objective_func(new_solution)
            cost_diff = new_cost - current_cost
            
            # 判断是否接受新解
            if cost_diff < 0 or np.exp(-cost_diff / temperature) > np.random.random():
                current_solution = new_solution
            
            # 更新最优解
            if objective_func(current_solution) < objective_func(best_solution):
                best_solution = current_solution
        
        # 降低温度
        temperature *= cooling_rate
        RECODE_sol.append(best_solution)
    RECODE_temp = [raw_temperature - i for i in RECODE_temp]
    RECODE_sol = [objective_function(i) for i in RECODE_sol] 
    plt.plot(RECODE_temp, RECODE_sol)
    plt.title("sol-temp")
    plt.xlabel("temp count")
    plt.ylabel("sol")
    plt.pause(0.01)
    return best_solution
# 调用退火算法求解最小值
best_solution = simulated_annealing(objective_function)
print(f"函数最小值: {objective_function(best_solution)} 自变量取值:{best_solution}")
 

 



















