-
Notifications
You must be signed in to change notification settings - Fork 2
/
q2.py
137 lines (115 loc) · 5.31 KB
/
q2.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import random
import time
import math
import function as f
import numpy as np
import constance as c
from matplotlib import pyplot as plt
import pandas as pd
class sa_tsp:
# 接受的输入参数:起始温度start_temp, 结束温度end_temp, 内循环次数num
def __init__(self, s_t, e_t, num):
self.start_temp = s_t
self.end_temp = e_t
self.num = num
# 获取当前状态的功率密度
def get_power_density(self, state):
power, _ = self.get_power(state)
return power / (state[0] * state[1] * state[3])
# 获取当前状态的功率值和摆放的圈数
def get_power(self, state):
nums = f.get_nums(state[0], state[3], state[4])
S = state[0]*state[1]
x, y = f.get_xy(nums, state[4])
loss, t = f.new_get_shadow_loss(state[4], 4, 6, len(nums))
d_HR, eta_at = f.new_get_d_HR(state[2], len(nums), state[4])
effi_trunc = f.get_trunc_effi(8, 7, state[0], state[1], len(nums), d_HR)
effi_cos = f.get_effi_cos(t, len(nums))
light_effi = f.get_light_effi(loss, effi_cos, eta_at, effi_trunc, len(nums))
E_field = f.new_get_heat_W(light_effi, S, c.DNI, len(nums), loss, nums)
return np.mean(E_field), len(nums)
def get_power_and_print(self, state):
nums = f.get_nums(state[0], state[3], state[4])
S = state[0]*state[1]
x, y = f.get_xy(nums, state[4])
loss, t = f.new_get_shadow_loss(state[4], 4, 6, len(nums))
f.get_average_mni(loss, len(nums))
d_HR, eta_at = f.new_get_d_HR(state[2], len(nums), state[4])
effi_trunc = f.get_trunc_effi(8, 7, state[0], state[1], len(nums), d_HR)
print(np.mean(effi_trunc))
effi_cos = f.get_effi_cos(t, len(nums))
f.get_average_mni(effi_cos, len(nums))
light_effi = f.get_light_effi(loss, effi_cos, eta_at, effi_trunc, len(nums))
f.get_average_mni(light_effi, len(nums))
density = []
E_field = f.new_get_heat_W(light_effi, S, c.DNI, len(nums), loss, nums)
for i in range(12):
E = 0
for time in range(5):
E += E_field[i][time]
density.append(E/(36*len(x)*5))
print(density)
return np.mean(E_field), len(nums)
# 获取下一个状态
# 如果符合约束条件,则返回新状态,否则放回原状态
def get_next_state(self, state):
next_state = state.copy()
select = random.randint(0, 4) # 生成0到4之间的随机整数
flag = random.choice([-1, 1])
vary_list = [4, 4, 2, 100, 10]
vary_num = random.random()
next_state[select] = next_state[select] + flag * vary_list[select] * vary_num
next_state[3] = int(next_state[3]) # 数目只能是整数
power, num = self.get_power(next_state)
if self.is_valid(next_state, power, num):
return next_state
else:
return state
# 判断是否满足约束条件
def is_valid(self, state, power, num):
return 2 <= state[0] <= 8 and 2 <= state[1] <= 8 and 2 <= state[2] <= 6 and state[1] <= 2 * state[2] \
and state[0] >= state[1] and state[4] >= state[0] + 5 and power >= 60000 and 100 + (num-1) * state[4] <= 350
# 降温函数
def update_temp(self, temp, num):
# return self.start_temp / math.log(1+num)
return 0.9 * temp
# 模拟退火算法
def simulated_annealing(self, initial_state):
state = initial_state
best_power_density, best_state = self.get_power_density(initial_state), initial_state
cur_temp = self.start_temp
change_num = 0
# 外层循环,这里的终止条件采取的是设置温度的阈值
while cur_temp > self.end_temp:
# 内层循环,这里的终止条件采取的是设置内循环数目
loop_num = self.num
for i in range(loop_num):
new_state = self.get_next_state(state)
if state == new_state:
continue
initial_power_density, new_power_density = self.get_power_density(state), self.get_power_density(new_state)
delta = initial_power_density - new_power_density
rec_p = math.exp(-(delta / cur_temp))
if rec_p > random.uniform(0, 1):
state = new_state
# print("state:", state, "pd:", new_power_density)
# 判断是否更优
if new_power_density > best_power_density:
best_state = new_state
best_power_density = new_power_density
# print("temp:", cur_temp, ", best_power_density:", best_power_density, "state:", best_state)
# print("temp:", cur_temp, ", best_power_density:", best_power_density, "state:", best_state)
# 更新温度
cur_temp = self.update_temp(cur_temp, change_num)
return best_power_density, best_state
if __name__ == '__main__':
start_time = time.time()
initial_state = [5.5, 5.5, 4, 2900, 10.5]
# 模拟退火
test = sa_tsp(10, 0.1, 100)
best_power_density, best_state = test.simulated_annealing(initial_state)
end_time = time.time()
# print(best_power_density)
# print(best_state)
print(test.get_power_and_print(best_state))
print("time:", end_time-start_time, "s")