-
Notifications
You must be signed in to change notification settings - Fork 0
/
local-search.xml
370 lines (175 loc) · 397 KB
/
local-search.xml
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title>23年数学建模国赛B题</title>
<link href="/2024/10/01/PDF_math/"/>
<url>/2024/10/01/PDF_math/</url>
<content type="html"><![CDATA[<!--<div class="row"> <embed src="./math_struct.pdf" width="100%" height="550" type="application/pdf"></div>--><p>手机端无法查看,可尝试浏览器爬虫功能,建议电脑端查看。<br><embed src="./math_struct.pdf" width="100%" height="750" type="application/pdf"></p>]]></content>
<categories>
<category>数学建模</category>
</categories>
</entry>
<entry>
<title>SARIMA预测代码</title>
<link href="/2024/09/11/SARIMA%E9%A2%84%E6%B5%8B/"/>
<url>/2024/09/11/SARIMA%E9%A2%84%E6%B5%8B/</url>
<content type="html"><![CDATA[<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">import</span> copy<br><span class="hljs-keyword">from</span> math <span class="hljs-keyword">import</span> log<br><span class="hljs-keyword">import</span> numpy <span class="hljs-keyword">as</span> np<br><span class="hljs-keyword">import</span> pandas <span class="hljs-keyword">as</span> pd<br><span class="hljs-keyword">import</span> matplotlib.pyplot <span class="hljs-keyword">as</span> plt<br><span class="hljs-keyword">from</span> sklearn.metrics <span class="hljs-keyword">import</span> mean_squared_error<br>np.set_printoptions(threshold=np.inf) <span class="hljs-comment"># threshold 指定超过多少使用省略号,np.inf代表无限大</span><br>np.set_printoptions(suppress=<span class="hljs-literal">True</span>) <span class="hljs-comment">#不以科学计数法输出</span><br><span class="hljs-keyword">import</span> warnings<br>warnings.filterwarnings(<span class="hljs-string">"ignore"</span>)<br>plt.rcParams[<span class="hljs-string">'axes.unicode_minus'</span>] = <span class="hljs-literal">False</span> <span class="hljs-comment">#显示负号</span><br>plt.rcParams[<span class="hljs-string">'font.family'</span>] = [<span class="hljs-string">'sans-serif'</span>]<br>plt.rcParams[<span class="hljs-string">'font.sans-serif'</span>] = [<span class="hljs-string">'SimHei'</span>] <span class="hljs-comment"># 散点图标签可以显示中文</span><br><br><br><span class="hljs-comment">##################################### 信息准则 ###########################################</span><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">information</span>(<span class="hljs-params">df,df0,p</span>):<br> n = <span class="hljs-built_in">len</span>(df)<br> mse = mean_squared_error(df,df0)<br> <span class="hljs-comment">#aic = n * log(mse) + 2 * p</span><br> aicc = log(mse) + (n+p)/(n-p-<span class="hljs-number">2</span>)<br> bic = n * log(mse) + p * log(n)<br> <span class="hljs-keyword">return</span> aicc,bic<br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">AR_prediction</span>(<span class="hljs-params">x, p, predict_x_n = <span class="hljs-number">0</span></span>):<br> df = np.array(x).ravel() <span class="hljs-comment">#将数据转化为numpy格式,并将其转化为一维列表</span><br> df0 = df.copy() <span class="hljs-comment">#准备一个副本,为了存储预测的数据</span><br> Y = df[p:].copy()<br> h = <span class="hljs-built_in">len</span>(df0)-p<br> X = np.zeros((h,p))<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(h): <span class="hljs-comment">#得到X矩阵</span><br> <span class="hljs-keyword">for</span> v <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">1</span>,p+<span class="hljs-number">1</span>):<br> X[i,-v] = df[i+v-<span class="hljs-number">1</span>]<br> sigma = np.linalg.inv(X.T.dot(X)).dot(X.T).dot(Y.T) <span class="hljs-comment">#最小二乘法估计参数值</span><br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(h):<br> df0[p+i] = <span class="hljs-built_in">sum</span>(np.multiply(sigma , X[i])) <span class="hljs-comment">#得到所有预测的估计值</span><br> df00 = df.copy()<br> df1 = np.zeros(predict_x_n)<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(predict_x_n):<br> df1[i] = <span class="hljs-built_in">sum</span>(np.multiply(sigma , df00[-p:][::-<span class="hljs-number">1</span>])) <span class="hljs-comment">#得到所有预测值</span><br> df00 = np.append(df00,df1[i])<br> <span class="hljs-keyword">return</span> df0,df1,sigma<br><span class="hljs-keyword">def</span> <span class="hljs-title function_">SAR</span>(<span class="hljs-params">x,p,s,predict_x_n=<span class="hljs-number">0</span></span>):<br> x = np.array(x).ravel()<br> df0 = x.copy()<br> Y = x[s*p:].copy()<br> h = <span class="hljs-built_in">len</span>(x) - p*s<br> X = np.zeros((h,p))<br> <span class="hljs-keyword">for</span> t <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(h):<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">1</span>,p+<span class="hljs-number">1</span>):<br> X[t][-i] = x[p*s+t-i*s]<br> sigma = np.linalg.inv(X.T.dot(X)).dot(X.T).dot(Y.T) <span class="hljs-comment">#最小二乘法估计参数值</span><br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(h):<br> df0[p*s+i] = <span class="hljs-built_in">sum</span>(sigma * X[i]) <span class="hljs-comment">#得到所有预测的估计值</span><br> df00 = x.copy()<br> df1 = np.zeros(predict_x_n)<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(predict_x_n):<br> df1[i] = <span class="hljs-built_in">sum</span>(np.multiply(sigma , df00[-p:][::-<span class="hljs-number">1</span>])) <span class="hljs-comment">#得到所有预测值</span><br> df00 = np.append(df00,df1[i])<br> <span class="hljs-keyword">return</span> df0,df1,sigma<br><br><span class="hljs-comment">######################################### 阶数确定 ##############################################</span><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">p_finally</span>(<span class="hljs-params">n</span>):<br> jieguo = []<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">1</span>,n):<br> df0,df1 = AR_prediction(data,i)<br> aicc,bic = information(data,df0,i)<br> jieguo.append([i,aicc,bic])<br> jieguo_aicc = <span class="hljs-built_in">sorted</span>(jieguo,reverse=<span class="hljs-literal">False</span>, key=<span class="hljs-keyword">lambda</span> x: x[<span class="hljs-number">1</span>]) <span class="hljs-comment">#以aicc排序</span><br> jieguo_bic = <span class="hljs-built_in">sorted</span>(jieguo,reverse=<span class="hljs-literal">False</span>, key=<span class="hljs-keyword">lambda</span> x: x[<span class="hljs-number">2</span>]) <span class="hljs-comment">#以bic排序</span><br> <span class="hljs-keyword">return</span> jieguo_aicc[<span class="hljs-number">0</span>][<span class="hljs-number">0</span>],jieguo_bic[<span class="hljs-number">0</span>][<span class="hljs-number">0</span>]<br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">MA_prediction</span>(<span class="hljs-params">data, q, predict_x_n=<span class="hljs-number">0</span></span>):<br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">sma</span>(<span class="hljs-params">x</span>):<br> <span class="hljs-keyword">return</span> np.mean(x) <span class="hljs-comment">#简单移动平均</span><br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">wma</span>(<span class="hljs-params">x</span>):<br> x = np.array(x).ravel()<br> w = np.arange(<span class="hljs-number">1</span>,<span class="hljs-built_in">len</span>(x)+<span class="hljs-number">1</span>) <span class="hljs-comment">#生成等差数列</span><br> <span class="hljs-keyword">return</span> np.<span class="hljs-built_in">sum</span>(x*w)/(<span class="hljs-built_in">len</span>(x)*(<span class="hljs-built_in">len</span>(x)+<span class="hljs-number">1</span>)/<span class="hljs-number">2</span>) <span class="hljs-comment">#加权移动平均(等距)</span><br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">ema</span>(<span class="hljs-params">x,i</span>):<br> x = np.array(x).ravel()<br> <span class="hljs-keyword">if</span> i < <span class="hljs-number">1</span> <span class="hljs-keyword">and</span> i > <span class="hljs-number">0</span>:<br> l = <span class="hljs-built_in">len</span>(x)<br> w = np.logspace(l, <span class="hljs-number">0</span>, num=l, base=(<span class="hljs-number">1</span>-i)) <span class="hljs-comment">#生成等比数列</span><br> <span class="hljs-keyword">else</span>:<br> <span class="hljs-built_in">print</span>(<span class="hljs-string">'平滑因子范围错误'</span>)<br> <span class="hljs-keyword">return</span> np.<span class="hljs-built_in">sum</span>(x*w)/np.<span class="hljs-built_in">sum</span>(w) <span class="hljs-comment">#指数移动平均</span><br> <span class="hljs-comment">########################## 移动平均预测 ################################</span><br> df = np.array(data).ravel() <span class="hljs-comment">#将数据转化为numpy格式,并将其转化为一维列表</span><br> df0 = df.copy() <span class="hljs-comment">#准备一个副本,存储真实值以及预测值</span><br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-built_in">len</span>(df0)-q+<span class="hljs-number">1</span>):<br> df[q+i-<span class="hljs-number">1</span>] = ema(df0[i:i+q],<span class="hljs-number">0.5</span>) <span class="hljs-comment">#获得简单移动平均获得的预测数列</span><br><br> df_wu = df0 - df <span class="hljs-comment">#获得误差项</span><br><br> df1 = np.zeros(predict_x_n) <span class="hljs-comment">#存储预测值</span><br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(predict_x_n):<br> df1[i] = ema(df0[-q:],<span class="hljs-number">0.5</span>) <span class="hljs-comment">#得到所有预测值</span><br> df0 = np.append(df0,df1[i])<br> <span class="hljs-comment">############################## 误差项预测 ###############################</span><br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">MA_AR_prediction</span>(<span class="hljs-params">x, p, predict_x_n = <span class="hljs-number">0</span></span>): <span class="hljs-comment">#误差项预测实际就为AR预测,这也是为什么MA模型阶数为0时就转化成AR模型的原因</span><br> df = np.array(x[p:]).ravel() <span class="hljs-comment">#将数据转化为numpy格式,并将其转化为一维列表</span><br> df0 = df.copy() <span class="hljs-comment">#准备一个副本,为了存储预测的数据</span><br> Y = df[p:].copy()<br> h = <span class="hljs-built_in">len</span>(df0)-p<br> X = np.zeros((h,p))<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(h): <span class="hljs-comment">#得到X矩阵</span><br> <span class="hljs-keyword">for</span> v <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">1</span>,p+<span class="hljs-number">1</span>):<br> X[i,-v] = df[i+v-<span class="hljs-number">1</span>]<br> sigma = np.linalg.inv(X.T.dot(X)).dot(X.T).dot(Y.T) <span class="hljs-comment">#最小二乘法估计参数值</span><br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(h):<br> df0[p+i] = <span class="hljs-built_in">sum</span>(np.multiply(sigma , X[i])) <span class="hljs-comment">#得到所有预测的估计值</span><br> df00 = df.copy()<br> df1 = np.zeros(predict_x_n)<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(predict_x_n):<br> df1[i] = <span class="hljs-built_in">sum</span>(np.multiply(sigma , df00[-p:][::-<span class="hljs-number">1</span>])) <span class="hljs-comment">#得到所有预测值</span><br> df00 = np.append(df00,df1[i])<br> <span class="hljs-keyword">return</span> df0,df1,sigma<br> wucha,wucha_predict,sigma = MA_AR_prediction(df_wu,q,predict_x_n)<br> <span class="hljs-keyword">return</span> wucha,wucha_predict,sigma,df_wu<br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">SMA</span>(<span class="hljs-params">data,q,s,predict_x_n=<span class="hljs-number">0</span></span>):<br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">sma</span>(<span class="hljs-params">x</span>):<br> <span class="hljs-keyword">return</span> np.mean(x) <span class="hljs-comment">#简单移动平均</span><br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">wma</span>(<span class="hljs-params">x</span>):<br> x = np.array(x).ravel()<br> w = np.arange(<span class="hljs-number">1</span>,<span class="hljs-built_in">len</span>(x)+<span class="hljs-number">1</span>) <span class="hljs-comment">#生成等差数列</span><br> <span class="hljs-keyword">return</span> np.<span class="hljs-built_in">sum</span>(x*w)/(<span class="hljs-built_in">len</span>(x)*(<span class="hljs-built_in">len</span>(x)+<span class="hljs-number">1</span>)/<span class="hljs-number">2</span>) <span class="hljs-comment">#加权移动平均(等距)</span><br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">ema</span>(<span class="hljs-params">x,i</span>):<br> x = np.array(x).ravel()<br> <span class="hljs-keyword">if</span> i < <span class="hljs-number">1</span> <span class="hljs-keyword">and</span> i > <span class="hljs-number">0</span>:<br> l = <span class="hljs-built_in">len</span>(x)<br> w = np.logspace(l, <span class="hljs-number">0</span>, num=l, base=(<span class="hljs-number">1</span>-i)) <span class="hljs-comment">#生成等比数列</span><br> <span class="hljs-keyword">else</span>:<br> <span class="hljs-built_in">print</span>(<span class="hljs-string">'平滑因子范围错误'</span>)<br> <span class="hljs-keyword">return</span> np.<span class="hljs-built_in">sum</span>(x*w)/np.<span class="hljs-built_in">sum</span>(w) <span class="hljs-comment">#指数移动平均</span><br> <span class="hljs-comment">########################## 移动平均预测 ################################</span><br> df = np.array(data).ravel() <span class="hljs-comment">#将数据转化为numpy格式,并将其转化为一维列表</span><br> df0 = df.copy() <span class="hljs-comment">#准备一个副本,存储真实值以及预测值</span><br> h = <span class="hljs-built_in">len</span>(data) - q*s<br> X = np.zeros((h,q))<br> <span class="hljs-keyword">for</span> t <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(h):<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">1</span>,q+<span class="hljs-number">1</span>):<br> X[t][-i] = df[q*s+t-i*s]<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(h):<br> df[q*s+i] = ema(X[i],<span class="hljs-number">0.5</span>) <span class="hljs-comment">#获得简单移动平均获得的预测数列</span><br><br> df_wu = df0 - df <span class="hljs-comment">#获得误差项</span><br><br> df1 = np.zeros(predict_x_n) <span class="hljs-comment">#存储预测值</span><br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(predict_x_n):<br> df1[i] = ema(df0[-q:],<span class="hljs-number">0.5</span>) <span class="hljs-comment">#得到所有预测值</span><br> df0 = np.append(df0,df1[i])<br> <span class="hljs-comment">############################## 误差项预测 ###############################</span><br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">SAR</span>(<span class="hljs-params">x,p,s,predict_x_n=<span class="hljs-number">0</span></span>):<br> x = np.array(x[p*s:]).ravel()<br> df0 = x.copy()<br> Y = x[s*p:].copy()<br> h = <span class="hljs-built_in">len</span>(x) - p*s<br> X = np.zeros((h,p))<br> <span class="hljs-keyword">for</span> t <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(h):<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">1</span>,p+<span class="hljs-number">1</span>):<br> X[t][-i] = x[p*s+t-i*s]<br> sigma = np.linalg.inv(X.T.dot(X)).dot(X.T).dot(Y.T) <span class="hljs-comment">#最小二乘法估计参数值</span><br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(h):<br> df0[p*s+i] = <span class="hljs-built_in">sum</span>(np.multiply(sigma , X[i])) <span class="hljs-comment">#得到所有预测的估计值</span><br> df00 = x.copy()<br> df1 = np.zeros(predict_x_n)<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(predict_x_n):<br> df1[i] = <span class="hljs-built_in">sum</span>(np.multiply(sigma , df00[-p:][::-<span class="hljs-number">1</span>])) <span class="hljs-comment">#得到所有预测值</span><br> df00 = np.append(df00,df1[i])<br> <span class="hljs-keyword">return</span> df0,df1,sigma<br> wucha,wucha_predict,sigma = SAR(df_wu,q,s,predict_x_n)<br> <span class="hljs-keyword">return</span> wucha,wucha_predict,sigma<br><span class="hljs-keyword">def</span> <span class="hljs-title function_">SARIMA</span>(<span class="hljs-params">p,q,P,Q,data,m</span>):<br> <span class="hljs-comment">#p_aicc,p_bic = p_finally(10)</span><br> df0,df1,sigma = AR_prediction(data,p,<span class="hljs-number">0</span>)<br> wucha,wucha_predict,sigma1,df_wu = MA_prediction(data, q, <span class="hljs-number">0</span>)<br> a,b,sigma2 = SAR(data,P,m,<span class="hljs-number">0</span>)<br> c,d,sigma3 = SMA(data,Q,m,<span class="hljs-number">0</span>)<br> sigma = sigma[::-<span class="hljs-number">1</span>]<br> sigma1 = sigma1[::-<span class="hljs-number">1</span>]<br> sigma2 = sigma2[::-<span class="hljs-number">1</span>]<br> sigma3 = sigma3[::-<span class="hljs-number">1</span>]<br> sigma22 = np.append(np.array([<span class="hljs-number">1</span>]),sigma2)<br> sigma33 = np.append(np.array([<span class="hljs-number">1</span>]),sigma3)<br> result = []<br> <span class="hljs-keyword">for</span> t <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">30</span>,<span class="hljs-built_in">len</span>(data)+<span class="hljs-number">1</span>):<br> sar = <span class="hljs-number">0</span><br> <span class="hljs-keyword">for</span> p <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(p):<br> <span class="hljs-keyword">for</span> P <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(P+<span class="hljs-number">1</span>):<br> sar += sigma[p] * data[t-p-<span class="hljs-number">1</span>-P*m] * sigma22[P]<br> sar += <span class="hljs-built_in">sum</span>(sigma2 * np.array([data[t-i*m] <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">1</span>,P+<span class="hljs-number">1</span>)]))<br> sma = <span class="hljs-number">0</span><br> <span class="hljs-keyword">for</span> q <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(q):<br> <span class="hljs-keyword">for</span> Q <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(Q+<span class="hljs-number">1</span>):<br> sma += sigma1[q] * df_wu[t-q-<span class="hljs-number">1</span>-Q*m] * sigma33[Q]<br> sma += <span class="hljs-built_in">sum</span>(sigma3 * np.array([df_wu[t-i*m] <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">1</span>,Q+<span class="hljs-number">1</span>)]))<br> result.append(sar + sma)<br> <span class="hljs-keyword">return</span> result<br><br><br>data0 = pd.read_csv(<span class="hljs-string">'时间序列预测数据集.csv'</span>,parse_dates=[<span class="hljs-string">'Date'</span>])<br>data0.set_index(<span class="hljs-string">'Date'</span>,inplace=<span class="hljs-literal">True</span>) <span class="hljs-comment">#将时间设置为行索引</span><br>data=np.array(copy.deepcopy(data0)).ravel()<br><span class="hljs-comment">#data = data.reshape((10,365)) #季节性差分</span><br><span class="hljs-comment">#data=np.diff(data,1)</span><br><span class="hljs-comment">#data = data.ravel()</span><br>result = SARIMA(<span class="hljs-number">6</span>,<span class="hljs-number">7</span>,<span class="hljs-number">2</span>,<span class="hljs-number">2</span>,data,<span class="hljs-number">365</span>)<br>plt.figure(figsize=(<span class="hljs-number">15</span>, <span class="hljs-number">7.5</span>))<br>plt.plot(<span class="hljs-built_in">range</span>(<span class="hljs-number">500</span>),data[-<span class="hljs-number">500</span>:],c = <span class="hljs-string">'black'</span>,label=<span class="hljs-string">'actual'</span>)<br>plt.plot(<span class="hljs-built_in">range</span>(<span class="hljs-number">500</span>),result[-<span class="hljs-number">500</span>:],c=<span class="hljs-string">'red'</span>,label=<span class="hljs-string">'model'</span>)<br>plt.show()<br><br><span class="hljs-built_in">print</span>(<span class="hljs-string">'mse:'</span>,mean_squared_error(result,data[-<span class="hljs-built_in">len</span>(result):]))<br><br></code></pre></td></tr></table></figure>]]></content>
<categories>
<category>数学建模</category>
</categories>
</entry>
<entry>
<title>ARIMA预测代码</title>
<link href="/2024/09/11/ARIMA%E9%A2%84%E6%B5%8B/"/>
<url>/2024/09/11/ARIMA%E9%A2%84%E6%B5%8B/</url>
<content type="html"><![CDATA[<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">import</span> copy<br><span class="hljs-keyword">import</span> pandas <span class="hljs-keyword">as</span> pd<br><span class="hljs-keyword">import</span> numpy <span class="hljs-keyword">as</span> np<br><span class="hljs-keyword">import</span> matplotlib.pyplot <span class="hljs-keyword">as</span> plt<br><span class="hljs-keyword">import</span> statsmodels.api <span class="hljs-keyword">as</span> sm<br><span class="hljs-keyword">from</span> statsmodels.stats.diagnostic <span class="hljs-keyword">import</span> acorr_ljungbox<br><span class="hljs-keyword">from</span> statsmodels.graphics.tsaplots <span class="hljs-keyword">import</span> plot_pacf,plot_acf<br><span class="hljs-keyword">import</span> warnings<br><span class="hljs-keyword">from</span> math <span class="hljs-keyword">import</span> log<br><span class="hljs-keyword">from</span> sklearn.metrics <span class="hljs-keyword">import</span> mean_squared_error<br>warnings.filterwarnings(<span class="hljs-string">"ignore"</span>)<br>plt.rcParams[<span class="hljs-string">'axes.unicode_minus'</span>] = <span class="hljs-literal">False</span> <span class="hljs-comment">#显示负号</span><br>plt.rcParams[<span class="hljs-string">'font.family'</span>] = [<span class="hljs-string">'sans-serif'</span>]<br>plt.rcParams[<span class="hljs-string">'font.sans-serif'</span>] = [<span class="hljs-string">'SimHei'</span>] <span class="hljs-comment"># 散点图标签可以显示中文</span><br><br>data = pd.read_csv(<span class="hljs-string">'时间序列预测数据集.csv'</span>,parse_dates=[<span class="hljs-string">'Date'</span>])<br>data.set_index(<span class="hljs-string">'Date'</span>,inplace=<span class="hljs-literal">True</span>) <span class="hljs-comment">#将时间设置为行索引</span><br><br><span class="hljs-comment">#################################### 绘制时序图 ############################################</span><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">picture</span>(<span class="hljs-params">data</span>):<br> plt.figure(figsize=(<span class="hljs-number">16</span>,<span class="hljs-number">16</span>))<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">1</span>,<span class="hljs-number">5</span>):<br> plt.subplot(<span class="hljs-number">4</span>,<span class="hljs-number">1</span>,i)<br> df = data[<span class="hljs-string">f"198<span class="hljs-subst">{<span class="hljs-number">1</span>+<span class="hljs-number">2</span>*(i-<span class="hljs-number">1</span>)}</span>-01-01"</span>:<span class="hljs-string">f"198<span class="hljs-subst">{<span class="hljs-number">3</span>+<span class="hljs-number">2</span>*(i-<span class="hljs-number">1</span>)}</span>-01-01"</span>]<br> plt.plot(df.index,df[<span class="hljs-string">'Temp'</span>].values)<br> plt.xticks(rotation=<span class="hljs-number">45</span>,size=<span class="hljs-number">6</span>)<br> <span class="hljs-keyword">if</span> i == <span class="hljs-number">1</span>:<br> plt.title(<span class="hljs-string">"时序图"</span>)<br> plt.show()<br> plt.close()<br><span class="hljs-comment">###################################### 时间序列检验 #######################################</span><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">inspect</span>(<span class="hljs-params">data</span>):<br> <span class="hljs-comment"># 单位根检验-ADF检验</span><br> ADF = sm.tsa.stattools.adfuller(data[<span class="hljs-string">'Temp'</span>])<br> <span class="hljs-built_in">print</span>(<span class="hljs-string">'ADF值:'</span>, <span class="hljs-built_in">format</span>(ADF[<span class="hljs-number">0</span>], <span class="hljs-string">'.4f'</span>))<br> <span class="hljs-built_in">print</span>(<span class="hljs-string">'拒绝程度值:'</span>, ADF[<span class="hljs-number">4</span>]) <span class="hljs-comment">#ADF值需要小于三个拒绝程度值</span><br><br> <span class="hljs-comment"># 白噪声检验</span><br> white_noise = acorr_ljungbox(data[<span class="hljs-string">'Temp'</span>], lags = [<span class="hljs-number">6</span>, <span class="hljs-number">12</span>, <span class="hljs-number">24</span>],boxpierce=<span class="hljs-literal">True</span>) <span class="hljs-comment">#lag是需要检验的阶数</span><br> <span class="hljs-built_in">print</span>(<span class="hljs-string">'白噪声检验:\n'</span>,white_noise) <span class="hljs-comment">#LB和BP统计量的P值都小于显著水平(α = 0.05),所以拒绝序列为纯随机序列的原假设,认为该序列为非白噪声序列</span><br><br> fig = plt.figure(figsize=(<span class="hljs-number">16</span>,<span class="hljs-number">6</span>))<br><br> ax1 = fig.add_subplot(<span class="hljs-number">1</span>,<span class="hljs-number">2</span>,<span class="hljs-number">1</span>)<br> plot_acf(data[<span class="hljs-string">'Temp'</span>],ax=ax1)<br> plt.title(<span class="hljs-string">"自相关图"</span>) <span class="hljs-comment">#需要拖尾</span><br><br> ax2 = fig.add_subplot(<span class="hljs-number">1</span>,<span class="hljs-number">2</span>,<span class="hljs-number">2</span>)<br> plot_pacf(data[<span class="hljs-string">'Temp'</span>],ax=ax2)<br> plt.title(<span class="hljs-string">"偏自相关图"</span>) <span class="hljs-comment">#需要截尾,确定p</span><br><br> plt.show()<br> plt.close()<br><span class="hljs-comment">##################################### 信息准则 ###########################################</span><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">information</span>(<span class="hljs-params">df,df0,p</span>):<br> n = <span class="hljs-built_in">len</span>(df)<br> mse = mean_squared_error(df,df0)<br> <span class="hljs-comment">#aic = n * log(mse) + 2 * p</span><br> aicc = log(mse) + (n+p)/(n-p-<span class="hljs-number">2</span>)<br> bic = n * log(mse) + p * log(n)<br> <span class="hljs-keyword">return</span> aicc,bic<br><span class="hljs-keyword">def</span> <span class="hljs-title function_">AR_prediction</span>(<span class="hljs-params">x, p, predict_x_n = <span class="hljs-number">0</span></span>):<br> df = np.array(x).ravel() <span class="hljs-comment">#将数据转化为numpy格式,并将其转化为一维列表</span><br> df0 = df.copy() <span class="hljs-comment">#准备一个副本,为了存储预测的数据</span><br> Y = df[p:].copy()<br> h = <span class="hljs-built_in">len</span>(df0)-p<br> X = np.zeros((h,p+<span class="hljs-number">1</span>))<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(h): <span class="hljs-comment">#得到X矩阵</span><br> X[i][<span class="hljs-number">0</span>] = <span class="hljs-number">1</span><br> <span class="hljs-keyword">for</span> v <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">1</span>,p+<span class="hljs-number">1</span>):<br> X[i,-v] = df[i+v-<span class="hljs-number">1</span>]<br> sigma = np.linalg.inv(X.T.dot(X)).dot(X.T).dot(Y.T) <span class="hljs-comment">#最小二乘法估计参数值</span><br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(h):<br> df0[p+i] = <span class="hljs-built_in">sum</span>(sigma * X[i]) <span class="hljs-comment">#得到所有预测的估计值</span><br> df00 = df.copy()<br> df1 = np.zeros(predict_x_n)<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(predict_x_n):<br> df1[i] = <span class="hljs-built_in">sum</span>(sigma[<span class="hljs-number">1</span>:] * df00[-p:][::-<span class="hljs-number">1</span>])+sigma[<span class="hljs-number">0</span>] <span class="hljs-comment">#得到所有预测值</span><br> df00 = np.append(df00,df1[i])<br> <span class="hljs-keyword">return</span> df0,df1<br><br><span class="hljs-comment">######################################### 阶数确定 ##############################################</span><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">p_finally</span>(<span class="hljs-params">n</span>):<br> jieguo = []<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">1</span>,n):<br> df0,df1 = AR_prediction(data,i)<br> aicc,bic = information(data,df0,i)<br> jieguo.append([i,aicc,bic])<br> jieguo_aicc = <span class="hljs-built_in">sorted</span>(jieguo,reverse=<span class="hljs-literal">False</span>, key=<span class="hljs-keyword">lambda</span> x: x[<span class="hljs-number">1</span>]) <span class="hljs-comment">#以aicc排序</span><br> jieguo_bic = <span class="hljs-built_in">sorted</span>(jieguo,reverse=<span class="hljs-literal">False</span>, key=<span class="hljs-keyword">lambda</span> x: x[<span class="hljs-number">2</span>]) <span class="hljs-comment">#以bic排序</span><br> <span class="hljs-keyword">return</span> jieguo_aicc[<span class="hljs-number">0</span>][<span class="hljs-number">0</span>],jieguo_bic[<span class="hljs-number">0</span>][<span class="hljs-number">0</span>]<br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">sma</span>(<span class="hljs-params">x</span>):<br> <span class="hljs-keyword">return</span> np.mean(x) <span class="hljs-comment">#简单移动平均</span><br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">wma</span>(<span class="hljs-params">x</span>):<br> x = np.array(x).ravel()<br> w = np.arange(<span class="hljs-number">1</span>,<span class="hljs-built_in">len</span>(x)+<span class="hljs-number">1</span>) <span class="hljs-comment">#生成等差数列</span><br> <span class="hljs-keyword">return</span> np.<span class="hljs-built_in">sum</span>(x*w)/(<span class="hljs-built_in">len</span>(x)*(<span class="hljs-built_in">len</span>(x)+<span class="hljs-number">1</span>)/<span class="hljs-number">2</span>) <span class="hljs-comment">#加权移动平均(等距)</span><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">ema</span>(<span class="hljs-params">x,i</span>):<br> x = np.array(x).ravel()<br> <span class="hljs-keyword">if</span> i < <span class="hljs-number">1</span> <span class="hljs-keyword">and</span> i > <span class="hljs-number">0</span>:<br> l = <span class="hljs-built_in">len</span>(x)<br> w = np.logspace(l, <span class="hljs-number">0</span>, num=l, base=(<span class="hljs-number">1</span>-i)) <span class="hljs-comment">#生成等比数列</span><br> <span class="hljs-keyword">else</span>:<br> <span class="hljs-built_in">print</span>(<span class="hljs-string">'平滑因子范围错误'</span>)<br> <span class="hljs-keyword">return</span> np.<span class="hljs-built_in">sum</span>(x*w)/np.<span class="hljs-built_in">sum</span>(w) <span class="hljs-comment">#指数移动平均</span><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">MA_prediction</span>(<span class="hljs-params">data, q, predict_x_n=<span class="hljs-number">0</span></span>):<br> <span class="hljs-comment">########################## 移动平均预测 ################################</span><br> df = np.array(data).ravel() <span class="hljs-comment">#将数据转化为numpy格式,并将其转化为一维列表</span><br> df0 = df.copy() <span class="hljs-comment">#准备一个副本,存储真实值以及预测值</span><br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-built_in">len</span>(data)-q+<span class="hljs-number">1</span>):<br> df[q+i-<span class="hljs-number">1</span>] = ema(data[i:i+q],<span class="hljs-number">0.5</span>) <span class="hljs-comment">#获得简单移动平均获得的预测数列</span><br><br> df_wu = df0 - df <span class="hljs-comment">#获得误差项</span><br><br> df1 = np.zeros(predict_x_n) <span class="hljs-comment">#存储预测值</span><br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(predict_x_n):<br> df1[i] = ema(df0[-q:],<span class="hljs-number">0.5</span>) <span class="hljs-comment">#得到所有预测值</span><br> df0 = np.append(df0,df1[i])<br> <span class="hljs-comment">############################## 误差项预测 ###############################</span><br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">MA_AR_prediction</span>(<span class="hljs-params">x, p, predict_x_n = <span class="hljs-number">0</span></span>): <span class="hljs-comment">#误差项预测实际就为AR预测,这也是为什么MA模型阶数为0时就转化成AR模型的原因</span><br> df = np.array(x[p:]).ravel() <span class="hljs-comment">#将数据转化为numpy格式,并将其转化为一维列表</span><br> df0 = df.copy() <span class="hljs-comment">#准备一个副本,为了存储预测的数据</span><br> Y = df[p:].copy()<br> h = <span class="hljs-built_in">len</span>(df0)-p<br> X = np.zeros((h,p+<span class="hljs-number">1</span>))<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(h): <span class="hljs-comment">#得到X矩阵</span><br> X[i][<span class="hljs-number">0</span>] = <span class="hljs-number">1</span><br> <span class="hljs-keyword">for</span> v <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">1</span>,p+<span class="hljs-number">1</span>):<br> X[i,-v] = df[i+v-<span class="hljs-number">1</span>]<br> sigma = np.linalg.inv(X.T.dot(X)).dot(X.T).dot(Y.T) <span class="hljs-comment">#最小二乘法估计参数值</span><br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(h):<br> df0[p+i] = <span class="hljs-built_in">sum</span>(sigma * X[i]) <span class="hljs-comment">#得到所有预测的估计值</span><br> df00 = df.copy()<br> df1 = np.zeros(predict_x_n)<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(predict_x_n):<br> df1[i] = <span class="hljs-built_in">sum</span>(sigma[<span class="hljs-number">1</span>:] * df00[-p:][::-<span class="hljs-number">1</span>])+sigma[<span class="hljs-number">0</span>] <span class="hljs-comment">#得到所有预测值</span><br> df00 = np.append(df00,df1[i])<br> <span class="hljs-keyword">return</span> df0,df1<br> wucha,wucha_predict = MA_AR_prediction(df_wu,q,predict_x_n)<br> <span class="hljs-keyword">return</span> wucha,wucha_predict<br><span class="hljs-keyword">def</span> <span class="hljs-title function_">sum_s</span>(<span class="hljs-params">data,df,q,result_predict</span>):<br> data = np.array(data).ravel()<br> df = np.array(df).ravel()<br> result_predict = np.array(result_predict).ravel()<br> <span class="hljs-keyword">if</span> <span class="hljs-built_in">len</span>(data)-<span class="hljs-built_in">len</span>(df)==<span class="hljs-number">1</span>+q:<br> data0 = np.zeros(<span class="hljs-built_in">len</span>(data))<br> data0[<span class="hljs-number">0</span>] = data[<span class="hljs-number">0</span>]<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-built_in">len</span>(data)-<span class="hljs-number">1</span>):<br> data0[i+<span class="hljs-number">1</span>] = data[i]<br> df0 = np.zeros(<span class="hljs-built_in">len</span>(df)+<span class="hljs-number">1</span>)<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-built_in">len</span>(df)):<br> df0[i+<span class="hljs-number">1</span>] = df[i]<br> asd = data0[-<span class="hljs-built_in">len</span>(df0):]+df0<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-built_in">len</span>(result_predict)):<br> <span class="hljs-keyword">if</span> i == <span class="hljs-number">0</span>:<br> result_predict[<span class="hljs-number">0</span>]=result_predict[<span class="hljs-number">0</span>]+asd[-<span class="hljs-number">1</span>]<br> <span class="hljs-keyword">else</span>:<br> result_predict[i]=result_predict[i]+result_predict[i-<span class="hljs-number">1</span>]<br> <span class="hljs-built_in">print</span>(result_predict)<br> <span class="hljs-keyword">return</span> asd,result_predict<br> <span class="hljs-keyword">elif</span> <span class="hljs-built_in">len</span>(data)-<span class="hljs-built_in">len</span>(df)==<span class="hljs-number">2</span>+q:<br> cha1 = np.diff(data)<br> cha1_1,result_predict = sum_s(cha1,df,q,result_predict)<br> <span class="hljs-keyword">return</span> sum_s(data,cha1_1,q,result_predict)<br> <span class="hljs-keyword">elif</span> <span class="hljs-built_in">len</span>(data)-<span class="hljs-built_in">len</span>(df)==<span class="hljs-number">3</span>+q:<br> cha1 = np.diff(data)<br> cha11 = np.diff(cha1)<br> cha1_1,result_predict = sum_s(cha11,df,q,result_predict)<br> cha1_1_1,result_predict = sum_s(cha1,cha1_1,q,result_predict)<br> <span class="hljs-keyword">return</span> sum_s(data,cha1_1_1,q,result_predict)<br><span class="hljs-keyword">def</span> <span class="hljs-title function_">ARIMA</span>(<span class="hljs-params">p,q,d,data,predict_n=<span class="hljs-number">0</span></span>):<br> df_0 = np.array(data).ravel()<br> df = np.diff(df_0,d)<br> wucha,wucha_predict = MA_prediction(df, q, predict_n)<br> <span class="hljs-comment">#p_aicc,p_bic = p_finally(10)</span><br> df0,df1 = AR_prediction(df,p,predict_n)<br> result = df0[-<span class="hljs-built_in">len</span>(wucha):] - wucha<br> result_predict = df1-wucha_predict<br> <span class="hljs-keyword">if</span> d != <span class="hljs-number">0</span>:<br> result,result_predict = sum_s(df_0,result,q,result_predict)<br> <span class="hljs-keyword">return</span> result,result_predict<br><br>result,result_predict = ARIMA(<span class="hljs-number">4</span>,<span class="hljs-number">4</span>,<span class="hljs-number">0</span>,data,<span class="hljs-number">4</span>)<br><br>asd = np.append(result,result_predict)<br>plt.plot(<span class="hljs-built_in">range</span>(<span class="hljs-built_in">len</span>(data[-<span class="hljs-number">60</span>:])),data[-<span class="hljs-number">60</span>:],c=<span class="hljs-string">'b'</span>)<br>plt.plot(<span class="hljs-built_in">range</span>(<span class="hljs-built_in">len</span>(result[-<span class="hljs-number">63</span>:])),asd[-<span class="hljs-number">63</span>:],c=<span class="hljs-string">'r'</span>)<br>plt.show()<br></code></pre></td></tr></table></figure>]]></content>
<categories>
<category>数学建模</category>
</categories>
</entry>
<entry>
<title>ARMA预测代码</title>
<link href="/2024/09/11/ARMA%E9%A2%84%E6%B5%8B/"/>
<url>/2024/09/11/ARMA%E9%A2%84%E6%B5%8B/</url>
<content type="html"><![CDATA[<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">from</span> math <span class="hljs-keyword">import</span> log<br><span class="hljs-keyword">import</span> numpy <span class="hljs-keyword">as</span> np<br><span class="hljs-keyword">import</span> pandas <span class="hljs-keyword">as</span> pd<br><span class="hljs-keyword">import</span> matplotlib.pyplot <span class="hljs-keyword">as</span> plt<br><span class="hljs-keyword">from</span> sklearn.metrics <span class="hljs-keyword">import</span> mean_squared_error<br>np.set_printoptions(threshold=np.inf) <span class="hljs-comment"># threshold 指定超过多少使用省略号,np.inf代表无限大</span><br>np.set_printoptions(suppress=<span class="hljs-literal">True</span>) <span class="hljs-comment">#不以科学计数法输出</span><br><span class="hljs-keyword">import</span> warnings<br>warnings.filterwarnings(<span class="hljs-string">"ignore"</span>)<br>plt.rcParams[<span class="hljs-string">'axes.unicode_minus'</span>] = <span class="hljs-literal">False</span> <span class="hljs-comment">#显示负号</span><br>plt.rcParams[<span class="hljs-string">'font.family'</span>] = [<span class="hljs-string">'sans-serif'</span>]<br>plt.rcParams[<span class="hljs-string">'font.sans-serif'</span>] = [<span class="hljs-string">'SimHei'</span>] <span class="hljs-comment"># 散点图标签可以显示中文</span><br><br>data = pd.read_csv(<span class="hljs-string">'时间序列预测数据集.csv'</span>,parse_dates=[<span class="hljs-string">'Date'</span>])<br>data.set_index(<span class="hljs-string">'Date'</span>,inplace=<span class="hljs-literal">True</span>) <span class="hljs-comment">#将时间设置为行索引</span><br><br><span class="hljs-comment">##################################### 信息准则 ###########################################</span><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">information</span>(<span class="hljs-params">df,df0,p</span>):<br> n = <span class="hljs-built_in">len</span>(df)<br> mse = mean_squared_error(df,df0)<br> <span class="hljs-comment">#aic = n * log(mse) + 2 * p</span><br> aicc = log(mse) + (n+p)/(n-p-<span class="hljs-number">2</span>)<br> bic = n * log(mse) + p * log(n)<br> <span class="hljs-keyword">return</span> aicc,bic<br><span class="hljs-keyword">def</span> <span class="hljs-title function_">AR_prediction</span>(<span class="hljs-params">x, p, predict_x_n = <span class="hljs-number">0</span></span>):<br> df = np.array(x).ravel() <span class="hljs-comment">#将数据转化为numpy格式,并将其转化为一维列表</span><br> df0 = df.copy() <span class="hljs-comment">#准备一个副本,为了存储预测的数据</span><br> Y = df[p:].copy()<br> h = <span class="hljs-built_in">len</span>(df0)-p<br> X = np.zeros((h,p+<span class="hljs-number">1</span>))<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(h): <span class="hljs-comment">#得到X矩阵</span><br> X[i][<span class="hljs-number">0</span>] = <span class="hljs-number">1</span><br> <span class="hljs-keyword">for</span> v <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">1</span>,p+<span class="hljs-number">1</span>):<br> X[i,-v] = df[i+v-<span class="hljs-number">1</span>]<br> sigma = np.linalg.inv(X.T.dot(X)).dot(X.T).dot(Y.T) <span class="hljs-comment">#最小二乘法估计参数值</span><br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(h):<br> df0[p+i] = <span class="hljs-built_in">sum</span>(sigma * X[i]) <span class="hljs-comment">#得到所有预测的估计值</span><br> df00 = df.copy()<br> df1 = np.zeros(predict_x_n)<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(predict_x_n):<br> df1[i] = <span class="hljs-built_in">sum</span>(np.multiply(sigma , df00[-p:][::-<span class="hljs-number">1</span>])) <span class="hljs-comment">#得到所有预测值</span><br> df00 = np.append(df00,df1[i])<br> <span class="hljs-keyword">return</span> df0,df1<br><br><span class="hljs-comment">######################################### 阶数确定 ##############################################</span><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">p_finally</span>(<span class="hljs-params">n</span>):<br> jieguo = []<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">1</span>,n):<br> df0,df1 = AR_prediction(data,i)<br> aicc,bic = information(data,df0,i)<br> jieguo.append([i,aicc,bic])<br> jieguo_aicc = <span class="hljs-built_in">sorted</span>(jieguo,reverse=<span class="hljs-literal">False</span>, key=<span class="hljs-keyword">lambda</span> x: x[<span class="hljs-number">1</span>]) <span class="hljs-comment">#以aicc排序</span><br> jieguo_bic = <span class="hljs-built_in">sorted</span>(jieguo,reverse=<span class="hljs-literal">False</span>, key=<span class="hljs-keyword">lambda</span> x: x[<span class="hljs-number">2</span>]) <span class="hljs-comment">#以bic排序</span><br> <span class="hljs-keyword">return</span> jieguo_aicc[<span class="hljs-number">0</span>][<span class="hljs-number">0</span>],jieguo_bic[<span class="hljs-number">0</span>][<span class="hljs-number">0</span>]<br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">sma</span>(<span class="hljs-params">x</span>):<br> <span class="hljs-keyword">return</span> np.mean(x) <span class="hljs-comment">#简单移动平均</span><br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">wma</span>(<span class="hljs-params">x</span>):<br> x = np.array(x).ravel()<br> w = np.arange(<span class="hljs-number">1</span>,<span class="hljs-built_in">len</span>(x)+<span class="hljs-number">1</span>) <span class="hljs-comment">#生成等差数列</span><br> <span class="hljs-keyword">return</span> np.<span class="hljs-built_in">sum</span>(x*w)/(<span class="hljs-built_in">len</span>(x)*(<span class="hljs-built_in">len</span>(x)+<span class="hljs-number">1</span>)/<span class="hljs-number">2</span>) <span class="hljs-comment">#加权移动平均(等距)</span><br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">ema</span>(<span class="hljs-params">x,i</span>):<br> x = np.array(x).ravel()<br> <span class="hljs-keyword">if</span> i < <span class="hljs-number">1</span> <span class="hljs-keyword">and</span> i > <span class="hljs-number">0</span>:<br> l = <span class="hljs-built_in">len</span>(x)<br> w = np.logspace(l, <span class="hljs-number">0</span>, num=l, base=(<span class="hljs-number">1</span>-i)) <span class="hljs-comment">#生成等比数列</span><br> <span class="hljs-keyword">else</span>:<br> <span class="hljs-built_in">print</span>(<span class="hljs-string">'平滑因子范围错误'</span>)<br> <span class="hljs-keyword">return</span> np.<span class="hljs-built_in">sum</span>(x*w)/np.<span class="hljs-built_in">sum</span>(w) <span class="hljs-comment">#指数移动平均</span><br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">MA_prediction</span>(<span class="hljs-params">data, q, predict_x_n=<span class="hljs-number">0</span></span>):<br> <span class="hljs-comment">########################## 移动平均预测 ################################</span><br> df = np.array(data).ravel() <span class="hljs-comment">#将数据转化为numpy格式,并将其转化为一维列表</span><br> df0 = df.copy() <span class="hljs-comment">#准备一个副本,存储真实值以及预测值</span><br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-built_in">len</span>(data)-q+<span class="hljs-number">1</span>):<br> df[q+i-<span class="hljs-number">1</span>] = ema(data[i:i+q],<span class="hljs-number">0.5</span>) <span class="hljs-comment">#获得简单移动平均获得的预测数列</span><br><br> df_wu = df0 - df <span class="hljs-comment">#获得误差项</span><br><br> df1 = np.zeros(predict_x_n) <span class="hljs-comment">#存储预测值</span><br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(predict_x_n):<br> df1[i] = ema(df0[-q:],<span class="hljs-number">0.5</span>) <span class="hljs-comment">#得到所有预测值</span><br> df0 = np.append(df0,df1[i])<br> <span class="hljs-comment">############################## 误差项预测 ###############################</span><br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">MA_AR_prediction</span>(<span class="hljs-params">x, p, predict_x_n = <span class="hljs-number">0</span></span>): <span class="hljs-comment">#误差项预测实际就为AR预测,这也是为什么MA模型阶数为0时就转化成AR模型的原因</span><br> df = np.array(x[p:]).ravel() <span class="hljs-comment">#将数据转化为numpy格式,并将其转化为一维列表</span><br> df0 = df.copy() <span class="hljs-comment">#准备一个副本,为了存储预测的数据</span><br> Y = df[p:].copy()<br> h = <span class="hljs-built_in">len</span>(df0)-p<br> X = np.zeros((h,p+<span class="hljs-number">1</span>))<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(h): <span class="hljs-comment">#得到X矩阵</span><br> X[i][<span class="hljs-number">0</span>] = <span class="hljs-number">1</span><br> <span class="hljs-keyword">for</span> v <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">1</span>,p+<span class="hljs-number">1</span>):<br> X[i,-v] = df[i+v-<span class="hljs-number">1</span>]<br> sigma = np.linalg.inv(X.T.dot(X)).dot(X.T).dot(Y.T) <span class="hljs-comment">#最小二乘法估计参数值</span><br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(h):<br> df0[p+i] = <span class="hljs-built_in">sum</span>(sigma * X[i]) <span class="hljs-comment">#得到所有预测的估计值</span><br> df00 = df.copy()<br> df1 = np.zeros(predict_x_n)<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(predict_x_n):<br> df1[i] = <span class="hljs-built_in">sum</span>(np.multiply(sigma , df00[-p:][::-<span class="hljs-number">1</span>])) <span class="hljs-comment">#得到所有预测值</span><br> df00 = np.append(df00,df1[i])<br> <span class="hljs-keyword">return</span> df0,df1<br> wucha,wucha_predict = MA_AR_prediction(df_wu,q,predict_x_n)<br> <span class="hljs-keyword">return</span> wucha,wucha_predict<br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">ARMA</span>(<span class="hljs-params">p,q</span>):<br> wucha,wucha_predict = MA_prediction(data, q, <span class="hljs-number">0</span>)<br> <span class="hljs-comment">#p_aicc,p_bic = p_finally(10)</span><br> df0,df1 = AR_prediction(data,p,<span class="hljs-number">0</span>)<br> result = df0[-<span class="hljs-built_in">len</span>(wucha):] - wucha<br> <span class="hljs-keyword">return</span> result<br><br>result = ARMA(<span class="hljs-number">1</span>,<span class="hljs-number">6</span>)<br>plt.figure()<br>plt.plot(<span class="hljs-built_in">range</span>(<span class="hljs-number">60</span>),data[-<span class="hljs-number">60</span>:],c = <span class="hljs-string">'black'</span>)<br>plt.plot(<span class="hljs-built_in">range</span>(<span class="hljs-number">60</span>),result[-<span class="hljs-number">60</span>:],c=<span class="hljs-string">'red'</span>)<br>plt.show()<br><br><span class="hljs-built_in">print</span>(<span class="hljs-string">'mse:'</span>,mean_squared_error(result,data[-<span class="hljs-built_in">len</span>(result):]))<br><br></code></pre></td></tr></table></figure>]]></content>
<categories>
<category>数学建模</category>
</categories>
</entry>
<entry>
<title>MA预测代码</title>
<link href="/2024/09/11/MA%E9%A2%84%E6%B5%8B/"/>
<url>/2024/09/11/MA%E9%A2%84%E6%B5%8B/</url>
<content type="html"><![CDATA[<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">import</span> numpy <span class="hljs-keyword">as</span> np<br><span class="hljs-keyword">import</span> pandas <span class="hljs-keyword">as</span> pd<br><span class="hljs-keyword">import</span> matplotlib.pyplot <span class="hljs-keyword">as</span> plt<br>np.set_printoptions(threshold=np.inf) <span class="hljs-comment"># threshold 指定超过多少使用省略号,np.inf代表无限大</span><br>np.set_printoptions(suppress=<span class="hljs-literal">True</span>) <span class="hljs-comment">#不以科学计数法输出</span><br><span class="hljs-keyword">import</span> warnings<br>warnings.filterwarnings(<span class="hljs-string">"ignore"</span>)<br>plt.rcParams[<span class="hljs-string">'axes.unicode_minus'</span>] = <span class="hljs-literal">False</span> <span class="hljs-comment">#显示负号</span><br>plt.rcParams[<span class="hljs-string">'font.family'</span>] = [<span class="hljs-string">'sans-serif'</span>]<br>plt.rcParams[<span class="hljs-string">'font.sans-serif'</span>] = [<span class="hljs-string">'SimHei'</span>] <span class="hljs-comment"># 散点图标签可以显示中文</span><br><br>data = pd.read_csv(<span class="hljs-string">'时间序列预测数据集.csv'</span>,parse_dates=[<span class="hljs-string">'Date'</span>])<br>data.set_index(<span class="hljs-string">'Date'</span>,inplace=<span class="hljs-literal">True</span>) <span class="hljs-comment">#将时间设置为行索引</span><br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">sma</span>(<span class="hljs-params">x</span>):<br> <span class="hljs-keyword">return</span> np.mean(x) <span class="hljs-comment">#简单移动平均</span><br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">wma</span>(<span class="hljs-params">x</span>):<br> x = np.array(x).ravel()<br> w = np.arange(<span class="hljs-number">1</span>,<span class="hljs-built_in">len</span>(x)+<span class="hljs-number">1</span>) <span class="hljs-comment">#生成等差数列</span><br> <span class="hljs-keyword">return</span> np.<span class="hljs-built_in">sum</span>(x*w)/(<span class="hljs-built_in">len</span>(x)*(<span class="hljs-built_in">len</span>(x)+<span class="hljs-number">1</span>)/<span class="hljs-number">2</span>) <span class="hljs-comment">#加权移动平均(等距)</span><br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">ema</span>(<span class="hljs-params">x,i</span>):<br> x = np.array(x).ravel()<br> <span class="hljs-keyword">if</span> i < <span class="hljs-number">1</span> <span class="hljs-keyword">and</span> i > <span class="hljs-number">0</span>:<br> l = <span class="hljs-built_in">len</span>(x)<br> w = np.logspace(l, <span class="hljs-number">0</span>, num=l, base=(<span class="hljs-number">1</span>-i)) <span class="hljs-comment">#生成等比数列</span><br> <span class="hljs-keyword">else</span>:<br> <span class="hljs-built_in">print</span>(<span class="hljs-string">'平滑因子范围错误'</span>)<br> <span class="hljs-keyword">return</span> np.<span class="hljs-built_in">sum</span>(x*w)/np.<span class="hljs-built_in">sum</span>(w) <span class="hljs-comment">#指数移动平均</span><br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">ma_prediction</span>(<span class="hljs-params">data, q, predict_x_n=<span class="hljs-number">0</span></span>):<br><span class="hljs-comment">########################## 移动平均预测 ################################</span><br> df = np.array(data).ravel() <span class="hljs-comment">#将数据转化为numpy格式,并将其转化为一维列表</span><br> df0 = df.copy() <span class="hljs-comment">#准备一个副本,存储真实值以及预测值</span><br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-built_in">len</span>(data)-q+<span class="hljs-number">1</span>):<br> df[q+i-<span class="hljs-number">1</span>] = ema(data[i:i+q],<span class="hljs-number">0.5</span>) <span class="hljs-comment">#获得简单移动平均获得的预测数列</span><br><br> df_wu = df0 - df <span class="hljs-comment">#获得误差项</span><br><br> df1 = np.zeros(predict_x_n) <span class="hljs-comment">#存储预测值</span><br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(predict_x_n):<br> df1[i] = ema(df0[-q:],<span class="hljs-number">0.5</span>) <span class="hljs-comment">#得到所有预测值</span><br> df0 = np.append(df0,df1[i])<br><span class="hljs-comment">############################## 误差项预测 ###############################</span><br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">AR_prediction</span>(<span class="hljs-params">x, p, predict_x_n = <span class="hljs-number">0</span></span>): <span class="hljs-comment">#误差项预测实际就为AR预测,这也是为什么MA模型阶数为0时就转化成AR模型的原因</span><br> df = np.array(x[p:]).ravel() <span class="hljs-comment">#将数据转化为numpy格式,并将其转化为一维列表</span><br> df0 = df.copy() <span class="hljs-comment">#准备一个副本,为了存储预测的数据</span><br> Y = df[p:].copy()<br> h = <span class="hljs-built_in">len</span>(df0)-p<br> X = np.zeros((h,p+<span class="hljs-number">1</span>))<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(h): <span class="hljs-comment">#得到X矩阵</span><br> X[i][<span class="hljs-number">0</span>] = <span class="hljs-number">1</span><br> <span class="hljs-keyword">for</span> v <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">1</span>,p+<span class="hljs-number">1</span>):<br> X[i,-v] = df[i+v-<span class="hljs-number">1</span>]<br> sigma = np.linalg.inv(X.T.dot(X)).dot(X.T).dot(Y.T) <span class="hljs-comment">#最小二乘法估计参数值</span><br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(h):<br> df0[p+i] = <span class="hljs-built_in">sum</span>(np.multiply(sigma , X[i])) <span class="hljs-comment">#得到所有预测的估计值</span><br> df00 = df.copy()<br> df1 = np.zeros(predict_x_n)<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(predict_x_n):<br> df1[i] = <span class="hljs-built_in">sum</span>(np.multiply(sigma , df00[-p:][::-<span class="hljs-number">1</span>])) <span class="hljs-comment">#得到所有预测值</span><br> df00 = np.append(df00,df1[i])<br> <span class="hljs-keyword">return</span> df0,df1<br> wucha,wucha_predict = AR_prediction(df_wu,q,predict_x_n)<br> result = df[-<span class="hljs-built_in">len</span>(wucha):] - wucha<br> predict = df1 - wucha_predict<br> <span class="hljs-keyword">return</span> result,predict<br><br>result,predict = ma_prediction(data, <span class="hljs-number">6</span>, <span class="hljs-number">0</span>)<br><br>plt.figure()<br>plt.plot(<span class="hljs-built_in">range</span>(<span class="hljs-number">60</span>),data[-<span class="hljs-number">60</span>:],c = <span class="hljs-string">'black'</span>)<br>plt.plot(<span class="hljs-built_in">range</span>(<span class="hljs-number">60</span>),result[-<span class="hljs-number">60</span>:],c=<span class="hljs-string">'red'</span>)<br>plt.show()<br></code></pre></td></tr></table></figure>]]></content>
<categories>
<category>数学建模</category>
</categories>
</entry>
<entry>
<title>AR预测代码</title>
<link href="/2024/09/11/AR%E9%A2%84%E6%B5%8B/"/>
<url>/2024/09/11/AR%E9%A2%84%E6%B5%8B/</url>
<content type="html"><![CDATA[<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">from</span> math <span class="hljs-keyword">import</span> log<br><span class="hljs-keyword">import</span> numpy <span class="hljs-keyword">as</span> np<br><span class="hljs-keyword">import</span> pandas <span class="hljs-keyword">as</span> pd<br><span class="hljs-keyword">import</span> matplotlib.pyplot <span class="hljs-keyword">as</span> plt<br><span class="hljs-keyword">from</span> sklearn.metrics <span class="hljs-keyword">import</span> mean_squared_error<br><span class="hljs-keyword">from</span> statsmodels.stats.diagnostic <span class="hljs-keyword">import</span> acorr_ljungbox<br><span class="hljs-keyword">from</span> statsmodels.graphics.tsaplots <span class="hljs-keyword">import</span> plot_pacf,plot_acf<br><span class="hljs-keyword">import</span> statsmodels.api <span class="hljs-keyword">as</span> sm<br><span class="hljs-keyword">import</span> warnings<br>warnings.filterwarnings(<span class="hljs-string">"ignore"</span>)<br>np.set_printoptions(threshold=np.inf) <span class="hljs-comment"># threshold 指定超过多少使用省略号,np.inf代表无限大</span><br>np.set_printoptions(suppress=<span class="hljs-literal">True</span>) <span class="hljs-comment">#不以科学计数法输出</span><br>plt.rcParams[<span class="hljs-string">'axes.unicode_minus'</span>] = <span class="hljs-literal">False</span> <span class="hljs-comment">#显示负号</span><br>plt.rcParams[<span class="hljs-string">'font.family'</span>] = [<span class="hljs-string">'sans-serif'</span>]<br>plt.rcParams[<span class="hljs-string">'font.sans-serif'</span>] = [<span class="hljs-string">'SimHei'</span>] <span class="hljs-comment"># 散点图标签可以显示中文</span><br><br>data = pd.read_csv(<span class="hljs-string">'时间序列预测数据集.csv'</span>,parse_dates=[<span class="hljs-string">'Date'</span>])<br>data.set_index(<span class="hljs-string">'Date'</span>,inplace=<span class="hljs-literal">True</span>) <span class="hljs-comment">#将时间设置为行索引</span><br><span class="hljs-comment">#data = data["1981-01-01":"1982-01-01"]</span><br><span class="hljs-comment">#################################### 绘制时序图 ############################################</span><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">picture</span>(<span class="hljs-params">data</span>):<br> plt.figure(figsize=(<span class="hljs-number">16</span>,<span class="hljs-number">16</span>))<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">1</span>,<span class="hljs-number">5</span>):<br> plt.subplot(<span class="hljs-number">4</span>,<span class="hljs-number">1</span>,i)<br> df = data[<span class="hljs-string">f"198<span class="hljs-subst">{<span class="hljs-number">1</span>+<span class="hljs-number">2</span>*(i-<span class="hljs-number">1</span>)}</span>-01-01"</span>:<span class="hljs-string">f"198<span class="hljs-subst">{<span class="hljs-number">3</span>+<span class="hljs-number">2</span>*(i-<span class="hljs-number">1</span>)}</span>-01-01"</span>]<br> plt.plot(df.index,df[<span class="hljs-string">'Temp'</span>])<br> plt.xticks(rotation=<span class="hljs-number">45</span>,size=<span class="hljs-number">6</span>)<br> <span class="hljs-keyword">if</span> i == <span class="hljs-number">1</span>:<br> plt.title(<span class="hljs-string">"时序图"</span>)<br> plt.show()<br> plt.close()<br><span class="hljs-comment">###################################### 时间序列检验 #######################################</span><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">inspect</span>(<span class="hljs-params">data</span>):<br> <span class="hljs-comment"># 单位根检验-ADF检验</span><br> ADF = sm.tsa.stattools.adfuller(data[<span class="hljs-string">'Temp'</span>])<br> <span class="hljs-built_in">print</span>(<span class="hljs-string">'ADF值:'</span>, <span class="hljs-built_in">format</span>(ADF[<span class="hljs-number">0</span>], <span class="hljs-string">'.4f'</span>))<br> <span class="hljs-built_in">print</span>(<span class="hljs-string">'拒绝程度值:'</span>, ADF[<span class="hljs-number">4</span>]) <span class="hljs-comment">#ADF值需要小于三个拒绝程度值</span><br><br> <span class="hljs-comment"># 白噪声检验</span><br> white_noise = acorr_ljungbox(data[<span class="hljs-string">'Temp'</span>], lags = [<span class="hljs-number">6</span>, <span class="hljs-number">12</span>, <span class="hljs-number">24</span>],boxpierce=<span class="hljs-literal">True</span>) <span class="hljs-comment">#lag是需要检验的阶数</span><br> <span class="hljs-built_in">print</span>(<span class="hljs-string">'白噪声检验:\n'</span>,white_noise) <span class="hljs-comment">#LB和BP统计量的P值都小于显著水平(α = 0.05),所以拒绝序列为纯随机序列的原假设,认为该序列为非白噪声序列</span><br><br> fig = plt.figure(figsize=(<span class="hljs-number">16</span>,<span class="hljs-number">6</span>))<br><br> ax1 = fig.add_subplot(<span class="hljs-number">1</span>,<span class="hljs-number">2</span>,<span class="hljs-number">1</span>)<br> plot_acf(data[<span class="hljs-string">'Temp'</span>],ax=ax1)<br> plt.title(<span class="hljs-string">"自相关图"</span>) <span class="hljs-comment">#需要拖尾,确定q</span><br><br> ax2 = fig.add_subplot(<span class="hljs-number">1</span>,<span class="hljs-number">2</span>,<span class="hljs-number">2</span>)<br> plot_pacf(data[<span class="hljs-string">'Temp'</span>],ax=ax2)<br> plt.title(<span class="hljs-string">"偏自相关图"</span>) <span class="hljs-comment">#需要截尾,确定p</span><br><br> plt.show()<br> plt.close()<br><span class="hljs-comment">##################################### 信息准则 ###########################################</span><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">information</span>(<span class="hljs-params">df,df0,p</span>):<br> n = <span class="hljs-built_in">len</span>(df)<br> mse = mean_squared_error(df,df0)<br> <span class="hljs-comment">#aic = n * log(mse) + 2 * p</span><br> aicc = log(mse) + (n+p)/(n-p-<span class="hljs-number">2</span>)<br> bic = n * log(mse) + p * log(n)<br> <span class="hljs-keyword">return</span> aicc,bic<br><br><span class="hljs-comment">#################################### 模型预测 ##########################################</span><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">AR_prediction</span>(<span class="hljs-params">x, p, predict_x_n = <span class="hljs-number">0</span></span>):<br> df = np.array(x).ravel() <span class="hljs-comment">#将数据转化为numpy格式,并将其转化为一维列表</span><br> df0 = df.copy() <span class="hljs-comment">#准备一个副本,为了存储预测的数据</span><br> Y = df[p:].copy()<br> h = <span class="hljs-built_in">len</span>(df0)-p<br> X = np.zeros((h,p+<span class="hljs-number">1</span>))<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(h): <span class="hljs-comment">#得到X矩阵</span><br> X[i][<span class="hljs-number">0</span>] = <span class="hljs-number">1</span><br> <span class="hljs-keyword">for</span> v <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">1</span>,p+<span class="hljs-number">1</span>):<br> X[i][-v] = df[i+v-<span class="hljs-number">1</span>]<br> sigma = np.linalg.inv(X.T.dot(X)).dot(X.T).dot(Y.T) <span class="hljs-comment">#最小二乘法估计参数值</span><br> <span class="hljs-built_in">print</span>(sigma)<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(h):<br> df0[p+i] = <span class="hljs-built_in">sum</span>(sigma * X[i]) <span class="hljs-comment">#得到所有预测的估计值</span><br> df00 = df.copy()<br> df1 = np.zeros(predict_x_n)<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(predict_x_n):<br> df1[i] = <span class="hljs-built_in">sum</span>(np.multiply(sigma , df00[-p:][::-<span class="hljs-number">1</span>])) <span class="hljs-comment">#得到所有预测值</span><br> df00 = np.append(df00,df1[i])<br> <span class="hljs-keyword">return</span> df0,df1<br><br><span class="hljs-comment">######################################### 阶数确定 ##############################################</span><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">p_finally</span>(<span class="hljs-params">n</span>):<br> jieguo = []<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">1</span>,n):<br> df0,df1 = AR_prediction(data,i)<br> aicc,bic = information(data,df0,i)<br> jieguo.append([i,aicc,bic])<br> jieguo_aicc = <span class="hljs-built_in">sorted</span>(jieguo,reverse=<span class="hljs-literal">False</span>, key=<span class="hljs-keyword">lambda</span> x: x[<span class="hljs-number">1</span>]) <span class="hljs-comment">#以aicc排序</span><br> jieguo_bic = <span class="hljs-built_in">sorted</span>(jieguo,reverse=<span class="hljs-literal">False</span>, key=<span class="hljs-keyword">lambda</span> x: x[<span class="hljs-number">2</span>]) <span class="hljs-comment">#以bic排序</span><br><br> <span class="hljs-keyword">return</span> jieguo_aicc[<span class="hljs-number">0</span>][<span class="hljs-number">0</span>],jieguo_bic[<span class="hljs-number">0</span>][<span class="hljs-number">0</span>]<br><br><span class="hljs-comment">################################# 得到最终结果 ###################################</span><br><span class="hljs-comment">#images(data)</span><br><span class="hljs-comment">#inspect(data)</span><br><br><span class="hljs-comment">#p_aicc,p_bic = p_finally(30)</span><br><span class="hljs-comment">#print(p_aicc)</span><br>df0,df1 = AR_prediction(data,<span class="hljs-number">4</span>,<span class="hljs-number">0</span>)<br><br>plt.figure()<br>plt.plot(<span class="hljs-built_in">range</span>(<span class="hljs-number">50</span>),data[-<span class="hljs-number">50</span>:],c = <span class="hljs-string">'black'</span>)<br>plt.plot(<span class="hljs-built_in">range</span>(<span class="hljs-number">50</span>),df0[-<span class="hljs-number">50</span>:],c=<span class="hljs-string">'red'</span>)<br>plt.show()<br><br></code></pre></td></tr></table></figure>]]></content>
<categories>
<category>数学建模</category>
</categories>
</entry>
<entry>
<title>灰色预测代码</title>
<link href="/2024/09/11/%E7%81%B0%E8%89%B2%E9%A2%84%E6%B5%8B/"/>
<url>/2024/09/11/%E7%81%B0%E8%89%B2%E9%A2%84%E6%B5%8B/</url>
<content type="html"><![CDATA[<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">import</span> numpy <span class="hljs-keyword">as</span> np<br><span class="hljs-keyword">import</span> math<br><span class="hljs-keyword">import</span> matplotlib.pyplot <span class="hljs-keyword">as</span> plt<br><span class="hljs-keyword">from</span> copy <span class="hljs-keyword">import</span> deepcopy<br><span class="hljs-keyword">import</span> plotly.graph_objects <span class="hljs-keyword">as</span> go<br>plt.rcParams[<span class="hljs-string">'font.sans-serif'</span>] = [<span class="hljs-string">'SimHei'</span>]<br>plt.rcParams[<span class="hljs-string">'axes.unicode_minus'</span>] = <span class="hljs-literal">False</span><br>np.set_printoptions(threshold=np.inf) <span class="hljs-comment"># threshold 指定超过多少使用省略号,np.inf代表无限大</span><br>np.set_printoptions(suppress=<span class="hljs-literal">True</span>) <span class="hljs-comment">#不以科学计数法输出</span><br><br><br>X = np.array([-<span class="hljs-number">18</span>, <span class="hljs-number">0.34</span>, <span class="hljs-number">4.68</span>, <span class="hljs-number">8.49</span>, <span class="hljs-number">29.84</span>, <span class="hljs-number">50.21</span>, <span class="hljs-number">77.65</span>, <span class="hljs-number">109.36</span>])<br>x = np.array([[<span class="hljs-number">83.0</span>, <span class="hljs-number">79.8</span>, <span class="hljs-number">78.1</span>, <span class="hljs-number">85.1</span>, <span class="hljs-number">86.6</span>, <span class="hljs-number">88.2</span>, <span class="hljs-number">90.3</span>, <span class="hljs-number">86.7</span>, <span class="hljs-number">93.3</span>, <span class="hljs-number">92.5</span>, <span class="hljs-number">90.9</span>, <span class="hljs-number">96.9</span>],<br> [<span class="hljs-number">101.7</span>, <span class="hljs-number">85.1</span>, <span class="hljs-number">87.8</span>, <span class="hljs-number">91.6</span>, <span class="hljs-number">93.4</span>, <span class="hljs-number">94.5</span>, <span class="hljs-number">97.4</span>, <span class="hljs-number">99.5</span>, <span class="hljs-number">104.2</span>, <span class="hljs-number">102.3</span>, <span class="hljs-number">101.0</span>, <span class="hljs-number">123.5</span>],<br> [<span class="hljs-number">92.2</span>, <span class="hljs-number">114.0</span>, <span class="hljs-number">93.3</span>, <span class="hljs-number">101.0</span>, <span class="hljs-number">103.5</span>, <span class="hljs-number">105.2</span>, <span class="hljs-number">109.5</span>, <span class="hljs-number">109.2</span>, <span class="hljs-number">109.6</span>, <span class="hljs-number">111.2</span>, <span class="hljs-number">121.7</span>, <span class="hljs-number">131.3</span>],<br> [<span class="hljs-number">105.0</span>, <span class="hljs-number">125.7</span>, <span class="hljs-number">106.6</span>, <span class="hljs-number">116.0</span>, <span class="hljs-number">117.6</span>, <span class="hljs-number">118.0</span>, <span class="hljs-number">121.7</span>, <span class="hljs-number">118.7</span>, <span class="hljs-number">120.2</span>, <span class="hljs-number">127.8</span>, <span class="hljs-number">121.8</span>, <span class="hljs-number">121.9</span>],<br> [<span class="hljs-number">139.3</span>, <span class="hljs-number">129.5</span>, <span class="hljs-number">122.5</span>, <span class="hljs-number">124.5</span>, <span class="hljs-number">135.7</span>, <span class="hljs-number">130.8</span>, <span class="hljs-number">138.7</span>, <span class="hljs-number">133.7</span>, <span class="hljs-number">136.8</span>, <span class="hljs-number">138.9</span>, <span class="hljs-number">129.6</span>, <span class="hljs-number">133.7</span>],<br> [<span class="hljs-number">137.5</span>, <span class="hljs-number">135.3</span>, <span class="hljs-number">133.0</span>, <span class="hljs-number">133.4</span>, <span class="hljs-number">142.8</span>, <span class="hljs-number">141.6</span>, <span class="hljs-number">142.9</span>, <span class="hljs-number">147.3</span>, <span class="hljs-number">159.6</span>, <span class="hljs-number">162.1</span>, <span class="hljs-number">153.5</span>, <span class="hljs-number">155.9</span>]])<br><span class="hljs-keyword">def</span> <span class="hljs-title function_">grey_model</span>(<span class="hljs-params">X,form,y</span>): <span class="hljs-comment">#X为代预测的数列,form为预测的数量,y为是否绘图,0不画,1画</span><br> x_0 = deepcopy(X)<br> <span class="hljs-comment">########################################## 级比检验 ###########################################</span><br> x_n = [X[i] / X[i + <span class="hljs-number">1</span>] <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-built_in">len</span>(X) - <span class="hljs-number">1</span>)] <span class="hljs-comment">#计算原数列的级比</span><br> <span class="hljs-keyword">if</span> <span class="hljs-built_in">any</span>(n <= math.exp(-<span class="hljs-number">2</span> / (<span class="hljs-built_in">len</span>(X) + <span class="hljs-number">1</span>)) <span class="hljs-keyword">for</span> n <span class="hljs-keyword">in</span> x_n)==<span class="hljs-literal">True</span> <span class="hljs-keyword">or</span> <span class="hljs-built_in">any</span>(n >= math.exp(-<span class="hljs-number">2</span> / (<span class="hljs-built_in">len</span>(X) + <span class="hljs-number">2</span>)) <span class="hljs-keyword">for</span> n <span class="hljs-keyword">in</span> x_n)==<span class="hljs-literal">True</span>:<br> <span class="hljs-built_in">print</span>(<span class="hljs-string">'______未通过级比检验______'</span>)<br> <span class="hljs-comment">#################### 级比检验不通过处理 ####################</span><br> i = <span class="hljs-number">0</span><br> <span class="hljs-keyword">while</span> <span class="hljs-literal">True</span>:<br> X += <span class="hljs-number">10</span> <span class="hljs-comment">#以10为步长慢慢给原数列加数值</span><br> x_n_new = [X[i] / X[i + <span class="hljs-number">1</span>] <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-built_in">len</span>(X) - <span class="hljs-number">1</span>)] <span class="hljs-comment">#计算每一个新的数列的级比</span><br> <span class="hljs-keyword">if</span> <span class="hljs-built_in">any</span>(n <= np.exp(-<span class="hljs-number">2</span> / (<span class="hljs-built_in">len</span>(X) + <span class="hljs-number">1</span>)) <span class="hljs-keyword">for</span> n <span class="hljs-keyword">in</span> x_n_new)==<span class="hljs-literal">True</span> <span class="hljs-keyword">or</span> <span class="hljs-built_in">any</span>(n >= np.exp(<span class="hljs-number">2</span> / (<span class="hljs-built_in">len</span>(X) + <span class="hljs-number">1</span>)) <span class="hljs-keyword">for</span> n <span class="hljs-keyword">in</span> x_n_new)==<span class="hljs-literal">True</span>:<br> i += <span class="hljs-number">1</span><br> <span class="hljs-keyword">continue</span><br> <span class="hljs-keyword">else</span>:<br> <span class="hljs-built_in">print</span>(<span class="hljs-string">'修正数列为:\n'</span>,X)<br> sc = <span class="hljs-number">10</span>*(i+<span class="hljs-number">1</span>)<br> <span class="hljs-built_in">print</span>(<span class="hljs-string">'修正值为:\n'</span>,sc)<br> <span class="hljs-keyword">break</span><br> <span class="hljs-keyword">else</span>:<br> <span class="hljs-built_in">print</span>(<span class="hljs-string">"_______通过级比检验______"</span>)<br><br> <span class="hljs-comment">###################################### 模型构建与求解 #######################################</span><br> X_sum = X.cumsum() <span class="hljs-comment"># 重新求得累加数列</span><br><br> z_n = [(X_sum[i] + X_sum[i + <span class="hljs-number">1</span>]) / <span class="hljs-number">2</span> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-built_in">len</span>(X_sum)-<span class="hljs-number">1</span>)] <span class="hljs-comment"># 紧邻均值序列</span><br><br> <span class="hljs-comment">############# 最小二乘法计算 ###############</span><br> Y = [X[i] <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">1</span>,<span class="hljs-built_in">len</span>(X))] <span class="hljs-comment">#生成数组Y</span><br> Y = np.array(Y) <span class="hljs-comment">#将数组转化为numpy数组</span><br> Y = Y.reshape(-<span class="hljs-number">1</span>,<span class="hljs-number">1</span>) <span class="hljs-comment">#转换格式</span><br><br> B = [-z_n[i] <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-built_in">len</span>(z_n))] <span class="hljs-comment">#生成数组B</span><br> B = np.array(B) <span class="hljs-comment">#将数组转化为numpy数组</span><br> B = B.reshape(-<span class="hljs-number">1</span>,<span class="hljs-number">1</span>) <span class="hljs-comment">#转换格式</span><br> c = np.ones((<span class="hljs-built_in">len</span>(B),<span class="hljs-number">1</span>)) <span class="hljs-comment">#生成数值全为1的一列数组</span><br> B = np.hstack((B,c)) <span class="hljs-comment">#将两者相连</span><br><br> parameters = np.linalg.inv(B.T.dot(B)).dot(B.T).dot(Y) <span class="hljs-comment"># 通过numpy求出参数(最小二乘法)</span><br> a = parameters[<span class="hljs-number">0</span>,<span class="hljs-number">0</span>] <span class="hljs-comment">#索引到a参数</span><br> b = parameters[<span class="hljs-number">1</span>,<span class="hljs-number">0</span>] <span class="hljs-comment">#索引到b参数</span><br> <span class="hljs-built_in">print</span>(<span class="hljs-string">"a="</span>,a) <span class="hljs-comment"># 打印结果</span><br> <span class="hljs-built_in">print</span>(<span class="hljs-string">"b="</span>,b)<br><br> <span class="hljs-comment">#生成预测模型##################################################### 要改在这改 ################################</span><br> b_a = b/a <span class="hljs-comment">#提前计算好常数项,减少后续程序的计算</span><br> model_predict = [(X[<span class="hljs-number">0</span>] - b_a) * np.exp(-a * k) + b_a <span class="hljs-keyword">for</span> k <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-built_in">len</span>(X)+form)] <span class="hljs-comment">#生成预测数列</span><br><br> list_predict = np.concatenate(([model_predict[<span class="hljs-number">0</span>]], np.diff(model_predict))) - sc <span class="hljs-comment"># 先累减获得预测数列,再做差得到真的预测序列</span><br><br> <span class="hljs-built_in">print</span>(<span class="hljs-string">"预测数列为:\n"</span>,list_predict)<br> list_predict = [<span class="hljs-built_in">float</span>(<span class="hljs-built_in">format</span>(i,<span class="hljs-string">'.4f'</span>)) <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> list_predict]<br> <span class="hljs-keyword">if</span> y == <span class="hljs-number">1</span>:<br> <span class="hljs-comment">##################################### 绘图 ####################################</span><br> fig = go.Figure()<br> fig.add_trace(go.Scatter(x=<span class="hljs-built_in">list</span>(<span class="hljs-built_in">range</span>(<span class="hljs-built_in">len</span>(X))),y=x_0, <span class="hljs-comment">#添加x,y</span><br> mode=<span class="hljs-string">"markers+lines+text"</span>,text=x_0,textposition=<span class="hljs-string">"top center"</span>, <span class="hljs-comment">#设置坐标点显示</span><br> name=<span class="hljs-string">'原数列'</span>)) <span class="hljs-comment">#设置标签名</span><br> fig.add_trace(go.Scatter(x=<span class="hljs-built_in">list</span>(<span class="hljs-built_in">range</span>(<span class="hljs-built_in">len</span>(X)+form)),y=list_predict, <span class="hljs-comment">#添加x,y</span><br> mode=<span class="hljs-string">"markers+lines+text"</span>,text=list_predict,textposition=<span class="hljs-string">"top center"</span>, <span class="hljs-comment">#设置坐标点显示</span><br> name=<span class="hljs-string">'预测数列'</span>)) <span class="hljs-comment">#设置标签名</span><br> fig.update_layout(title=<span class="hljs-string">"灰色预测"</span>, <span class="hljs-comment">#设置图表名</span><br> xaxis=<span class="hljs-built_in">dict</span>(title=<span class="hljs-string">"时间序号"</span>), <span class="hljs-comment">#设置x轴参数</span><br> yaxis=<span class="hljs-built_in">dict</span>(title=<span class="hljs-string">"值"</span>), <span class="hljs-comment">#设置y轴参数</span><br> title_x=<span class="hljs-number">0.5</span>, <span class="hljs-comment"># 将标题居中</span><br> title_y=<span class="hljs-number">0.94</span>, <span class="hljs-comment"># 将标题置于上方</span><br> template=<span class="hljs-string">"plotly"</span>)<br> fig.show()<br><br> <span class="hljs-comment">######################################## 模型检验 #######################################</span><br> G = np.array(list_predict[:<span class="hljs-built_in">len</span>(list_predict)-form]) <span class="hljs-comment">#生成与真实数列对应的预测数列</span><br> e = x_0 - G <span class="hljs-comment">#获得每一个预测值的残差</span><br> q = <span class="hljs-built_in">abs</span>(e / x_0) <span class="hljs-comment"># 获得每一个预测值的相对误差</span><br> <span class="hljs-built_in">print</span>(<span class="hljs-string">"相对误差数列为:\n"</span>,q)<br> q_q = q.<span class="hljs-built_in">sum</span>()/(<span class="hljs-built_in">len</span>(q)-<span class="hljs-number">1</span>) <span class="hljs-comment">#求得平均相对误差</span><br> <span class="hljs-built_in">print</span>(<span class="hljs-string">f"平均相对误差为:\n<span class="hljs-subst">{q_q:<span class="hljs-number">.4</span>f}</span>"</span>)<br><br> S0 = np.sqrt(np.var(x_0)) <span class="hljs-comment">#原数列的标准差</span><br> S1 = np.sqrt(np.var(e)) <span class="hljs-comment">#残差数列的标准差</span><br> <span class="hljs-built_in">print</span>(<span class="hljs-string">'后验差比值C为:\n'</span>,S1 / S0)<br><br> E = e.<span class="hljs-built_in">sum</span>()/(<span class="hljs-built_in">len</span>(e)-<span class="hljs-number">1</span>) <span class="hljs-comment">#计算残差的均值</span><br> yu_zhi = <span class="hljs-number">0.6745</span>*S0<br> g = <span class="hljs-number">0</span><br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-built_in">len</span>(e)):<br> <span class="hljs-keyword">if</span> <span class="hljs-built_in">abs</span>(e[i]-E) < yu_zhi:<br> g += <span class="hljs-number">1</span><br> p = g/<span class="hljs-built_in">len</span>(e)<br> <span class="hljs-built_in">print</span>(<span class="hljs-string">'小概率误差为:\n'</span>,p)<br><br> list_p = list_predict[-form:] <span class="hljs-comment">#获得我们预测的值</span><br> <span class="hljs-keyword">return</span> list_p<br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">grey_models</span>(<span class="hljs-params">x</span>):<br> av = np.array([np.mean(x[i]) <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-built_in">len</span>(x))]) <span class="hljs-comment">#求得每一个过程的平均值</span><br> av_predict = grey_model(av,<span class="hljs-number">1</span>,<span class="hljs-number">0</span>) <span class="hljs-comment">#求得预测过程的平均值</span><br> sum_predict = <span class="hljs-built_in">len</span>(x[<span class="hljs-number">0</span>]) * av_predict[<span class="hljs-number">0</span>] <span class="hljs-comment">#计算获得预测过程的总和</span><br> x_x = x.T <span class="hljs-comment">#将数组转置</span><br><br> pre = np.array([grey_model(x_x[i],<span class="hljs-number">1</span>,<span class="hljs-number">0</span>) <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-built_in">len</span>(x_x))]) <span class="hljs-comment">#获得每个过程同一时间在预测过程中的预测值</span><br> pre = pre.ravel()<br><br> c_predict = np.array(pre/<span class="hljs-built_in">sum</span>(pre)) <span class="hljs-comment">#获得预测过程每一个的预测占比</span><br> c_predict = c_predict.ravel()<br> predict = c_predict * sum_predict<br> <span class="hljs-keyword">return</span> predict<br><br>list_p = grey_model(X,<span class="hljs-number">3</span>,<span class="hljs-number">1</span>)<br><span class="hljs-built_in">print</span>(list_p)<br><span class="hljs-comment">#predict = grey_models(x)</span><br><span class="hljs-comment">#print(predict)</span><br></code></pre></td></tr></table></figure>]]></content>
<categories>
<category>数学建模</category>
</categories>
</entry>
<entry>
<title>结合熵权法的topsis客观评价代码</title>
<link href="/2024/09/11/%E7%BB%93%E5%90%88%E7%86%B5%E6%9D%83%E6%B3%95%E7%9A%84topsis%E5%AE%A2%E8%A7%82%E8%AF%84%E4%BB%B7/"/>
<url>/2024/09/11/%E7%BB%93%E5%90%88%E7%86%B5%E6%9D%83%E6%B3%95%E7%9A%84topsis%E5%AE%A2%E8%A7%82%E8%AF%84%E4%BB%B7/</url>
<content type="html"><![CDATA[<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">import</span> numpy <span class="hljs-keyword">as</span> np<br><span class="hljs-keyword">import</span> pandas <span class="hljs-keyword">as</span> pd<br>np.set_printoptions(threshold=np.inf) <span class="hljs-comment"># threshold 指定超过多少使用省略号,np.inf代表无限大</span><br>np.set_printoptions(suppress=<span class="hljs-literal">True</span>) <span class="hljs-comment">#不以科学计数法输出</span><br><br><span class="hljs-comment">#导入数据</span><br>data = pd.read_excel(<span class="hljs-string">'收发货表格.xlsx'</span>,usecols=[<span class="hljs-string">'发货'</span>,<span class="hljs-string">'收货'</span>,<span class="hljs-string">'总运输'</span>,<span class="hljs-string">'发斜'</span>,<span class="hljs-string">'收斜'</span>,<span class="hljs-string">'平均相关性'</span>,<span class="hljs-string">'发货城市'</span>,<span class="hljs-string">'收货城市'</span>,<span class="hljs-string">'连接数'</span>])<br>x_data = np.array(data)<br><br><span class="hljs-comment">#正向化</span><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">positive</span>(<span class="hljs-params">x, <span class="hljs-built_in">type</span>, best_value=<span class="hljs-literal">None</span>, a=<span class="hljs-literal">None</span>, b=<span class="hljs-literal">None</span></span>):<br> <span class="hljs-string">'''</span><br><span class="hljs-string"> :param x: 原始数据</span><br><span class="hljs-string"> :param type: 1表示极小型,2表示中间型,3表示区间型,4表示正数话,[[,1],[,2],[,3]]前面是需要正向化的列的序号</span><br><span class="hljs-string"> :param best_value: 中间型的最优值</span><br><span class="hljs-string"> :param a: 区间型的区间下限</span><br><span class="hljs-string"> :param b: 区间型的区间上限</span><br><span class="hljs-string"> :return: 正向化后的数据(列)</span><br><span class="hljs-string"> '''</span><br> <span class="hljs-keyword">if</span> <span class="hljs-built_in">type</span> == <span class="hljs-literal">None</span>: <span class="hljs-comment">#先判断是否需要正向化</span><br> <span class="hljs-keyword">pass</span><br> <span class="hljs-keyword">else</span>:<br> x = x.T <span class="hljs-comment">#转置</span><br> m = np.array(<span class="hljs-built_in">type</span>).shape[<span class="hljs-number">0</span>] <span class="hljs-comment">#获得需要正向化的列数</span><br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-built_in">int</span>(m)): <span class="hljs-comment">#迭代需要正向化的列</span><br> <span class="hljs-keyword">if</span> <span class="hljs-built_in">type</span>[i][<span class="hljs-number">1</span>] == <span class="hljs-number">1</span>: <span class="hljs-comment">#成本型数据的转化,采用max-x</span><br> x[<span class="hljs-built_in">type</span>[i][<span class="hljs-number">0</span>]] = x[<span class="hljs-built_in">type</span>[i][<span class="hljs-number">0</span>]].<span class="hljs-built_in">max</span>(<span class="hljs-number">0</span>)-x[<span class="hljs-built_in">type</span>[i][<span class="hljs-number">0</span>]]<br> <span class="hljs-keyword">elif</span> <span class="hljs-built_in">type</span>[i][<span class="hljs-number">1</span>] == <span class="hljs-number">2</span>: <span class="hljs-comment">#中间型数据的转化</span><br> max_value = (<span class="hljs-built_in">abs</span>(x[<span class="hljs-built_in">type</span>[i][<span class="hljs-number">0</span>]] - best_value)).<span class="hljs-built_in">max</span>()<br> x[<span class="hljs-built_in">type</span>[i][<span class="hljs-number">0</span>]] = <span class="hljs-number">1</span> - <span class="hljs-built_in">abs</span>(x[<span class="hljs-built_in">type</span>[i][<span class="hljs-number">0</span>]] - best_value) / max_value<br> <span class="hljs-keyword">elif</span> <span class="hljs-built_in">type</span>[i][<span class="hljs-number">1</span>] == <span class="hljs-number">3</span>: <span class="hljs-comment">#区间型数据的转化</span><br> max_value = (np.append(a-x[<span class="hljs-built_in">type</span>[i][<span class="hljs-number">0</span>]].<span class="hljs-built_in">min</span>(),x[<span class="hljs-built_in">type</span>[i][<span class="hljs-number">0</span>]].<span class="hljs-built_in">max</span>()-b)).<span class="hljs-built_in">max</span>() <span class="hljs-comment">#即M,后面转换时的分母</span><br> x_rows = x[<span class="hljs-built_in">type</span>[i][<span class="hljs-number">0</span>]].shape[<span class="hljs-number">0</span>]<br> <span class="hljs-keyword">for</span> v <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(x_rows):<br> <span class="hljs-keyword">if</span> x[<span class="hljs-built_in">type</span>[i][<span class="hljs-number">0</span>]][v] > b: <span class="hljs-comment">#当数据大于区间最大值的转换</span><br> x[<span class="hljs-built_in">type</span>[i][<span class="hljs-number">0</span>]][v] = <span class="hljs-number">1</span>-(x[<span class="hljs-built_in">type</span>[i][<span class="hljs-number">0</span>]][v]-b)/max_value<br> <span class="hljs-keyword">elif</span> x[<span class="hljs-built_in">type</span>[i][<span class="hljs-number">0</span>]][v] < a: <span class="hljs-comment">#当数据小于区间最小值的转换</span><br> x[<span class="hljs-built_in">type</span>[i][<span class="hljs-number">0</span>]][v] = <span class="hljs-number">1</span>-(a-x[<span class="hljs-built_in">type</span>[i][<span class="hljs-number">0</span>]][v])/max_value<br> <span class="hljs-keyword">elif</span> a <= x[<span class="hljs-built_in">type</span>[i][<span class="hljs-number">0</span>]][v] <= b: <span class="hljs-comment">#当数据在区间内则给予最优值1</span><br> x[<span class="hljs-built_in">type</span>[i][<span class="hljs-number">0</span>]][v] = <span class="hljs-number">1</span><br> <span class="hljs-keyword">else</span>: <span class="hljs-comment">#其它情况则给予最劣值0</span><br> x[<span class="hljs-built_in">type</span>[i][<span class="hljs-number">0</span>]][v] = <span class="hljs-number">0</span><br> <span class="hljs-keyword">elif</span> <span class="hljs-built_in">type</span>[i][<span class="hljs-number">1</span>] == <span class="hljs-number">4</span>: <span class="hljs-comment">#极大型负数的转换</span><br> x[<span class="hljs-built_in">type</span>[i][<span class="hljs-number">0</span>]] = <span class="hljs-number">1</span>-(x[<span class="hljs-built_in">type</span>[i][<span class="hljs-number">0</span>]].<span class="hljs-built_in">min</span>(<span class="hljs-number">0</span>)) + x[<span class="hljs-built_in">type</span>[i][<span class="hljs-number">0</span>]]<br> <span class="hljs-keyword">return</span> x.T<br><br><span class="hljs-comment">#标准化</span><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">normalize</span>(<span class="hljs-params">x</span>):<br> sqrt_sum = (x * x).<span class="hljs-built_in">sum</span>(axis=<span class="hljs-number">0</span>) <span class="hljs-comment">#每一列元素的平方和</span><br> sqt_sum_z = np.tile(sqrt_sum, (x.shape[<span class="hljs-number">0</span>], <span class="hljs-number">1</span>)) <span class="hljs-comment">#转换格式,每一列的值均为当列的元素平方和</span><br> Z = x / np.sqrt(sqt_sum_z) <span class="hljs-comment">#标准化</span><br> <span class="hljs-keyword">return</span> Z<br><br><span class="hljs-comment">#熵权法计算权值</span><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">importance</span>(<span class="hljs-params">data</span>):<br> l = <span class="hljs-built_in">len</span>(data[<span class="hljs-number">0</span>])<br> h = [<span class="hljs-number">0</span>]*l<br> w = [<span class="hljs-number">0</span>]*l<br> data = data.T<br> <span class="hljs-keyword">for</span> v <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(l):<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-built_in">len</span>(data[<span class="hljs-number">0</span>])):<br> <span class="hljs-keyword">if</span> data[v][i] == <span class="hljs-number">0</span>:<br> <span class="hljs-keyword">pass</span><br> <span class="hljs-keyword">else</span>:<br> h[v] += -data[v][i] * np.log(data[v][i])/np.log(<span class="hljs-built_in">len</span>(data[<span class="hljs-number">0</span>])) <span class="hljs-comment">#计算每个指标的信息熵值</span><br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(l):<br> w[i] = (<span class="hljs-number">1</span>-h[i])/(<span class="hljs-built_in">len</span>(data)-<span class="hljs-built_in">sum</span>(h)) <span class="hljs-comment">#计算每个指标的权重</span><br> <span class="hljs-keyword">return</span> w<br><span class="hljs-comment">#topsis算法</span><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">topsis</span>(<span class="hljs-params">z,h</span>):<br> z_max = z.<span class="hljs-built_in">max</span>(<span class="hljs-number">0</span>) <span class="hljs-comment">#每一列的最大值与最小值</span><br> z_min = z.<span class="hljs-built_in">min</span>(<span class="hljs-number">0</span>)<br><br> d_m = z - np.tile(z_max, (z.shape[<span class="hljs-number">0</span>], <span class="hljs-number">1</span>)) <span class="hljs-comment">#每个方案与最优解及最劣解的差值数列</span><br> d_i = z - np.tile(z_min, (z.shape[<span class="hljs-number">0</span>], <span class="hljs-number">1</span>))<br><br> d_i_max = np.sqrt(((h * d_m) ** <span class="hljs-number">2</span>).<span class="hljs-built_in">sum</span>(axis=<span class="hljs-number">1</span>)) <span class="hljs-comment">#每个方案的综合距离</span><br> d_i_min = np.sqrt(((h * d_i) ** <span class="hljs-number">2</span>).<span class="hljs-built_in">sum</span>(axis=<span class="hljs-number">1</span>))<br><br> score = d_i_min/(d_i_max + d_i_min) <span class="hljs-comment">#每个方案的评分</span><br> std_score = score / score.<span class="hljs-built_in">sum</span>(axis=<span class="hljs-number">0</span>) <span class="hljs-comment">#归一化,方便查看</span><br> <span class="hljs-keyword">return</span> std_score<br><br><span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">"__main__"</span>:<br> <span class="hljs-comment">#正向化,如果不需要则为空列表即可,要求都为正向化且数据都大于0</span><br> <span class="hljs-built_in">type</span> = [[<span class="hljs-number">3</span>,<span class="hljs-number">4</span>],[<span class="hljs-number">4</span>,<span class="hljs-number">4</span>],[<span class="hljs-number">1</span>,<span class="hljs-number">4</span>],[<span class="hljs-number">7</span>,<span class="hljs-number">4</span>]]<br> a = positive(x_data,<span class="hljs-built_in">type</span>,best_value=<span class="hljs-literal">None</span>, a=<span class="hljs-literal">None</span>, b=<span class="hljs-literal">None</span>)<br> <span class="hljs-comment">#标准化</span><br> b = normalize(a)<br> <span class="hljs-comment">#信息熵计算</span><br> h = importance(b)<br> <span class="hljs-comment">#topsis评价</span><br> s = topsis(b,h)<br> <span class="hljs-comment">#将评价与方案连接,方便对比与观察</span><br> clo = np.array([<span class="hljs-string">'A'</span>,<span class="hljs-string">'B'</span>,<span class="hljs-string">'C'</span>,<span class="hljs-string">'D'</span>,<span class="hljs-string">'E'</span>,<span class="hljs-string">'G'</span>,<span class="hljs-string">'H'</span>,<span class="hljs-string">'I'</span>,<span class="hljs-string">'J'</span>,<span class="hljs-string">'K'</span>,<span class="hljs-string">'L'</span>,<span class="hljs-string">'M'</span>,<span class="hljs-string">'N'</span>,<span class="hljs-string">'O'</span>,<span class="hljs-string">'P'</span>,<span class="hljs-string">'Q'</span>,<span class="hljs-string">'R'</span>,<span class="hljs-string">'S'</span>,<span class="hljs-string">'T'</span>,<span class="hljs-string">'U'</span>,<span class="hljs-string">'V'</span>,<span class="hljs-string">'W'</span>,<span class="hljs-string">'X'</span>,<span class="hljs-string">'Y'</span>])<br> lianjie_list = []<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-built_in">len</span>(s)):<br> lianjie_list.append([clo[i], s[i]])<br> jieguo = <span class="hljs-built_in">sorted</span>(lianjie_list,reverse=<span class="hljs-literal">True</span>, key=<span class="hljs-keyword">lambda</span> x: x[<span class="hljs-number">1</span>]) <span class="hljs-comment">#根据评分值进行排序</span><br> <span class="hljs-built_in">print</span>(jieguo)<br><br></code></pre></td></tr></table></figure>]]></content>
<categories>
<category>数学建模</category>
</categories>
</entry>
<entry>
<title>排队论模型代码</title>
<link href="/2024/09/11/%E6%8E%92%E9%98%9F%E8%AE%BA%E6%A8%A1%E5%9E%8B%E4%BB%A3%E7%A0%81/"/>
<url>/2024/09/11/%E6%8E%92%E9%98%9F%E8%AE%BA%E6%A8%A1%E5%9E%8B%E4%BB%A3%E7%A0%81/</url>
<content type="html"><![CDATA[<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">import</span> math<br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">mm1_model</span>(<span class="hljs-params">lamb_da, miu, n=<span class="hljs-number">0</span></span>):<br> rou = lamb_da / miu<br> W_s = <span class="hljs-number">1</span> / (miu - lamb_da)<br> W_q = rou / (miu - lamb_da)<br> L_s = lamb_da * W_s<br> L_q = lamb_da * W_q<br> P_n = (<span class="hljs-number">1</span>-rou)*(rou**n)<br> <span class="hljs-keyword">return</span> {<br> <span class="hljs-string">'服务强度'</span>: rou,<br> <span class="hljs-string">'平均队长'</span>: L_s,<br> <span class="hljs-string">'平均队列长'</span>: L_q,<br> <span class="hljs-string">'平均逗留时间'</span>: W_s,<br> <span class="hljs-string">'平均等待时间'</span>: W_q,<br> <span class="hljs-string">f'系统稳定有<span class="hljs-subst">{n}</span>个顾客的概率'</span>:P_n<br> }<br><span class="hljs-keyword">def</span> <span class="hljs-title function_">mm1N_model</span>(<span class="hljs-params">lamb_da, miu, N, n=<span class="hljs-number">0</span></span>):<br> <span class="hljs-string">'''</span><br><span class="hljs-string"> 损失制:当顾客到达时,队列达到N,顾客随即离去。</span><br><span class="hljs-string"> '''</span><br> rou = lamb_da / miu<br> P_N = (<span class="hljs-number">1</span>-rou)*(rou**N)/(<span class="hljs-number">1</span>-rou**(N+<span class="hljs-number">1</span>))<br> lamb_da_e = lamb_da*(<span class="hljs-number">1</span>-P_N)<br> rou_e = lamb_da_e / miu<br> L_s = <span class="hljs-number">1</span>/(<span class="hljs-number">1</span>-rou) - ((N+<span class="hljs-number">1</span>)*rou**(N+<span class="hljs-number">1</span>))/(<span class="hljs-number">1</span>-rou**(N+<span class="hljs-number">1</span>))<br> L_q = L_s - rou_e<br> W_s = L_s/lamb_da_e<br> W_q = L_q/lamb_da_e<br> P_n = (<span class="hljs-number">1</span>-rou)*(rou**n)/(<span class="hljs-number">1</span>-rou**(N+<span class="hljs-number">1</span>))<br> <span class="hljs-keyword">return</span> {<br> <span class="hljs-string">'有效服务强度'</span>: rou_e,<br> <span class="hljs-string">'平均队长'</span>: L_s,<br> <span class="hljs-string">'平均队列长'</span>: L_q,<br> <span class="hljs-string">'平均逗留时间'</span>: W_s,<br> <span class="hljs-string">'平均等待时间'</span>: W_q,<br> <span class="hljs-string">f'系统稳定有<span class="hljs-subst">{n}</span>个顾客的概率'</span>:P_n<br> }<br><span class="hljs-keyword">def</span> <span class="hljs-title function_">mm1_m_model</span>(<span class="hljs-params">lamb_da, miu, m, n=<span class="hljs-number">0</span></span>):<br> <span class="hljs-string">'''</span><br><span class="hljs-string"> 这里的lamb_da定义为每个顾客的到达率</span><br><span class="hljs-string"> '''</span><br> rou = lamb_da / miu<br> P_0 = <span class="hljs-number">1</span>/<span class="hljs-built_in">sum</span>(math.factorial(m)/math.factorial(m-i)*rou**i<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">0</span>,m+<span class="hljs-number">1</span>))<br> W_s = m/(miu*(<span class="hljs-number">1</span>-P_0)) - <span class="hljs-number">1</span>/lamb_da<br> W_q = W_s - <span class="hljs-number">1</span>/miu<br> L_s = m - (miu/lamb_da)*(<span class="hljs-number">1</span>-P_0)<br> L_q = L_s - (<span class="hljs-number">1</span>-P_0)<br> <span class="hljs-keyword">if</span> n == <span class="hljs-number">0</span>:<br> P_n = P_0<br> <span class="hljs-keyword">else</span>:<br> P_n = math.factorial(m)/math.factorial(m-n)*rou**n * P_0<br> <span class="hljs-keyword">return</span> {<br> <span class="hljs-string">'服务强度'</span>: rou,<br> <span class="hljs-string">'平均队长'</span>: L_s,<br> <span class="hljs-string">'平均队列长'</span>: L_q,<br> <span class="hljs-string">'平均逗留时间'</span>: W_s,<br> <span class="hljs-string">'平均等待时间'</span>: W_q,<br> <span class="hljs-string">f'系统稳定有<span class="hljs-subst">{n}</span>个顾客的概率'</span>:P_n<br> }<br><span class="hljs-keyword">def</span> <span class="hljs-title function_">mmc_model</span>(<span class="hljs-params">lamb_da, miu, c, n=<span class="hljs-number">0</span></span>):<br> rou = lamb_da / (miu*c)<br> P_0 = <span class="hljs-number">1</span>/(<span class="hljs-built_in">sum</span>(<span class="hljs-number">1</span>/math.factorial(i)*(rou*c)**i<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">0</span>,c-<span class="hljs-number">1</span>))<br> +<span class="hljs-number">1</span>/(math.factorial(c)*(<span class="hljs-number">1</span>-rou))*(rou*c)**c)<br> L_q = P_0*(rou*c)**c*rou/(math.factorial(c)*(<span class="hljs-number">1</span>+rou)**<span class="hljs-number">2</span>)<br> L_s = L_q + rou*c<br> W_s = L_s / lamb_da<br> W_q = L_q / lamb_da<br> <span class="hljs-keyword">if</span> n == <span class="hljs-number">0</span>:<br> P_n = P_0<br> <span class="hljs-keyword">elif</span> n<=c:<br> P_n = P_0*(rou*c)**n / math.factorial(n)<br> <span class="hljs-keyword">else</span>:<br> P_n = P_0*(rou*c)**n / (math.factorial(c)*c**(n-c))<br> <span class="hljs-keyword">return</span> {<br> <span class="hljs-string">'服务强度'</span>: rou,<br> <span class="hljs-string">'平均队长'</span>: L_s,<br> <span class="hljs-string">'平均队列长'</span>: L_q,<br> <span class="hljs-string">'平均逗留时间'</span>: W_s,<br> <span class="hljs-string">'平均等待时间'</span>: W_q,<br> <span class="hljs-string">f'系统稳定有<span class="hljs-subst">{n}</span>个顾客的概率'</span>:P_n<br> }<br><span class="hljs-keyword">def</span> <span class="hljs-title function_">mmcN_model</span>(<span class="hljs-params">lamb_da, miu, c, N, n=<span class="hljs-number">0</span></span>):<br> rou = lamb_da / (miu*c)<br> <span class="hljs-keyword">if</span> rou == <span class="hljs-number">1</span>:<br> P_0 = <span class="hljs-built_in">sum</span>(c**i/math.factorial(i) <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">0</span>,c))\<br> +(N-c+<span class="hljs-number">1</span>)*c**c/math.factorial(c)<br> <span class="hljs-keyword">else</span>:<br> P_0 =<span class="hljs-number">1</span>/(<span class="hljs-built_in">sum</span>(c*rou**i/math.factorial(i) <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">0</span>,c))\<br> +(rou*(rou**c-rou**N)/(<span class="hljs-number">1</span>-rou))*c**c/math.factorial(c))<br> <span class="hljs-keyword">if</span> n<=c:<br> P_n = P_0*(rou*c)**n / math.factorial(n)<br> <span class="hljs-keyword">elif</span> n>c <span class="hljs-keyword">and</span> n<=N:<br> P_n = P_0 * c**c * rou**n / math.factorial(c)<br> L_q = <span class="hljs-number">0</span><br> P_N = P_0 * c**c * rou**N / math.factorial(c)<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">1</span>,N-c+<span class="hljs-number">1</span>):<br> L_q += i*P_N<br> L_s = L_q + rou*c*(<span class="hljs-number">1</span>-P_N)<br> W_q = L_q / (lamb_da*(<span class="hljs-number">1</span>-P_N))<br> W_s = W_q + <span class="hljs-number">1</span>/miu<br> <span class="hljs-keyword">return</span> {<br> <span class="hljs-string">'服务强度'</span>: rou,<br> <span class="hljs-string">'平均队长'</span>: L_s,<br> <span class="hljs-string">'平均队列长'</span>: L_q,<br> <span class="hljs-string">'平均逗留时间'</span>: W_s,<br> <span class="hljs-string">'平均等待时间'</span>: W_q,<br> <span class="hljs-string">f'系统稳定有<span class="hljs-subst">{n}</span>个顾客的概率'</span>: P_n<br> }<br><span class="hljs-keyword">def</span> <span class="hljs-title function_">mmc_m_model</span>(<span class="hljs-params">lamb_da, miu, c, m, n=<span class="hljs-number">0</span></span>):<br> <span class="hljs-string">'''</span><br><span class="hljs-string"> n应该要大于c,不然概率可能大于1.</span><br><span class="hljs-string"> 因为有时每个服务台都会有人。</span><br><span class="hljs-string"> '''</span><br> rou = m*lamb_da / (miu*c)<br> P_0 =<span class="hljs-number">1</span>/((<span class="hljs-built_in">sum</span>((c*rou/m)**i/(math.factorial(i)*math.factorial(m-i)) <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">0</span>,c+<span class="hljs-number">1</span>))\<br> +<span class="hljs-built_in">sum</span>(c**c*(rou/m)**i/(math.factorial(m-i)*math.factorial(c)) <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">0</span>,c+<span class="hljs-number">1</span>)))\<br> *math.factorial(m))<br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">P</span>(<span class="hljs-params">P_0, lamb_da, miu, c, m, n=<span class="hljs-number">0</span></span>):<br> <span class="hljs-keyword">if</span> n<=c:<br> P_n = (P_0*((lamb_da/miu)**n)*math.factorial(m) /<br> (math.factorial(n)*math.factorial(m-n)))<br> <span class="hljs-keyword">elif</span> n>c <span class="hljs-keyword">and</span> n<=m:<br> P_n = (P_0*(lamb_da/miu)**n*math.factorial(m) /<br> (math.factorial(c)*math.factorial(m-n)*c**(n-c)))<br> <span class="hljs-keyword">return</span> P_n<br> P_n = P(P_0, lamb_da, miu, c, m, n)<br> L_q = <span class="hljs-built_in">sum</span>(i*P(P_0, lamb_da, miu, c, m, i) <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">1</span>,m-c+<span class="hljs-number">1</span>))<br> L_s = <span class="hljs-built_in">sum</span>(i*P(P_0, lamb_da, miu, c, m, i) <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">1</span>,m+<span class="hljs-number">1</span>))<br> lamb_da_e = lamb_da * (m-L_s)<br> W_s = L_s/lamb_da_e<br> W_q = L_q/lamb_da_e<br> <span class="hljs-keyword">return</span> {<br> <span class="hljs-string">'服务强度'</span>: rou,<br> <span class="hljs-string">'平均队长'</span>: L_s,<br> <span class="hljs-string">'平均队列长'</span>: L_q,<br> <span class="hljs-string">'平均逗留时间'</span>: W_s,<br> <span class="hljs-string">'平均等待时间'</span>: W_q,<br> <span class="hljs-string">f'系统稳定有<span class="hljs-subst">{n}</span>个顾客的概率'</span>: P_n<br> }<br><span class="hljs-comment"># 输入模拟参数</span><br>lamb_da = <span class="hljs-number">0.8</span> <span class="hljs-comment"># 平均到达速率</span><br>miu = <span class="hljs-number">0.6</span> <span class="hljs-comment"># 平均服务速率</span><br>c = <span class="hljs-number">10</span> <span class="hljs-comment"># 服务台数量 ,需要小于m</span><br>N = <span class="hljs-number">5</span> <span class="hljs-comment"># 队列(排队)容量</span><br>m = <span class="hljs-number">10</span> <span class="hljs-comment"># 顾客源总数</span><br><br>results = mmc_m_model(lamb_da, miu, c, m, <span class="hljs-number">5</span>)<br><span class="hljs-keyword">for</span> key, value <span class="hljs-keyword">in</span> results.items():<br> <span class="hljs-built_in">print</span>(<span class="hljs-string">f"<span class="hljs-subst">{key}</span>: <span class="hljs-subst">{value:<span class="hljs-number">.6</span>f}</span>"</span>)<br><br></code></pre></td></tr></table></figure>]]></content>
<categories>
<category>数学建模</category>
</categories>
</entry>
<entry>
<title>粒子群算法代码</title>
<link href="/2024/09/11/%E7%B2%92%E5%AD%90%E7%BE%A4%E7%AE%97%E6%B3%95%E4%BB%A3%E7%A0%81/"/>
<url>/2024/09/11/%E7%B2%92%E5%AD%90%E7%BE%A4%E7%AE%97%E6%B3%95%E4%BB%A3%E7%A0%81/</url>
<content type="html"><![CDATA[<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">import</span> numpy <span class="hljs-keyword">as</span> np<br><span class="hljs-keyword">import</span> matplotlib.pyplot <span class="hljs-keyword">as</span> plt<br><span class="hljs-keyword">import</span> warnings<br>warnings.filterwarnings(<span class="hljs-string">"ignore"</span>)<br>plt.rcParams[<span class="hljs-string">'axes.unicode_minus'</span>] = <span class="hljs-literal">False</span> <span class="hljs-comment">#显示负号</span><br>plt.rcParams[<span class="hljs-string">'font.family'</span>] = [<span class="hljs-string">'sans-serif'</span>]<br>plt.rcParams[<span class="hljs-string">'font.sans-serif'</span>] = [<span class="hljs-string">'SimHei'</span>] <span class="hljs-comment"># 散点图标签可以显示中文</span><br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">Objective_function</span>(<span class="hljs-params">X</span>): <span class="hljs-comment"># 目标函数和约束条件 最小化</span><br> X = X.flatten() <span class="hljs-comment">#将X变为一维数组</span><br> x1 = X[<span class="hljs-number">0</span>]<br> x2 = X[<span class="hljs-number">1</span>]<br> x3 = X[<span class="hljs-number">2</span>]<br> p1 = (<span class="hljs-built_in">max</span>(<span class="hljs-number">0</span>, <span class="hljs-number">6</span> * x1 + <span class="hljs-number">5</span> * x2 - <span class="hljs-number">60</span>)) ** <span class="hljs-number">2</span> <span class="hljs-comment">#表达的含义是函数表达式小于0</span><br> p2 = (<span class="hljs-built_in">max</span>(<span class="hljs-number">0</span>, <span class="hljs-number">10</span> * x1 + <span class="hljs-number">20</span> * x2 - <span class="hljs-number">150</span>)) ** <span class="hljs-number">2</span><br> <span class="hljs-comment">#如果是等式约束,可以转化成表达式=0,然后目标函数-10000*表达式</span><br> fx = <span class="hljs-number">100.0</span> * (x2 - x1) ** <span class="hljs-number">2.0</span> + (<span class="hljs-number">1</span> - x1) ** <span class="hljs-number">2.0</span> * x3<br> <span class="hljs-keyword">return</span> fx + <span class="hljs-number">10000</span> * (p1 + p2) <span class="hljs-comment">#施加惩罚项</span><br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">main_work</span>():<br> <span class="hljs-comment"># ( 粒子个数, 最大迭代次数,x_min,x_max, max_vel, 阈值, C1=2, C2=2, W=1) 范围都是左闭右开</span><br> pso = PSO(<span class="hljs-number">10</span>, <span class="hljs-number">10000</span>,[[-<span class="hljs-number">30</span>,-<span class="hljs-number">30</span>],[-<span class="hljs-number">1</span>],[]],[[<span class="hljs-number">30</span>,<span class="hljs-number">30</span>],[<span class="hljs-number">1</span>],[]], <span class="hljs-number">30</span>, -<span class="hljs-number">1000</span>, C1=<span class="hljs-number">1</span>, C2=<span class="hljs-number">2</span>, W=<span class="hljs-number">1</span>)<br> fit_var_list, best_pos = pso.update_ndim()<br> <span class="hljs-built_in">print</span>(<span class="hljs-string">"最优位置:"</span> + <span class="hljs-built_in">str</span>(best_pos))<br> <span class="hljs-built_in">print</span>(<span class="hljs-string">f"最优解为:<span class="hljs-subst">{fit_var_list[-<span class="hljs-number">1</span>]:<span class="hljs-number">.9</span>f}</span>"</span>)<br> plt.title(<span class="hljs-string">'粒子群'</span>)<br> plt.plot([i <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">1</span>,<span class="hljs-built_in">len</span>(fit_var_list)+<span class="hljs-number">1</span>)],fit_var_list, color=<span class="hljs-string">'r'</span>)<br> plt.show()<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">particle</span>:<br> <span class="hljs-comment"># 初始化</span><br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">__init__</span>(<span class="hljs-params">self, x_min, x_max, max_vel, dim</span>):<br> pos = np.zeros((dim))<br> self.l1 = <span class="hljs-built_in">len</span>(x_min[<span class="hljs-number">0</span>])<br> self.l2 = <span class="hljs-built_in">len</span>(x_min[<span class="hljs-number">0</span>]+x_min[<span class="hljs-number">1</span>])<br> <span class="hljs-keyword">for</span> v <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(dim): <span class="hljs-comment">#生成初始解</span><br> <span class="hljs-keyword">if</span> v < self.l1:<br> pos[v] = np.random.uniform(x_min[<span class="hljs-number">0</span>][v], x_max[<span class="hljs-number">0</span>][v]) <span class="hljs-comment">#有理数</span><br> <span class="hljs-keyword">elif</span> v >= self.l1 <span class="hljs-keyword">and</span> v < self.l2:<br> pos[v] = np.random.randint(x_min[<span class="hljs-number">1</span>][v-self.l1], x_max[<span class="hljs-number">1</span>][v-self.l1]+<span class="hljs-number">1</span>) <span class="hljs-comment">#整数</span><br> <span class="hljs-keyword">else</span>:<br> pos[v] = np.random.randint(<span class="hljs-number">0</span>,<span class="hljs-number">2</span>) <span class="hljs-comment">#0-1变量</span><br> self.__pos = np.array(pos) <span class="hljs-comment"># 粒子的位置</span><br> self.__vel = np.random.uniform(-max_vel, max_vel, (<span class="hljs-number">1</span>, dim)) <span class="hljs-comment"># 粒子的速度</span><br> self.__bestPos = np.zeros((<span class="hljs-number">1</span>, dim)) <span class="hljs-comment"># 粒子最好的位置</span><br> self.__fitnessValue = Objective_function(self.__pos) <span class="hljs-comment"># 适应度函数值</span><br><span class="hljs-comment">#__开头的为私有属性,只在类内存在</span><br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">set_pos</span>(<span class="hljs-params">self, value</span>):<br> pos = np.array(value).ravel()<br> self.__pos = pos<br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">get_pos</span>(<span class="hljs-params">self</span>):<br> <span class="hljs-keyword">return</span> self.__pos<br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">set_best_pos</span>(<span class="hljs-params">self, value</span>):<br> self.__bestPos = value<br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">get_best_pos</span>(<span class="hljs-params">self</span>):<br> <span class="hljs-keyword">return</span> self.__bestPos<br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">set_vel</span>(<span class="hljs-params">self, value</span>):<br> self.__vel = value<br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">get_vel</span>(<span class="hljs-params">self</span>):<br> <span class="hljs-keyword">return</span> self.__vel<br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">set_fitness_value</span>(<span class="hljs-params">self, value</span>):<br> self.__fitnessValue = value<br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">get_fitness_value</span>(<span class="hljs-params">self</span>):<br> <span class="hljs-keyword">return</span> self.__fitnessValue<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">PSO</span>:<br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">__init__</span>(<span class="hljs-params">self, size, iter_num, x_min,x_max, max_vel, tol, best_fitness_value=<span class="hljs-built_in">float</span>(<span class="hljs-params"><span class="hljs-string">'Inf'</span></span>), C1=<span class="hljs-number">2</span>, C2=<span class="hljs-number">2</span>, W=<span class="hljs-number">1</span></span>):<br> self.C1 = C1 <span class="hljs-comment">#加速常数1,控制局部最优解</span><br> self.C2 = C2 <span class="hljs-comment">#加速常数2,控制全局最优解</span><br> self.W = W <span class="hljs-comment">#惯性因子</span><br> self.dim = <span class="hljs-built_in">len</span>(np.array(x_min).ravel()) <span class="hljs-comment"># 粒子的维度,变量个数</span><br> self.size = size <span class="hljs-comment"># 粒子个数</span><br> self.iter_num = iter_num <span class="hljs-comment"># 迭代次数</span><br> self.x_min = x_min <span class="hljs-comment">#x 的下限</span><br> self.x_max = x_max <span class="hljs-comment"># x 的上限</span><br> self.max_vel = max_vel <span class="hljs-comment"># 粒子最大速度</span><br> self.tol = tol <span class="hljs-comment"># 截止条件</span><br> self.l1 = <span class="hljs-built_in">len</span>(x_min[<span class="hljs-number">0</span>])<br> self.l2 = <span class="hljs-built_in">len</span>(x_min[<span class="hljs-number">0</span>]+x_min[<span class="hljs-number">1</span>])<br> self.best_fitness_value = best_fitness_value<br> self.best_position = np.zeros((<span class="hljs-number">1</span>, self.dim)) <span class="hljs-comment"># 种群最优位置</span><br> self.fitness_val_list = [] <span class="hljs-comment"># 每次迭代最优适应值</span><br> <span class="hljs-comment"># 对种群进行初始化</span><br> self.Particle_list = [particle(self.x_min,self.x_max, self.max_vel, self.dim) <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(self.size)]<br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">set_bestFitnessValue</span>(<span class="hljs-params">self, value</span>):<br> self.best_fitness_value = value<br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">get_bestFitnessValue</span>(<span class="hljs-params">self</span>):<br> <span class="hljs-keyword">return</span> self.best_fitness_value<br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">set_bestPosition</span>(<span class="hljs-params">self, value</span>):<br> self.best_position = value<br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">get_bestPosition</span>(<span class="hljs-params">self</span>):<br> <span class="hljs-keyword">return</span> self.best_position<br> <span class="hljs-comment"># 更新速度</span><br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">update_vel</span>(<span class="hljs-params">self, part</span>):<br> vel_value = self.W * part.get_vel() + self.C1 * np.random.rand() * (part.get_best_pos() - part.get_pos()) \<br> + self.C2 * np.random.rand() * (self.get_bestPosition() - part.get_pos())<br> vel_value[vel_value > self.max_vel] = self.max_vel<br> vel_value[vel_value < -self.max_vel] = -self.max_vel<br> part.set_vel(vel_value)<br> <span class="hljs-comment"># 更新位置</span><br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">update_pos</span>(<span class="hljs-params">self, part</span>):<br> pos_value = part.get_pos() + part.get_vel()<br> pos_value = np.array(pos_value).ravel()<br> <span class="hljs-keyword">for</span> v <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-built_in">len</span>(pos_value)): <span class="hljs-comment">#生成初始解</span><br> <span class="hljs-keyword">if</span> v < self.l1:<br> pos_value[v] = <span class="hljs-built_in">max</span>(<span class="hljs-built_in">min</span>(pos_value[v], self.x_max[<span class="hljs-number">0</span>][v]), self.x_min[<span class="hljs-number">0</span>][v]) <span class="hljs-comment"># 保证新解在 [min,max] 范围内</span><br> <span class="hljs-keyword">elif</span> v >= self.l1 <span class="hljs-keyword">and</span> v < self.l2:<br> pos_value[v] = <span class="hljs-built_in">max</span>(<span class="hljs-built_in">min</span>(pos_value[v], self.x_max[<span class="hljs-number">1</span>][v-self.l1]), self.x_min[<span class="hljs-number">1</span>][v-self.l1]) <span class="hljs-comment"># 保证新解在 [min,max] 范围内</span><br> <span class="hljs-keyword">else</span>:<br> pos_value[v] = <span class="hljs-built_in">max</span>(<span class="hljs-built_in">min</span>(pos_value[v], self.x_max[<span class="hljs-number">1</span>][v-self.l2]), self.x_min[<span class="hljs-number">1</span>][v-self.l2]) <span class="hljs-comment"># 保证新解在 [min,max] 范围内</span><br> part.set_pos(pos_value)<br> value = Objective_function(part.get_pos())<br> <span class="hljs-keyword">if</span> value < part.get_fitness_value():<br> part.set_fitness_value(value)<br> part.set_best_pos(pos_value)<br> <span class="hljs-keyword">if</span> value < self.get_bestFitnessValue():<br> self.set_bestFitnessValue(value)<br> self.set_bestPosition(pos_value)<br> <span class="hljs-comment">#更新粒子</span><br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">update_ndim</span>(<span class="hljs-params">self</span>):<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(self.iter_num):<br> <span class="hljs-keyword">for</span> part <span class="hljs-keyword">in</span> self.Particle_list:<br> self.update_vel(part) <span class="hljs-comment"># 更新速度</span><br> self.update_pos(part) <span class="hljs-comment"># 更新位置</span><br> self.fitness_val_list.append(self.get_bestFitnessValue()) <span class="hljs-comment"># 每次迭代完把当前的最优适应度存到列表</span><br> <span class="hljs-built_in">print</span>(<span class="hljs-string">'第{}次最佳适应值为{}'</span>.<span class="hljs-built_in">format</span>(i, self.get_bestFitnessValue()))<span class="hljs-comment">#################################################</span><br> <span class="hljs-keyword">if</span> self.get_bestFitnessValue() < self.tol:<br> <span class="hljs-keyword">break</span><br> <span class="hljs-built_in">print</span>(<span class="hljs-string">'--------------粒子群--------------'</span>)<br> <span class="hljs-keyword">return</span> self.fitness_val_list, self.get_bestPosition()<br><span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">'__main__'</span>:<br> main_work()<br></code></pre></td></tr></table></figure>]]></content>
<categories>
<category>数学建模</category>
</categories>
</entry>
<entry>
<title>模拟退火算法代码</title>
<link href="/2024/09/11/%E6%A8%A1%E6%8B%9F%E9%80%80%E7%81%AB%E7%AE%97%E6%B3%95%E4%BB%A3%E7%A0%81/"/>
<url>/2024/09/11/%E6%A8%A1%E6%8B%9F%E9%80%80%E7%81%AB%E7%AE%97%E6%B3%95%E4%BB%A3%E7%A0%81/</url>
<content type="html"><![CDATA[<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-string">'''参考文献:</span><br><span class="hljs-string">(1)胡山鹰,陈丙珍,非线性规划问题全局优化的模拟退火法,清华大学学报,1997,37(6):5-9</span><br><span class="hljs-string">(2)李歧强,具有约束指导的模拟退火算法,系统工程,2001,19(3):49-55</span><br><span class="hljs-string">'''</span><br><span class="hljs-keyword">import</span> random<br><span class="hljs-keyword">import</span> numpy <span class="hljs-keyword">as</span> np<br><span class="hljs-keyword">import</span> matplotlib.pyplot <span class="hljs-keyword">as</span> plt<br><span class="hljs-keyword">import</span> warnings<br>warnings.filterwarnings(<span class="hljs-string">"ignore"</span>)<br>plt.rcParams[<span class="hljs-string">'axes.unicode_minus'</span>] = <span class="hljs-literal">False</span> <span class="hljs-comment">#显示负号</span><br>plt.rcParams[<span class="hljs-string">'font.family'</span>] = [<span class="hljs-string">'sans-serif'</span>]<br>plt.rcParams[<span class="hljs-string">'font.sans-serif'</span>] = [<span class="hljs-string">'SimHei'</span>] <span class="hljs-comment"># 散点图标签可以显示中文</span><br><br><span class="hljs-comment"># 定义优化问题的目标函数,最小化问题</span><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">Objective_function</span>(<span class="hljs-params">X</span>): <span class="hljs-comment"># 目标函数和约束条件 最小化</span><br> X = X.flatten() <span class="hljs-comment">#将X变为一维数组</span><br> x1 = X[<span class="hljs-number">0</span>]<br> x2 = X[<span class="hljs-number">1</span>]<br> x3 = X[<span class="hljs-number">2</span>]<br> p1 = (<span class="hljs-built_in">max</span>(<span class="hljs-number">0</span>, <span class="hljs-number">6</span> * x1 + <span class="hljs-number">5</span> * x2 - <span class="hljs-number">60</span>)) ** <span class="hljs-number">2</span> <span class="hljs-comment">#表达的含义是函数表达式小于0</span><br> p2 = (<span class="hljs-built_in">max</span>(<span class="hljs-number">0</span>, <span class="hljs-number">10</span> * x1 + <span class="hljs-number">20</span> * x2 - <span class="hljs-number">150</span>)) ** <span class="hljs-number">2</span><br> <span class="hljs-comment">#如果是等式约束,可以转化成表达式=0,然后目标函数-10000*表达式</span><br> fx = <span class="hljs-number">100.0</span> * (x2 - x1) ** <span class="hljs-number">2.0</span> + (<span class="hljs-number">1</span> - x1) ** <span class="hljs-number">2.0</span> * x3<br> <span class="hljs-keyword">return</span> fx + <span class="hljs-number">10000</span> * (p1 + p2) <span class="hljs-comment">#施加惩罚项</span><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">main_work</span>(): <span class="hljs-comment">#有理数,整数,0-1变量</span><br> sa = SA(x_min=[[-<span class="hljs-number">30</span>,-<span class="hljs-number">30</span>],[-<span class="hljs-number">1</span>],[]],x_max=[[<span class="hljs-number">30</span>,<span class="hljs-number">30</span>],[<span class="hljs-number">1</span>],[]],t1=<span class="hljs-number">1000</span>,t0=<span class="hljs-number">1e-4</span>,k=<span class="hljs-number">0.98</span>,Markov=<span class="hljs-number">500</span>,step=<span class="hljs-number">0.1</span>)<br> fv = sa.optimize()<br> plt.title(<span class="hljs-string">'模拟退火'</span>)<br> plt.plot(<span class="hljs-built_in">range</span>(<span class="hljs-number">1</span>,<span class="hljs-built_in">len</span>(fv)+<span class="hljs-number">1</span>), fv, color=<span class="hljs-string">'r'</span>)<br> plt.show()<br><span class="hljs-keyword">class</span> <span class="hljs-title class_">SA</span>:<br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">__init__</span>(<span class="hljs-params">self, x_min,x_max,t1,t0,k,Markov,step</span>):<br> <span class="hljs-comment"># ====== 初始化随机数发生器 ======</span><br> randseed = random.randint(<span class="hljs-number">1</span>, <span class="hljs-number">100</span>)<br> random.seed(randseed) <span class="hljs-comment"># 随机数发生器设置种子,也可以设为指定整数</span><br><br> self.n = <span class="hljs-built_in">len</span>(np.array(x_min).ravel()) <span class="hljs-comment"># 自变量数量</span><br> self.x_min = x_min <span class="hljs-comment"># 给定搜索空间的下限</span><br> self.x_max = x_max <span class="hljs-comment"># 给定搜索空间的上限</span><br> self.t1 = t1 <span class="hljs-comment"># 初始退火温度</span><br> self.t0 = t0 <span class="hljs-comment"># 终止退火温度,不能是0,因为只会无限趋近于0</span><br> self.k = k <span class="hljs-comment"># 降温参数,T(i)=k*T(i-1)</span><br> self.Markov = Markov <span class="hljs-comment"># Markov链长度,内循环运行次数</span><br> self.step = step <span class="hljs-comment"># 搜索步长</span><br><br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">optimize</span>(<span class="hljs-params">self</span>):<br> <span class="hljs-comment"># ====== 随机产生优化问题的初始解 ======</span><br> xInitial = np.zeros((self.n)) <span class="hljs-comment"># 初始化,创建数组</span><br> l1 = <span class="hljs-built_in">len</span>(self.x_min[<span class="hljs-number">0</span>])<br> l2 = <span class="hljs-built_in">len</span>(self.x_min[<span class="hljs-number">0</span>]+self.x_min[<span class="hljs-number">1</span>])<br> <span class="hljs-keyword">for</span> v <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(self.n):<br> <span class="hljs-keyword">if</span> v < l1:<br> xInitial[v] = np.random.uniform(self.x_min[<span class="hljs-number">0</span>][v], self.x_max[<span class="hljs-number">0</span>][v]) <span class="hljs-comment">#有理数</span><br> <span class="hljs-keyword">elif</span> v >= l1 <span class="hljs-keyword">and</span> v < l2:<br> xInitial[v] = np.random.randint(self.x_min[<span class="hljs-number">1</span>][v-l1], self.x_max[<span class="hljs-number">1</span>][v-l1]+<span class="hljs-number">1</span>) <span class="hljs-comment">#整数</span><br> <span class="hljs-keyword">else</span>:<br> xInitial[v] = np.random.randint(<span class="hljs-number">0</span>,<span class="hljs-number">2</span>) <span class="hljs-comment">#0-1变量</span><br> fxInitial = Objective_function(xInitial)<br><br> <span class="hljs-comment">################################## 模拟退火算法初始化 ##############################</span><br> xNew = np.zeros((self.n)) <span class="hljs-comment"># 初始化,创建数组</span><br> xNow = np.zeros((self.n)) <span class="hljs-comment"># 初始化,创建数组</span><br> xBest = np.zeros((self.n)) <span class="hljs-comment"># 初始化,创建数组</span><br> xNow[:] = xInitial[:] <span class="hljs-comment"># 初始化当前解,将初始解置为当前解</span><br> xBest[:] = xInitial[:] <span class="hljs-comment"># 初始化最优解,将当前解置为最优解</span><br> fxNow = fxInitial <span class="hljs-comment"># 将初始解的目标函数置为当前值</span><br> fxBest = fxInitial <span class="hljs-comment"># 将当前解的目标函数置为最优值</span><br> <span class="hljs-comment">#print('初始解:{:.6f},{:.6f},\t初始值:{:.6f}'.format(xInitial[0], xInitial[1], fxInitial))</span><br><br> recordIter = [] <span class="hljs-comment"># 初始化,外循环次数</span><br> recordFxNow = [] <span class="hljs-comment"># 初始化,当前解的目标函数值</span><br> recordFxBest = [] <span class="hljs-comment"># 初始化,最佳解的目标函数值</span><br> recordPBad = [] <span class="hljs-comment"># 初始化,劣质解的接受概率</span><br> n_Iter = <span class="hljs-number">0</span> <span class="hljs-comment"># 外循环迭代次数</span><br> totalMar = <span class="hljs-number">0</span> <span class="hljs-comment"># 总计 Markov 链长度</span><br> totalImprove = <span class="hljs-number">0</span> <span class="hljs-comment"># fxBest 改善次数</span><br> nMarkov = self.Markov <span class="hljs-comment"># 固定长度 Markov链</span><br><br> <span class="hljs-comment">################################### 开始模拟退火优化 ####################################</span><br> <span class="hljs-comment"># 外循环</span><br> fv = []<br> tNow = self.t1 <span class="hljs-comment"># 当前温度</span><br> <span class="hljs-keyword">while</span> tNow > self.t0: <span class="hljs-comment"># 外循环,直到当前温度达到终止温度时结束</span><br> kBetter = <span class="hljs-number">0</span> <span class="hljs-comment"># 获得优质解的次数</span><br> kBadAccept = <span class="hljs-number">0</span> <span class="hljs-comment"># 接受劣质解的次数</span><br> kBadRefuse = <span class="hljs-number">0</span> <span class="hljs-comment"># 拒绝劣质解的次数</span><br><br> <span class="hljs-comment"># 内循环</span><br> <span class="hljs-keyword">for</span> k <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(nMarkov): <span class="hljs-comment"># 内循环,循环次数为Markov链长度</span><br> totalMar += <span class="hljs-number">1</span> <span class="hljs-comment"># 总 Markov链长度计数器</span><br><br> <span class="hljs-comment"># ---产生新解</span><br> <span class="hljs-comment"># 产生新解:通过在当前解附近随机扰动而产生新解,新解必须在 [min,max] 范围内</span><br> <span class="hljs-comment"># 方案 1:只对 n元变量中的一个进行扰动,其它 n-1个变量保持不变</span><br> xNew[:] = xNow[:]<br> v = random.randint(<span class="hljs-number">0</span>, self.n - <span class="hljs-number">1</span>) <span class="hljs-comment"># 产生 [0,n-1]之间的随机数</span><br> <span class="hljs-keyword">if</span> v < l1:<br> xNew[v] = xNow[v] + self.step * (self.x_max[<span class="hljs-number">0</span>][v] - self.x_min[<span class="hljs-number">0</span>][v]) * random.normalvariate(<span class="hljs-number">0</span>, <span class="hljs-number">1</span>)<br> <span class="hljs-comment"># random.normalvariate(0, 1):产生服从均值为0、标准差为 1 的正态分布随机实数</span><br> xNew[v] = <span class="hljs-built_in">max</span>(<span class="hljs-built_in">min</span>(xNew[v], self.x_max[<span class="hljs-number">0</span>][v]), self.x_min[<span class="hljs-number">0</span>][v]) <span class="hljs-comment"># 保证新解在 [min,max] 范围内</span><br> <span class="hljs-keyword">elif</span> v >= l1 <span class="hljs-keyword">and</span> v < l2:<br> xNew[v] = xNow[v] + <span class="hljs-built_in">int</span>(self.step * (self.x_max[<span class="hljs-number">1</span>][v-l1] - self.x_min[<span class="hljs-number">1</span>][v-l1]) * random.normalvariate(<span class="hljs-number">0</span>, <span class="hljs-number">1</span>))<br> <span class="hljs-comment"># random.normalvariate(0, 1):产生服从均值为0、标准差为 1 的正态分布随机实数</span><br> xNew[v] = <span class="hljs-built_in">max</span>(<span class="hljs-built_in">min</span>(xNew[v], self.x_max[<span class="hljs-number">1</span>][v-l1]), self.x_min[<span class="hljs-number">1</span>][v-l1]) <span class="hljs-comment"># 保证新解在 [min,max] 范围内</span><br> <span class="hljs-keyword">else</span>:<br> xNew[v] = np.random.randint(<span class="hljs-number">0</span>,<span class="hljs-number">2</span>) <span class="hljs-comment">#0-1变量</span><br> xNew[v] = <span class="hljs-built_in">max</span>(<span class="hljs-built_in">min</span>(xNew[v], self.x_max[<span class="hljs-number">2</span>][v-l2]), self.x_min[<span class="hljs-number">2</span>][v-l2]) <span class="hljs-comment"># 保证新解在 [min,max] 范围内</span><br><br> <span class="hljs-comment"># 计算目标函数和能量差</span><br> fxNew = Objective_function(xNew)<br> deltaE = fxNew - fxNow<br><br> <span class="hljs-comment"># 按 Metropolis 准则接受新解</span><br> <span class="hljs-keyword">if</span> fxNew < fxNow: <span class="hljs-comment"># 更优解:如果新解的目标函数好于当前解,则接受新解</span><br> accept = <span class="hljs-literal">True</span><br> kBetter += <span class="hljs-number">1</span><br> <span class="hljs-keyword">else</span>: <span class="hljs-comment"># 容忍解:如果新解的目标函数比当前解差,则以一定概率接受新解</span><br> pAccept = np.exp(-np.float64(deltaE) / np.float64(tNow)) <span class="hljs-comment"># 计算容忍解的状态迁移概率</span><br> <span class="hljs-keyword">if</span> pAccept > random.random():<br> accept = <span class="hljs-literal">True</span> <span class="hljs-comment"># 接受劣质解</span><br> kBadAccept += <span class="hljs-number">1</span><br> <span class="hljs-keyword">else</span>:<br> accept = <span class="hljs-literal">False</span> <span class="hljs-comment"># 拒绝劣质解</span><br> kBadRefuse += <span class="hljs-number">1</span><br><br> <span class="hljs-comment"># 保存新解</span><br> <span class="hljs-keyword">if</span> accept == <span class="hljs-literal">True</span>: <span class="hljs-comment"># 如果接受新解,则将新解保存为当前解</span><br> xNow[:] = xNew[:]<br> fxNow = fxNew<br> <span class="hljs-keyword">if</span> fxNew < fxBest: <span class="hljs-comment"># 如果新解的目标函数好于最优解,则将新解保存为最优解</span><br> fxBest = fxNew<br> xBest[:] = xNew[:]<br> totalImprove += <span class="hljs-number">1</span><br> self.step = self.step * <span class="hljs-number">0.99</span> <span class="hljs-comment"># 可变搜索步长,逐步减小搜索范围,提高搜索精度</span><br><br> <span class="hljs-comment"># 完成当前温度的搜索,保存数据和输出</span><br> pBadAccept = kBadAccept / (kBadAccept + kBadRefuse) <span class="hljs-comment"># 劣质解的接受概率</span><br> recordIter.append(n_Iter) <span class="hljs-comment"># 当前外循环次数</span><br> recordFxNow.append(<span class="hljs-built_in">round</span>(fxNow, <span class="hljs-number">4</span>)) <span class="hljs-comment"># 当前解的目标函数值</span><br> recordFxBest.append(<span class="hljs-built_in">round</span>(fxBest, <span class="hljs-number">4</span>)) <span class="hljs-comment"># 最佳解的目标函数值</span><br> recordPBad.append(<span class="hljs-built_in">round</span>(pBadAccept, <span class="hljs-number">4</span>)) <span class="hljs-comment"># 最佳解的目标函数值</span><br><br> <span class="hljs-comment">#if n_Iter % 10 == 0: # 模运算,商的余数</span><br> <span class="hljs-comment">#print('迭代次数:{},温度:{:.3f},最优值:{:.6f}'.format(n_Iter,tNow,fxBest))</span><br><br> <span class="hljs-comment"># 缓慢降温至新的温度,降温曲线:T(k)=k*T(k-1)</span><br> tNow = tNow * self.k<br> n_Iter = n_Iter + <span class="hljs-number">1</span><br> fxBest = Objective_function(xBest)<br> <span class="hljs-comment">############################### 结束模拟退火过程 #######################################</span><br> <span class="hljs-built_in">print</span>(<span class="hljs-string">'--------------模拟退火-------------'</span>)<br> <span class="hljs-built_in">print</span>(<span class="hljs-string">'提升次数:{:d}'</span>.<span class="hljs-built_in">format</span>(totalImprove))<br> <span class="hljs-built_in">print</span>(<span class="hljs-string">"求解结果:"</span>)<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(self.n):<br> <span class="hljs-built_in">print</span>(<span class="hljs-string">'\tx[{}] = {:.9f}'</span>.<span class="hljs-built_in">format</span>(i, xBest[i]))<br> <span class="hljs-built_in">print</span>(<span class="hljs-string">'\tf(x):{:.9f}'</span>.<span class="hljs-built_in">format</span>(Objective_function(xBest)))<br> <span class="hljs-keyword">return</span> recordFxBest<span class="hljs-comment">#,fxBest,n_Iter, xBest, fxNow, recordIter, recordFxNow, recordPBad</span><br><br><span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">'__main__'</span>:<br> main_work()<br></code></pre></td></tr></table></figure>]]></content>
<categories>
<category>数学建模</category>
</categories>
</entry>
<entry>
<title>交通运输工程学课程设计代码</title>
<link href="/2024/09/11/%E4%BA%A4%E9%80%9A%E8%BF%90%E8%BE%93%E5%B7%A5%E7%A8%8B%E5%AD%A6%E8%AF%BE%E7%A8%8B%E8%AE%BE%E8%AE%A1%E4%BB%A3%E7%A0%81/"/>
<url>/2024/09/11/%E4%BA%A4%E9%80%9A%E8%BF%90%E8%BE%93%E5%B7%A5%E7%A8%8B%E5%AD%A6%E8%AF%BE%E7%A8%8B%E8%AE%BE%E8%AE%A1%E4%BB%A3%E7%A0%81/</url>
<content type="html"><![CDATA[<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br><span class="line">260</span><br><span class="line">261</span><br><span class="line">262</span><br><span class="line">263</span><br><span class="line">264</span><br><span class="line">265</span><br><span class="line">266</span><br><span class="line">267</span><br><span class="line">268</span><br><span class="line">269</span><br><span class="line">270</span><br><span class="line">271</span><br><span class="line">272</span><br><span class="line">273</span><br><span class="line">274</span><br><span class="line">275</span><br><span class="line">276</span><br><span class="line">277</span><br><span class="line">278</span><br><span class="line">279</span><br><span class="line">280</span><br><span class="line">281</span><br><span class="line">282</span><br><span class="line">283</span><br><span class="line">284</span><br><span class="line">285</span><br><span class="line">286</span><br><span class="line">287</span><br><span class="line">288</span><br><span class="line">289</span><br><span class="line">290</span><br><span class="line">291</span><br><span class="line">292</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">import</span> numpy <span class="hljs-keyword">as</span> np<br><span class="hljs-keyword">from</span> numpy <span class="hljs-keyword">import</span> random<br><span class="hljs-keyword">from</span> copy <span class="hljs-keyword">import</span> deepcopy<br><span class="hljs-keyword">import</span> matplotlib.pyplot <span class="hljs-keyword">as</span> plt<br><span class="hljs-keyword">from</span> tqdm <span class="hljs-keyword">import</span> tqdm<br><span class="hljs-keyword">import</span> warnings<br>warnings.filterwarnings(<span class="hljs-string">"ignore"</span>)<br>np.set_printoptions(threshold=np.inf) <span class="hljs-comment"># threshold 指定超过多少使用省略号,np.inf代表无限大</span><br>np.set_printoptions(suppress=<span class="hljs-literal">True</span>) <span class="hljs-comment">#不以科学计数法输出</span><br>plt.rcParams[<span class="hljs-string">'axes.unicode_minus'</span>] = <span class="hljs-literal">False</span> <span class="hljs-comment">#显示负号</span><br>plt.rcParams[<span class="hljs-string">'font.family'</span>] = [<span class="hljs-string">'sans-serif'</span>]<br>plt.rcParams[<span class="hljs-string">'font.sans-serif'</span>] = [<span class="hljs-string">'SimHei'</span>] <span class="hljs-comment"># 散点图标签可以显示中文</span><br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">haversine_distance</span>(<span class="hljs-params">coord1, coord2</span>):<br> <span class="hljs-comment"># 将经纬度从度数转换为弧度</span><br> lat1, lon1 = np.radians(coord1[<span class="hljs-number">1</span>]), np.radians(coord1[<span class="hljs-number">0</span>])<br> lat2, lon2 = np.radians(coord2[<span class="hljs-number">1</span>]), np.radians(coord2[<span class="hljs-number">0</span>])<br> <span class="hljs-comment"># Haversine 公式</span><br> dlon = lon2 - lon1<br> dlat = lat2 - lat1<br> a = np.sin(dlat / <span class="hljs-number">2</span>) ** <span class="hljs-number">2</span> + np.cos(lat1) * np.cos(lat2) * np.sin(dlon / <span class="hljs-number">2</span>) ** <span class="hljs-number">2</span><br> c = <span class="hljs-number">2</span> * np.arctan2(np.sqrt(a), np.sqrt(<span class="hljs-number">1</span> - a))<br> <span class="hljs-comment"># 地球半径(单位:公里)</span><br> radius = <span class="hljs-number">6371.0</span><br> <span class="hljs-comment"># 计算距离</span><br> distance = radius * c<br> <span class="hljs-keyword">return</span> distance<br>coordinates = np.array([<br> [<span class="hljs-number">104.107895</span>, <span class="hljs-number">30.457623</span>],<br> [<span class="hljs-number">104.642054</span>, <span class="hljs-number">30.702534</span>],<br> [<span class="hljs-number">104.055628</span>, <span class="hljs-number">30.527435</span>],<br> [<span class="hljs-number">103.721549</span>, <span class="hljs-number">30.931824</span>],<br> [<span class="hljs-number">104.112324</span>, <span class="hljs-number">30.668907</span>],<br> [<span class="hljs-number">104.077094</span>, <span class="hljs-number">30.674277</span>],<br> [<span class="hljs-number">104.214562</span>, <span class="hljs-number">30.531782</span>],<br> [<span class="hljs-number">103.943217</span>, <span class="hljs-number">30.782159</span>],<br> [<span class="hljs-number">104.145552</span>, <span class="hljs-number">30.605267</span>],<br> [<span class="hljs-number">104.028378</span>, <span class="hljs-number">30.676363</span>],<br> [<span class="hljs-number">103.974325</span>, <span class="hljs-number">30.735671</span>],<br> [<span class="hljs-number">104.076092</span>, <span class="hljs-number">30.624577</span>],<br> [<span class="hljs-number">104.060045</span>, <span class="hljs-number">30.633286</span>],<br> [<span class="hljs-number">104.042753</span>, <span class="hljs-number">30.637203</span>],<br> [<span class="hljs-number">104.034653</span>, <span class="hljs-number">30.525472</span>],<br> [<span class="hljs-number">103.922376</span>, <span class="hljs-number">30.570071</span>],<br> [<span class="hljs-number">103.693276</span>, <span class="hljs-number">30.632171</span>],<br> [<span class="hljs-number">104.101776</span>, <span class="hljs-number">30.632171</span>],<br> [<span class="hljs-number">104.234756</span>, <span class="hljs-number">30.568442</span>],<br> [<span class="hljs-number">104.074576</span>, <span class="hljs-number">30.624871</span>],<br> [<span class="hljs-number">104.204776</span>, <span class="hljs-number">30.518071</span>]<br>])<br><span class="hljs-comment"># 初始化距离矩阵</span><br>num_points = <span class="hljs-built_in">len</span>(coordinates)<br>dist_matrix = np.zeros((num_points, num_points))<br><span class="hljs-comment"># 计算距离矩阵</span><br><span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(num_points):<br> <span class="hljs-keyword">for</span> j <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(num_points):<br> dist_matrix[i, j] = haversine_distance(coordinates[i], coordinates[j])<br>values = [<span class="hljs-number">0</span>, <span class="hljs-number">1.151</span>, <span class="hljs-number">1.273</span>, <span class="hljs-number">1.512</span>, <span class="hljs-number">2.311</span>, <span class="hljs-number">0.827</span>, <span class="hljs-number">4.185</span>, <span class="hljs-number">2.342</span>, <span class="hljs-number">1.124</span>, <span class="hljs-number">1.367</span>, <span class="hljs-number">4.227</span>,<br> <span class="hljs-number">0.622</span>, <span class="hljs-number">0.937</span>, <span class="hljs-number">1.722</span>, <span class="hljs-number">3.075</span>, <span class="hljs-number">1.252</span>, <span class="hljs-number">5.221</span>, <span class="hljs-number">2.879</span>, <span class="hljs-number">2.357</span>, <span class="hljs-number">4.212</span>, <span class="hljs-number">3.661</span>]<br><span class="hljs-comment"># 46t</span><br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">xuhao</span>(<span class="hljs-params">x,v</span>): <span class="hljs-comment"># 获取x中第v个1的纵坐标</span><br> vv = <span class="hljs-number">0</span><br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-built_in">len</span>(x)):<br> <span class="hljs-keyword">if</span> x[i] == <span class="hljs-number">1</span>:<br> vv += <span class="hljs-number">1</span><br> <span class="hljs-keyword">if</span> vv == v:<br> <span class="hljs-keyword">return</span> i<br><span class="hljs-keyword">def</span> <span class="hljs-title function_">dfs</span>(<span class="hljs-params">graph, start, end, k, matrix</span>):<br> xx = []<br> dd = [<span class="hljs-number">0</span>]*k<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(k):<br> xxx = [start]<br> down = xuhao(graph[start],i+<span class="hljs-number">1</span>)<br> dd[i] += <span class="hljs-built_in">float</span>(matrix[start,down])<br> start = down<br> xxx.append(start)<br> <span class="hljs-keyword">while</span> start != end:<br> down = xuhao(graph[start],<span class="hljs-number">1</span>)<br> dd[i] += matrix[start][down]<br> xxx.append(down)<br> start = down<br> xx.append(xxx)<br> vv = [<span class="hljs-number">0</span>]*k<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-built_in">len</span>(xx)):<br> <span class="hljs-keyword">for</span> j <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">1</span>,<span class="hljs-built_in">len</span>(xx[i])-<span class="hljs-number">1</span>):<br> vv[i] += values[xx[i][j]]<br> <span class="hljs-keyword">return</span> xx,dd,vv<br><br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">xijdef</span>(<span class="hljs-params">x</span>):<br> xij = np.zeros((<span class="hljs-number">21</span>,<span class="hljs-number">21</span>), dtype=<span class="hljs-built_in">int</span>)<br> <span class="hljs-comment"># 将主对角线上面的一条线设为1</span><br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">1</span>,<span class="hljs-number">21</span>-x):<br> xij[i, i+x] = <span class="hljs-number">1</span><br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">1</span>,x+<span class="hljs-number">1</span>):<br> xij[-i,<span class="hljs-number">0</span>] = <span class="hljs-number">1</span><br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">1</span>,x+<span class="hljs-number">1</span>):<br> xij[<span class="hljs-number">0</span>,i] = <span class="hljs-number">1</span><br> <span class="hljs-keyword">return</span> xij<br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">fun</span>(<span class="hljs-params">X</span>): <span class="hljs-comment"># 目标函数和约束条件</span><br> x = X.flatten() <span class="hljs-comment">#将X变为一维数组</span><br> xij = xijdef(<span class="hljs-built_in">int</span>(x[-<span class="hljs-number">1</span>]))<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">15</span>):<br> xij[:,<span class="hljs-built_in">int</span>(x[<span class="hljs-number">2</span>*i])] , xij[:,<span class="hljs-built_in">int</span>(x[<span class="hljs-number">2</span>*i+<span class="hljs-number">1</span>])] = xij[:,<span class="hljs-built_in">int</span>(x[<span class="hljs-number">2</span>*i+<span class="hljs-number">1</span>])].copy() , xij[:,<span class="hljs-built_in">int</span>(x[<span class="hljs-number">2</span>*i])].copy()<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">15</span>,<span class="hljs-number">30</span>):<br> xij[<span class="hljs-built_in">int</span>(x[<span class="hljs-number">2</span>*i]),:] , xij[<span class="hljs-built_in">int</span>(x[<span class="hljs-number">2</span>*i+<span class="hljs-number">1</span>]),:] = xij[<span class="hljs-built_in">int</span>(x[<span class="hljs-number">2</span>*i+<span class="hljs-number">1</span>]),:].copy() , xij[<span class="hljs-built_in">int</span>(x[<span class="hljs-number">2</span>*i]),:].copy()<br> result,dd,vv = dfs(xij,<span class="hljs-number">0</span>,<span class="hljs-number">0</span>,<span class="hljs-built_in">int</span>(x[-<span class="hljs-number">1</span>]),dist_matrix) <span class="hljs-comment"># 获得路径与路程</span><br><br> st = <span class="hljs-number">0</span><br> lis = [element <span class="hljs-keyword">for</span> sublist <span class="hljs-keyword">in</span> result <span class="hljs-keyword">for</span> element <span class="hljs-keyword">in</span> sublist <span class="hljs-keyword">if</span> element != <span class="hljs-number">0</span>]<br> <span class="hljs-keyword">if</span> <span class="hljs-built_in">len</span>(lis) != <span class="hljs-number">20</span>:<br> st += <span class="hljs-number">1000000000000</span><br> <span class="hljs-keyword">if</span> <span class="hljs-built_in">max</span>(dd) > <span class="hljs-number">150</span>: <span class="hljs-comment"># 最大距离限制</span><br> st += <span class="hljs-number">1000000000</span><br> <span class="hljs-keyword">if</span> <span class="hljs-built_in">max</span>(vv) > <span class="hljs-number">10</span>: <span class="hljs-comment"># 最大容量限制</span><br> st += <span class="hljs-number">1000000000</span><br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">1</span>,<span class="hljs-number">21</span>): <span class="hljs-comment"># 每个点都要走</span><br> <span class="hljs-keyword">if</span> <span class="hljs-built_in">sum</span>(xij[:,i]) != <span class="hljs-number">1</span>:<br> st += <span class="hljs-number">1000000000</span><br> <span class="hljs-keyword">if</span> <span class="hljs-built_in">sum</span>(xij[i,:]) != <span class="hljs-number">1</span>:<br> st += <span class="hljs-number">1000000000</span><br><br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">21</span>): <span class="hljs-comment"># 避免车辆来回跑</span><br> <span class="hljs-keyword">for</span> j <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(i+<span class="hljs-number">1</span>):<br> <span class="hljs-keyword">if</span> xij[i,j] == xij[j,i] <span class="hljs-keyword">and</span> xij[i,j] == <span class="hljs-number">1</span>:<br> st += <span class="hljs-number">1000000000</span><br><br> fx1 = x[-<span class="hljs-number">1</span>]*<span class="hljs-number">150</span> <span class="hljs-comment"># 车辆固定成本</span><br> fx2 = <span class="hljs-number">0</span><br> fx3 = <span class="hljs-number">0</span><br> e = np.e<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-built_in">len</span>(result)):<br> ddd = <span class="hljs-number">0</span><br> <span class="hljs-keyword">for</span> j <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">1</span>,<span class="hljs-built_in">len</span>(result[i])):<br> ddd += dist_matrix[result[i][j-<span class="hljs-number">1</span>],result[i][j]]<br> <span class="hljs-keyword">if</span> j == <span class="hljs-built_in">len</span>(result[i])-<span class="hljs-number">1</span>:<br> fx3 += <span class="hljs-number">6</span>*dist_matrix[result[i][j-<span class="hljs-number">1</span>],result[i][j]]<br> <span class="hljs-keyword">else</span>:<br> fx2 += (<span class="hljs-number">1</span>-<span class="hljs-number">1</span>/e**(<span class="hljs-number">0.05</span>*(ddd/<span class="hljs-number">23</span>)))*<span class="hljs-number">500</span>*values[result[i][j]] <span class="hljs-comment"># 货损成本</span><br> fx3 += ddd*<span class="hljs-number">7</span>*values[result[i][j]] <span class="hljs-comment"># 运输费用</span><br> <span class="hljs-keyword">return</span> fx1+fx2+fx3+st<br><br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">dd2</span>(<span class="hljs-params">best_x, x</span>): <span class="hljs-comment">#欧氏距离</span><br> best_x = np.array(best_x) <span class="hljs-comment">#转化成numpy数组</span><br> x = np.array(x) <span class="hljs-comment">#转化成numpy数组</span><br> c = np.<span class="hljs-built_in">sum</span>(<span class="hljs-built_in">pow</span>(x - best_x, <span class="hljs-number">2</span>), axis=<span class="hljs-number">1</span>) <span class="hljs-comment">#求方差,在行上的标准差</span><br> d = <span class="hljs-built_in">pow</span>(c, <span class="hljs-number">0.5</span>) <span class="hljs-comment">#标准差</span><br> <span class="hljs-keyword">return</span> d<br><span class="hljs-keyword">def</span> <span class="hljs-title function_">new_min</span>(<span class="hljs-params">arr</span>): <span class="hljs-comment">#求最小</span><br> min_data = <span class="hljs-built_in">min</span>(arr) <span class="hljs-comment">#找到最小值</span><br> key = np.argmin(arr) <span class="hljs-comment">#找到最小值的索引</span><br> <span class="hljs-keyword">return</span> min_data, key<br><span class="hljs-keyword">def</span> <span class="hljs-title function_">type_x</span>(<span class="hljs-params">xx,<span class="hljs-built_in">type</span>,n</span>): <span class="hljs-comment">#变量范围约束</span><br> <span class="hljs-keyword">for</span> v <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(n):<br> <span class="hljs-keyword">if</span> <span class="hljs-built_in">type</span>[v] == -<span class="hljs-number">1</span>:<br> xx[v] = np.maximum(sub[v], xx[v])<br> xx[v] = np.minimum(up[v], xx[v])<br> <span class="hljs-keyword">elif</span> <span class="hljs-built_in">type</span>[v] == <span class="hljs-number">0</span>:<br> xx[v] = np.maximum(sub[v], <span class="hljs-built_in">int</span>(xx[v]))<br> xx[v] = np.minimum(up[v], <span class="hljs-built_in">int</span>(xx[v]))<br> <span class="hljs-keyword">else</span>:<br> xx[v] = np.maximum(sub[v], random.randint(<span class="hljs-number">0</span>,<span class="hljs-number">2</span>))<br> xx[v] = np.minimum(up[v], random.randint(<span class="hljs-number">0</span>,<span class="hljs-number">2</span>))<br> <span class="hljs-keyword">return</span> xx<br><span class="hljs-keyword">def</span> <span class="hljs-title function_">woa</span>(<span class="hljs-params">sub,up,<span class="hljs-built_in">type</span>,nums,det</span>):<br> n = <span class="hljs-built_in">len</span>(sub) <span class="hljs-comment"># 自变量个数</span><br> num = nums * n <span class="hljs-comment"># 种群大小</span><br> x = np.zeros([num, n]) <span class="hljs-comment">#生成保存解的矩阵</span><br><br> f = np.zeros(num) <span class="hljs-comment">#生成保存值的矩阵</span><br> <span class="hljs-keyword">for</span> s <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(num): <span class="hljs-comment">#随机生成初始解</span><br> <span class="hljs-keyword">for</span> v <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(n):<br> rand_data = np.random.uniform(<span class="hljs-number">0</span>,<span class="hljs-number">1</span>)<br> x[s, v] = sub[v] + (up[v] - sub[v]) * rand_data<br> x[s, :] = type_x(x[s, :],<span class="hljs-built_in">type</span>,n)<br> f[s] = fun(x[s, :])<br> best_f, a = new_min(f) <span class="hljs-comment"># 记录历史最优值</span><br> best_x = x[a, :] <span class="hljs-comment"># 记录历史最优解</span><br> trace = np.array([deepcopy(best_f)]) <span class="hljs-comment">#记录初始最优值,以便后期添加最优值画图</span><br> <span class="hljs-comment">############################ 改进的鲸鱼算法 ################################</span><br> xx = np.zeros([num, n])<br> ff = np.zeros(num)<br> Mc = (up - sub) * <span class="hljs-number">0.1</span> <span class="hljs-comment"># 猎物行动最大范围</span><br> <span class="hljs-keyword">for</span> ii <span class="hljs-keyword">in</span> tqdm(<span class="hljs-built_in">range</span>(det)): <span class="hljs-comment">#设置迭代次数,进入迭代过程</span><br> <span class="hljs-comment"># 猎物躲避,蒙特卡洛模拟,并选择最佳的点作为下一逃跑点 #########!!!创新点</span><br> d = dd2(best_x, x) <span class="hljs-comment">#记录当前解与最优解的距离</span><br> d.sort() <span class="hljs-comment">#从小到大排序,d[0]恒为0</span><br> z = np.exp(-d[<span class="hljs-number">1</span>] / np.mean(Mc)) <span class="hljs-comment"># 猎物急躁系数</span><br> z = <span class="hljs-built_in">max</span>(z, <span class="hljs-number">0.1</span>) <span class="hljs-comment">#决定最终系数</span><br> yx = [] <span class="hljs-comment">#初始化存储函数值</span><br> dx = [] <span class="hljs-comment">#初始化存储解</span><br> random_rand = random.random() <span class="hljs-comment">#0-1的随机数</span><br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">30</span>): <span class="hljs-comment">#蒙特卡洛模拟的次数</span><br> m = [random.choice([-<span class="hljs-number">1</span>, <span class="hljs-number">1</span>]) <span class="hljs-keyword">for</span> _ <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(n)] <span class="hljs-comment">#随机的-1和1</span><br> asd = best_x + Mc * z * ((det-ii )/det) * random_rand * m <span class="hljs-comment">#最优解更新公式</span><br> xd = type_x(asd,<span class="hljs-built_in">type</span>,n) <span class="hljs-comment">#对自变量进行限制</span><br> <span class="hljs-keyword">if</span> i < <span class="hljs-number">1</span>:<br> dx = deepcopy(xd)<br> <span class="hljs-keyword">else</span>:<br> dx = np.vstack((dx,xd)) <span class="hljs-comment">#存储每一次的解</span><br> yx=np.hstack((yx,fun(xd))) <span class="hljs-comment">#存储每一次的值</span><br> best_t, a = new_min(yx) <span class="hljs-comment"># 选择最佳逃跑点</span><br> best_c = dx[a, :] <span class="hljs-comment">#最佳逃跑点</span><br> <span class="hljs-keyword">if</span> best_t < best_f: <span class="hljs-comment">#与鲸鱼算法得到的最优值对比</span><br> best_f = best_t <span class="hljs-comment">#更新最优值</span><br> best_x = best_c <span class="hljs-comment">#更新最优解</span><br> <span class="hljs-comment">############################# 鲸鱼追捕 #################################</span><br> w = (ii / det)**<span class="hljs-number">3</span> <span class="hljs-comment">#自适应惯性权重!!!创新点</span><br> a = (<span class="hljs-number">2</span> - <span class="hljs-number">2</span>*ii/det)*(<span class="hljs-number">1</span>- w) <span class="hljs-comment">#a随迭代次数从2非线性下降至0!!!创新点</span><br> pp=<span class="hljs-number">0.7</span> <span class="hljs-keyword">if</span> ii <= <span class="hljs-number">0.5</span>*det <span class="hljs-keyword">else</span> <span class="hljs-number">0.4</span><br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(num):<br> r1 = np.random.rand() <span class="hljs-comment"># r1为[0,1]之间的随机数</span><br> r2 = np.random.rand() <span class="hljs-comment"># r2为[0,1]之间的随机数</span><br> A = <span class="hljs-number">2</span> * a * r1 - a<br> C = <span class="hljs-number">2</span> * r2<br> b = <span class="hljs-number">1</span> <span class="hljs-comment">#螺旋形状系数</span><br> l = np.random.uniform(-<span class="hljs-number">1</span>,<span class="hljs-number">1</span>) <span class="hljs-comment">#参数l</span><br> p = np.random.rand()<br> <span class="hljs-keyword">if</span> p < pp:<br> <span class="hljs-keyword">if</span> <span class="hljs-built_in">abs</span>(A) >= <span class="hljs-number">1</span>:<br> rand_leader = np.random.randint(<span class="hljs-number">0</span>, num)<br> X_rand = x[rand_leader, :]<br> D_X_rand = <span class="hljs-built_in">abs</span>(C * X_rand - x[i, :])<br> xx[i, :] = w*X_rand - A * D_X_rand<br> xx[i, :] = type_x(xx[i, :],<span class="hljs-built_in">type</span>,n) <span class="hljs-comment">#对自变量进行限制</span><br> <span class="hljs-keyword">elif</span> <span class="hljs-built_in">abs</span>(A) < <span class="hljs-number">1</span>:<br> D_Leader = <span class="hljs-built_in">abs</span>(C * best_x - x[i, :])<br> xx[i, :] = w*best_x - A * D_Leader<br> xx[i, :] = type_x(xx[i, :],<span class="hljs-built_in">type</span>,n) <span class="hljs-comment">#对自变量进行限制</span><br> <span class="hljs-keyword">elif</span> p >= pp:<br> D = <span class="hljs-built_in">abs</span>(best_x - x[i, :])<br> xx[i, :] = D*np.exp(b*l)*np.cos(<span class="hljs-number">2</span>*np.pi*l) + (<span class="hljs-number">1</span>-w)*best_x <span class="hljs-comment">#完整的气泡网捕食公式</span><br> xx[i, :] = type_x(xx[i, :],<span class="hljs-built_in">type</span>,n) <span class="hljs-comment">#对自变量进行限制</span><br> ff[i] = fun(xx[i, :])<br> <span class="hljs-keyword">if</span> <span class="hljs-built_in">len</span>(np.unique(ff[:i]))/(i+<span class="hljs-number">1</span>) <= <span class="hljs-number">0.1</span>: <span class="hljs-comment">#limit阈值 + 随机差分变异!!!创新点</span><br> xx[i,:] = (r1*(best_x-xx[i,:]) +<br> r2*(x[np.random.randint(<span class="hljs-number">0</span>,num),:] - xx[i,:]))<br> xx[i, :] = type_x(xx[i, :],<span class="hljs-built_in">type</span>,n) <span class="hljs-comment">#对自变量进行限制</span><br> ff[i] = fun(xx[i, :])<br> <span class="hljs-comment">#将上一代种群与这一代种群以及最优种群结合,选取排名靠前的个体组成新的种群</span><br> F = np.hstack((np.array([best_f]), f, ff))<br> F, b = np.sort(F,axis=-<span class="hljs-number">1</span>,kind=<span class="hljs-string">'stable'</span>), np.argsort(F)<span class="hljs-comment">#按小到大排序,获得靠前的位置</span><br> X = np.vstack(([best_x], x, xx))[b, :]<br> f = F[:num] <span class="hljs-comment">#新种群的位置</span><br> x = X[:num, :] <span class="hljs-comment">#新种群的位置</span><br> best_f, a = new_min(f) <span class="hljs-comment"># 记录历史最优值</span><br> best_x = x[a , :] <span class="hljs-comment"># 记录历史最优解</span><br> trace = np.hstack((trace, [best_f]))<br> <span class="hljs-keyword">return</span> best_x,best_f,trace<br><br><br>s = np.zeros((<span class="hljs-number">1</span>,<span class="hljs-number">60</span>))<br>sub = np.concatenate((s+<span class="hljs-number">1</span>,np.array([[<span class="hljs-number">5</span>]])), axis=<span class="hljs-number">1</span>).ravel() <span class="hljs-comment"># 自变量下限</span><br>up = np.concatenate((s+<span class="hljs-number">20</span>,np.array([[<span class="hljs-number">7</span>]])), axis=<span class="hljs-number">1</span>).ravel() <span class="hljs-comment"># 自变量上限</span><br><span class="hljs-built_in">type</span> = np.concatenate((s,np.array([[<span class="hljs-number">0</span>]])), axis=<span class="hljs-number">1</span>).ravel() <span class="hljs-comment">#-1是有理数,0是整数,1是0-1变量</span><br>best_x,best_f,trace = woa(sub,up,<span class="hljs-built_in">type</span>,<span class="hljs-number">40</span>,<span class="hljs-number">10</span>) <span class="hljs-comment">#种群大小,迭代次数</span><br><span class="hljs-comment">#种群大小可以为自变量个数,迭代次数看情况</span><br><span class="hljs-built_in">print</span>(<span class="hljs-string">'最优解为:'</span>)<br><span class="hljs-built_in">print</span>(best_x)<br><span class="hljs-built_in">print</span>(<span class="hljs-string">'最优值为:'</span>)<br><span class="hljs-built_in">print</span>(<span class="hljs-built_in">float</span>(best_f))<br><br>xij = xijdef(<span class="hljs-built_in">int</span>(best_x[-<span class="hljs-number">1</span>]))<br><span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">15</span>):<br> xij[:,<span class="hljs-built_in">int</span>(best_x[<span class="hljs-number">2</span>*i])] , xij[:,<span class="hljs-built_in">int</span>(best_x[<span class="hljs-number">2</span>*i+<span class="hljs-number">1</span>])] = xij[:,<span class="hljs-built_in">int</span>(best_x[<span class="hljs-number">2</span>*i+<span class="hljs-number">1</span>])].copy() , xij[:,<span class="hljs-built_in">int</span>(best_x[<span class="hljs-number">2</span>*i])].copy()<br><span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">15</span>,<span class="hljs-number">30</span>):<br> xij[<span class="hljs-built_in">int</span>(best_x[<span class="hljs-number">2</span>*i])] , xij[<span class="hljs-built_in">int</span>(best_x[<span class="hljs-number">2</span>*i+<span class="hljs-number">1</span>])] = xij[<span class="hljs-built_in">int</span>(best_x[<span class="hljs-number">2</span>*i+<span class="hljs-number">1</span>])].copy() , xij[<span class="hljs-built_in">int</span>(best_x[<span class="hljs-number">2</span>*i])].copy()<br>result,dd,vv = dfs(xij,<span class="hljs-number">0</span>,<span class="hljs-number">0</span>,<span class="hljs-built_in">int</span>(best_x[-<span class="hljs-number">1</span>]),dist_matrix)<br><span class="hljs-built_in">print</span>(result)<br><span class="hljs-built_in">print</span>(dd)<br><span class="hljs-built_in">print</span>(vv)<br>fx1 = best_x[-<span class="hljs-number">1</span>]*<span class="hljs-number">150</span> <span class="hljs-comment"># 车辆固定成本</span><br>fx2 = <span class="hljs-number">0</span><br>fx3 = <span class="hljs-number">0</span><br>e = np.e<br><span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-built_in">len</span>(result)):<br> ddd = <span class="hljs-number">0</span><br> <span class="hljs-keyword">for</span> j <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">1</span>,<span class="hljs-built_in">len</span>(result[i])):<br> ddd += dist_matrix[result[i][j-<span class="hljs-number">1</span>],result[i][j]]<br> <span class="hljs-keyword">if</span> j == <span class="hljs-built_in">len</span>(result[i])-<span class="hljs-number">1</span>:<br> fx3 += <span class="hljs-number">4</span>*dist_matrix[result[i][j-<span class="hljs-number">1</span>],result[i][j]]<br> <span class="hljs-keyword">else</span>:<br> fx2 += (<span class="hljs-number">1</span>-<span class="hljs-number">1</span>/e**(<span class="hljs-number">0.05</span>*(ddd/<span class="hljs-number">23</span>)))*<span class="hljs-number">500</span>*values[result[i][j]] <span class="hljs-comment"># 货损成本</span><br> fx3 += ddd*<span class="hljs-number">7</span>*values[result[i][j]] <span class="hljs-comment"># 运输费用</span><br><span class="hljs-built_in">print</span>(fx1,fx2,fx3)<br><br>plt.title(<span class="hljs-string">'鲸鱼算法'</span>)<br>plt.plot(<span class="hljs-built_in">range</span>(<span class="hljs-number">1</span>,<span class="hljs-built_in">len</span>(trace)+<span class="hljs-number">1</span>),trace, color=<span class="hljs-string">'r'</span>)<br>plt.show()<br></code></pre></td></tr></table></figure>]]></content>
<categories>
<category>数学建模</category>
</categories>
</entry>
<entry>
<title>改进的鲸鱼算法代码</title>
<link href="/2024/09/11/%E6%94%B9%E8%BF%9B%E7%9A%84%E9%B2%B8%E9%B1%BC%E7%AE%97%E6%B3%95%E4%BB%A3%E7%A0%81/"/>
<url>/2024/09/11/%E6%94%B9%E8%BF%9B%E7%9A%84%E9%B2%B8%E9%B1%BC%E7%AE%97%E6%B3%95%E4%BB%A3%E7%A0%81/</url>
<content type="html"><![CDATA[<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">import</span> numpy <span class="hljs-keyword">as</span> np<br><span class="hljs-keyword">from</span> numpy <span class="hljs-keyword">import</span> random<br><span class="hljs-keyword">from</span> copy <span class="hljs-keyword">import</span> deepcopy<br><span class="hljs-keyword">from</span> tqdm <span class="hljs-keyword">import</span> tqdm<br><span class="hljs-keyword">import</span> matplotlib.pyplot <span class="hljs-keyword">as</span> plt<br><span class="hljs-keyword">import</span> warnings<br>warnings.filterwarnings(<span class="hljs-string">"ignore"</span>)<br>np.set_printoptions(threshold=np.inf) <span class="hljs-comment"># threshold 指定超过多少使用省略号,np.inf代表无限大</span><br>np.set_printoptions(suppress=<span class="hljs-literal">True</span>) <span class="hljs-comment">#不以科学计数法输出</span><br>plt.rcParams[<span class="hljs-string">'axes.unicode_minus'</span>] = <span class="hljs-literal">False</span> <span class="hljs-comment">#显示负号</span><br>plt.rcParams[<span class="hljs-string">'font.family'</span>] = [<span class="hljs-string">'sans-serif'</span>]<br>plt.rcParams[<span class="hljs-string">'font.sans-serif'</span>] = [<span class="hljs-string">'SimHei'</span>] <span class="hljs-comment"># 散点图标签可以显示中文</span><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">fun</span>(<span class="hljs-params">X</span>): <span class="hljs-comment"># 目标函数和约束条件</span><br> x = X.flatten() <span class="hljs-comment">#将X变为一维数组</span><br> fx = <span class="hljs-number">0</span><br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-built_in">len</span>(x)-<span class="hljs-number">1</span>):<br> a = x[i]**<span class="hljs-number">2</span> - <span class="hljs-number">10</span>*np.cos(<span class="hljs-number">2</span>*np.pi*x[i]) + <span class="hljs-number">10</span><br> fx += a<br> fx += -<span class="hljs-number">7</span>*x[-<span class="hljs-number">1</span>]<br> <span class="hljs-keyword">return</span> fx <span class="hljs-comment">#施加惩罚项</span><br><br>s = np.zeros((<span class="hljs-number">1</span>,<span class="hljs-number">30</span>))<br>sub = np.array(s-<span class="hljs-number">10</span>).ravel() <span class="hljs-comment"># 自变量下限</span><br>up = np.array(s+<span class="hljs-number">10</span>).ravel() <span class="hljs-comment"># 自变量上限</span><br><span class="hljs-built_in">type</span> = np.array(s).ravel() <span class="hljs-comment">#-1是有理数,0是整数,1是0-1变量</span><br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">dd2</span>(<span class="hljs-params">best_x, x</span>): <span class="hljs-comment">#欧氏距离</span><br> best_x = np.array(best_x) <span class="hljs-comment">#转化成numpy数组</span><br> x = np.array(x) <span class="hljs-comment">#转化成numpy数组</span><br> c = np.<span class="hljs-built_in">sum</span>(<span class="hljs-built_in">pow</span>(x - best_x, <span class="hljs-number">2</span>), axis=<span class="hljs-number">1</span>) <span class="hljs-comment">#求方差,在行上的标准差</span><br> d = <span class="hljs-built_in">pow</span>(c, <span class="hljs-number">0.5</span>) <span class="hljs-comment">#标准差</span><br> <span class="hljs-keyword">return</span> d<br><span class="hljs-keyword">def</span> <span class="hljs-title function_">new_min</span>(<span class="hljs-params">arr</span>): <span class="hljs-comment">#求最小</span><br> min_data = <span class="hljs-built_in">min</span>(arr) <span class="hljs-comment">#找到最小值</span><br> key = np.argmin(arr) <span class="hljs-comment">#找到最小值的索引</span><br> <span class="hljs-keyword">return</span> min_data, key<br><span class="hljs-keyword">def</span> <span class="hljs-title function_">type_x</span>(<span class="hljs-params">xx,<span class="hljs-built_in">type</span>,n</span>): <span class="hljs-comment">#变量范围约束</span><br> <span class="hljs-keyword">for</span> v <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(n):<br> <span class="hljs-keyword">if</span> <span class="hljs-built_in">type</span>[v] == -<span class="hljs-number">1</span>:<br> xx[v] = np.maximum(sub[v], xx[v])<br> xx[v] = np.minimum(up[v], xx[v])<br> <span class="hljs-keyword">elif</span> <span class="hljs-built_in">type</span>[v] == <span class="hljs-number">0</span>:<br> xx[v] = np.maximum(sub[v], <span class="hljs-built_in">int</span>(xx[v]))<br> xx[v] = np.minimum(up[v], <span class="hljs-built_in">int</span>(xx[v]))<br> <span class="hljs-keyword">else</span>:<br> xx[v] = np.maximum(sub[v], random.randint(<span class="hljs-number">0</span>,<span class="hljs-number">2</span>))<br> xx[v] = np.minimum(up[v], random.randint(<span class="hljs-number">0</span>,<span class="hljs-number">2</span>))<br> <span class="hljs-keyword">return</span> xx<br><span class="hljs-keyword">def</span> <span class="hljs-title function_">woa</span>(<span class="hljs-params">sub,up,<span class="hljs-built_in">type</span>,nums,det</span>):<br> n = <span class="hljs-built_in">len</span>(sub) <span class="hljs-comment"># 自变量个数</span><br> num = nums * n <span class="hljs-comment"># 种群大小</span><br> x = np.zeros([num, n]) <span class="hljs-comment">#生成保存解的矩阵</span><br> f = np.zeros(num) <span class="hljs-comment">#生成保存值的矩阵</span><br> <span class="hljs-keyword">for</span> s <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(num): <span class="hljs-comment">#随机生成初始解</span><br> <span class="hljs-keyword">for</span> v <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(n):<br> rand_data = np.random.uniform(<span class="hljs-number">0</span>,<span class="hljs-number">1</span>)<br> x[s, v] = sub[v] + (up[v] - sub[v]) * rand_data<br> x[s, :] = type_x(x[s, :],<span class="hljs-built_in">type</span>,n)<br> f[s] = fun(x[s, :])<br> best_f, a = new_min(f) <span class="hljs-comment"># 记录历史最优值</span><br> best_x = x[a, :] <span class="hljs-comment"># 记录历史最优解</span><br> trace = np.array([deepcopy(best_f)]) <span class="hljs-comment">#记录初始最优值,以便后期添加最优值画图</span><br> <span class="hljs-comment">############################ 改进的鲸鱼算法 ################################</span><br> xx = np.zeros([num, n])<br> ff = np.zeros(num)<br> Mc = (up - sub) * <span class="hljs-number">0.1</span> <span class="hljs-comment"># 猎物行动最大范围</span><br> <span class="hljs-keyword">for</span> ii <span class="hljs-keyword">in</span> tqdm(<span class="hljs-built_in">range</span>(det)): <span class="hljs-comment">#设置迭代次数,进入迭代过程</span><br> <span class="hljs-comment"># 猎物躲避,蒙特卡洛模拟,并选择最佳的点作为下一逃跑点 #########!!!创新点</span><br> d = dd2(best_x, x) <span class="hljs-comment">#记录当前解与最优解的距离</span><br> d.sort() <span class="hljs-comment">#从小到大排序,d[0]恒为0</span><br> z = np.exp(-d[<span class="hljs-number">1</span>] / np.mean(Mc)) <span class="hljs-comment"># 猎物急躁系数</span><br> z = <span class="hljs-built_in">max</span>(z, <span class="hljs-number">0.1</span>) <span class="hljs-comment">#决定最终系数</span><br> yx = [] <span class="hljs-comment">#初始化存储函数值</span><br> dx = [] <span class="hljs-comment">#初始化存储解</span><br> random_rand = random.random(n) <span class="hljs-comment">#0-1的随机数</span><br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">50</span>): <span class="hljs-comment">#蒙特卡洛模拟的次数</span><br> m = [random.choice([-<span class="hljs-number">1</span>, <span class="hljs-number">1</span>]) <span class="hljs-keyword">for</span> _ <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(n)] <span class="hljs-comment">#随机的-1和1</span><br> asd = best_x + Mc * z * ((det-ii )/det) * random_rand * m <span class="hljs-comment">#最优解更新公式</span><br> xd = type_x(asd,<span class="hljs-built_in">type</span>,n) <span class="hljs-comment">#对自变量进行限制</span><br> <span class="hljs-keyword">if</span> i < <span class="hljs-number">1</span>:<br> dx = deepcopy(xd)<br> <span class="hljs-keyword">else</span>:<br> dx = np.vstack((dx,xd)) <span class="hljs-comment">#存储每一次的解</span><br> yx=np.hstack((yx,fun(xd))) <span class="hljs-comment">#存储每一次的值</span><br> best_t, a = new_min(yx) <span class="hljs-comment"># 选择最佳逃跑点</span><br> best_c = dx[a, :] <span class="hljs-comment">#最佳逃跑点</span><br> <span class="hljs-keyword">if</span> best_t < best_f: <span class="hljs-comment">#与鲸鱼算法得到的最优值对比</span><br> best_f = best_t <span class="hljs-comment">#更新最优值</span><br> best_x = best_c <span class="hljs-comment">#更新最优解</span><br> <span class="hljs-comment">############################# 鲸鱼追捕 #################################</span><br> w = (ii / det)**<span class="hljs-number">3</span> <span class="hljs-comment">#自适应惯性权重!!!创新点</span><br> a = (<span class="hljs-number">2</span> - <span class="hljs-number">2</span>*ii/det)*(<span class="hljs-number">1</span>- w) <span class="hljs-comment">#a随迭代次数从2非线性下降至0!!!创新点</span><br> pp=<span class="hljs-number">0.7</span> <span class="hljs-keyword">if</span> ii <= <span class="hljs-number">0.5</span>*det <span class="hljs-keyword">else</span> <span class="hljs-number">0.4</span><br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(num):<br> r1 = np.random.rand() <span class="hljs-comment"># r1为[0,1]之间的随机数</span><br> r2 = np.random.rand() <span class="hljs-comment"># r2为[0,1]之间的随机数</span><br> A = <span class="hljs-number">2</span> * a * r1 - a<br> C = <span class="hljs-number">2</span> * r2<br> b = <span class="hljs-number">1</span> <span class="hljs-comment">#螺旋形状系数</span><br> l = np.random.uniform(-<span class="hljs-number">1</span>,<span class="hljs-number">1</span>) <span class="hljs-comment">#参数l</span><br> p = np.random.rand()<br> <span class="hljs-keyword">if</span> p < pp:<br> <span class="hljs-keyword">if</span> <span class="hljs-built_in">abs</span>(A) >= <span class="hljs-number">1</span>:<br> rand_leader = np.random.randint(<span class="hljs-number">0</span>, num)<br> X_rand = x[rand_leader, :]<br> D_X_rand = <span class="hljs-built_in">abs</span>(C * X_rand - x[i, :])<br> xx[i, :] = w*X_rand - A * D_X_rand<br> xx[i, :] = type_x(xx[i, :],<span class="hljs-built_in">type</span>,n) <span class="hljs-comment">#对自变量进行限制</span><br> <span class="hljs-keyword">elif</span> <span class="hljs-built_in">abs</span>(A) < <span class="hljs-number">1</span>:<br> D_Leader = <span class="hljs-built_in">abs</span>(C * best_x - x[i, :])<br> xx[i, :] = w*best_x - A * D_Leader<br> xx[i, :] = type_x(xx[i, :],<span class="hljs-built_in">type</span>,n) <span class="hljs-comment">#对自变量进行限制</span><br> <span class="hljs-keyword">elif</span> p >= pp:<br> D = <span class="hljs-built_in">abs</span>(best_x - x[i, :])<br> xx[i, :] = D*np.exp(b*l)*np.cos(<span class="hljs-number">2</span>*np.pi*l) + (<span class="hljs-number">1</span>-w)*best_x <span class="hljs-comment">#完整的气泡网捕食公式</span><br> xx[i, :] = type_x(xx[i, :],<span class="hljs-built_in">type</span>,n) <span class="hljs-comment">#对自变量进行限制</span><br> ff[i] = fun(xx[i, :])<br> <span class="hljs-keyword">if</span> <span class="hljs-built_in">len</span>(np.unique(ff[:i]))/(i+<span class="hljs-number">1</span>) <= <span class="hljs-number">0.1</span>: <span class="hljs-comment">#limit阈值 + 随机差分变异!!!创新点</span><br> xx[i,:] = (r1*(best_x-xx[i,:]) +<br> r2*(x[np.random.randint(<span class="hljs-number">0</span>,num),:] - xx[i,:]))<br> xx[i, :] = type_x(xx[i, :],<span class="hljs-built_in">type</span>,n) <span class="hljs-comment">#对自变量进行限制</span><br> ff[i] = fun(xx[i, :])<br> <span class="hljs-comment">#将上一代种群与这一代种群以及最优种群结合,选取排名靠前的个体组成新的种群</span><br> F = np.hstack((np.array([best_f]), f, ff))<br> F, b = np.sort(F,axis=-<span class="hljs-number">1</span>,kind=<span class="hljs-string">'stable'</span>), np.argsort(F)<span class="hljs-comment">#按小到大排序,获得靠前的位置</span><br> X = np.vstack(([best_x], x, xx))[b, :]<br> f = F[:num] <span class="hljs-comment">#新种群的位置</span><br> x = X[:num, :] <span class="hljs-comment">#新种群的位置</span><br> best_f, a = new_min(f) <span class="hljs-comment"># 记录历史最优值</span><br> best_x = x[a , :] <span class="hljs-comment"># 记录历史最优解</span><br> trace = np.hstack((trace, [best_f]))<br> <span class="hljs-keyword">return</span> best_x,best_f,trace<br><br>best_x,best_f,trace = woa(sub,up,<span class="hljs-built_in">type</span>,<span class="hljs-number">20</span>,<span class="hljs-number">60</span>) <span class="hljs-comment">#种群大小,迭代次数</span><br><span class="hljs-comment">#种群大小可以为自变量个数,迭代次数看情况</span><br><span class="hljs-built_in">print</span>(<span class="hljs-string">'最优解为:'</span>)<br><span class="hljs-built_in">print</span>(best_x)<br><span class="hljs-built_in">print</span>(<span class="hljs-string">'最优值为:'</span>)<br><span class="hljs-built_in">print</span>(<span class="hljs-built_in">float</span>(best_f))<br><br>plt.title(<span class="hljs-string">'鲸鱼算法'</span>)<br>plt.plot(<span class="hljs-built_in">range</span>(<span class="hljs-number">1</span>,<span class="hljs-built_in">len</span>(trace)+<span class="hljs-number">1</span>),trace, color=<span class="hljs-string">'r'</span>)<br>plt.show()<br></code></pre></td></tr></table></figure>]]></content>
<categories>
<category>数学建模</category>
</categories>
</entry>
<entry>
<title>生死狙击2净化行动挂机脚本</title>
<link href="/2024/07/21/%E7%94%9F%E6%AD%BB%E7%8B%99%E5%87%BB2%E5%87%80%E5%8C%96%E8%A1%8C%E5%8A%A8%E6%8C%82%E6%9C%BA%E8%84%9A%E6%9C%AC/"/>
<url>/2024/07/21/%E7%94%9F%E6%AD%BB%E7%8B%99%E5%87%BB2%E5%87%80%E5%8C%96%E8%A1%8C%E5%8A%A8%E6%8C%82%E6%9C%BA%E8%84%9A%E6%9C%AC/</url>
<content type="html"><![CDATA[<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">import</span> pyautogui<br><span class="hljs-keyword">import</span> pydirectinput<br><span class="hljs-keyword">import</span> time<br><span class="hljs-keyword">import</span> os<br><span class="hljs-keyword">import</span> sys<br>pyautogui.PAUSE = <span class="hljs-number">0</span><br><span class="hljs-comment">#适用于净化行动,关闭自动匹配队友,开启单人匹配,在开始匹配页面运行程序。</span><br><span class="hljs-comment">######### 以管理员身份运行!!!! ###########</span><br><span class="hljs-comment"># 获取图片的绝对路径</span><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">get_resource_path</span>(<span class="hljs-params">relative_path</span>):<br> <span class="hljs-keyword">if</span> <span class="hljs-built_in">hasattr</span>(sys, <span class="hljs-string">'_MEIPASS'</span>):<br> <span class="hljs-keyword">return</span> os.path.join(sys._MEIPASS, relative_path)<br> <span class="hljs-keyword">return</span> os.path.join(os.path.abspath(<span class="hljs-string">"."</span>), relative_path)<br><span class="hljs-comment">#局内动作循环</span><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">repeat_keys</span>(<span class="hljs-params">keys</span>):<br> <span class="hljs-keyword">try</span>:<br> a = time.time()<br> bb = time.time()<br> <span class="hljs-keyword">while</span> a-bb+<span class="hljs-number">5000</span>><span class="hljs-number">0</span>:<br> <span class="hljs-keyword">for</span> key <span class="hljs-keyword">in</span> keys:<br> pyautogui.keyDown(key)<br> time.sleep(<span class="hljs-number">1</span>)<br> pyautogui.keyUp(key)<br> time.sleep(<span class="hljs-number">9</span>)<br> bb = time.time()<br> pyautogui.press(<span class="hljs-string">'esc'</span>)<br> <span class="hljs-keyword">except</span> KeyboardInterrupt:<br> <span class="hljs-built_in">print</span>(<span class="hljs-string">"Stopped by user"</span>)<br><span class="hljs-comment">#检测图片</span><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">identify_picture</span>(<span class="hljs-params">a</span>):<br> left, top, width, height = pyautogui.locateOnScreen(get_resource_path(a),confidence=<span class="hljs-number">0.9</span>,grayscale=<span class="hljs-literal">True</span>) <span class="hljs-comment"># 寻找图片</span><br> center = pyautogui.center((left, top, width, height)) <span class="hljs-comment"># 寻找图片的中心</span><br> <span class="hljs-built_in">print</span>(<span class="hljs-string">'开始'</span>,center)<br> pydirectinput.moveTo(center[<span class="hljs-number">0</span>],center[<span class="hljs-number">1</span>])<br> pydirectinput.click()<br> time.sleep(<span class="hljs-number">10</span>)<br><span class="hljs-comment"># 4:3比例 + 无边框窗口</span><br><span class="hljs-keyword">while</span> <span class="hljs-literal">True</span>:<br> <span class="hljs-keyword">try</span>:<br> identify_picture(<span class="hljs-string">'img\sta1.png'</span>) <span class="hljs-comment">#检测开始匹配</span><br> <span class="hljs-keyword">except</span> TypeError:<br> <span class="hljs-keyword">try</span>:<br> identify_picture(<span class="hljs-string">'img\\bac.png'</span>) <span class="hljs-comment">#检测返回大厅</span><br> <span class="hljs-keyword">except</span> TypeError:<br> <span class="hljs-keyword">try</span>:<br> identify_picture(<span class="hljs-string">'img\\img.png'</span>) <span class="hljs-comment">#检测准备完毕</span><br> repeat_keys([<span class="hljs-string">'w'</span>, <span class="hljs-string">'a'</span>, <span class="hljs-string">'s'</span>, <span class="hljs-string">'d'</span>]) <span class="hljs-comment">#局内动作,防止强退</span><br> <span class="hljs-keyword">except</span> TypeError:<br> <span class="hljs-keyword">try</span>:<br> identify_picture(<span class="hljs-string">'img\\img_1.png'</span>) <span class="hljs-comment">#检测返回大厅(出错情况)</span><br> <span class="hljs-keyword">except</span> TypeError:<br> <span class="hljs-keyword">try</span>:<br> identify_picture(<span class="hljs-string">'img\\img_2.png'</span>) <span class="hljs-comment">#检测确定(出错情况)</span><br> <span class="hljs-keyword">except</span> TypeError:<br> <span class="hljs-keyword">try</span>:<br> identify_picture(<span class="hljs-string">'img\\img_3.png'</span>) <span class="hljs-comment">#检测点击空白处关闭(出错情况)</span><br> <span class="hljs-keyword">except</span> TypeError:<br> <span class="hljs-built_in">print</span>(<span class="hljs-string">'无'</span>)<br> time.sleep(<span class="hljs-number">2</span>)<br></code></pre></td></tr></table></figure>]]></content>
<categories>
<category>游戏</category>
<category>自动化</category>
</categories>
</entry>
<entry>
<title>数据结构之栈与队列代码</title>
<link href="/2024/02/03/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E4%B9%8B%E6%A0%88%E4%B8%8E%E9%98%9F%E5%88%97%E4%BB%A3%E7%A0%81/"/>
<url>/2024/02/03/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E4%B9%8B%E6%A0%88%E4%B8%8E%E9%98%9F%E5%88%97%E4%BB%A3%E7%A0%81/</url>
<content type="html"><![CDATA[<h1 id="一,顺序栈"><a href="#一,顺序栈" class="headerlink" title="一,顺序栈"></a>一,顺序栈</h1><h2 id="顺序栈的定义:"><a href="#顺序栈的定义:" class="headerlink" title="顺序栈的定义:"></a><strong>顺序栈的定义:</strong></h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-meta">#<span class="hljs-keyword">define</span> MaxSize 10 <span class="hljs-comment">//定义栈中元素的最大个数</span></span><br><span class="hljs-keyword">typedef</span> <span class="hljs-keyword">struct</span>{<br> ElemType data[MaxSize]; <span class="hljs-comment">//静态数组存放栈中元素</span><br> <span class="hljs-type">int</span> top; <span class="hljs-comment">//栈顶元素</span><br>}SqStack;<br></code></pre></td></tr></table></figure><h2 id="顺序栈的初始化:"><a href="#顺序栈的初始化:" class="headerlink" title="顺序栈的初始化:"></a><strong>顺序栈的初始化:</strong></h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-meta">#<span class="hljs-keyword">define</span> MaxSize 10</span><br><span class="hljs-keyword">typedef</span> <span class="hljs-keyword">struct</span>{<br> ElemType data[MaxSize];<br> <span class="hljs-type">int</span> top;<br>}SqStack;<br><br><span class="hljs-comment">// 初始化栈</span><br><span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">InitStack</span><span class="hljs-params">(SqStack &S)</span></span>{<br> S.top = <span class="hljs-number">-1</span>;<span class="hljs-comment">//初始化栈顶指针</span><br>}<br><br><span class="hljs-comment">// 判断栈是否为空</span><br><span class="hljs-function"><span class="hljs-type">bool</span> <span class="hljs-title">StackEmpty</span><span class="hljs-params">(SqStack S)</span></span>{<br> <span class="hljs-keyword">if</span>(S.top == <span class="hljs-number">-1</span>)<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;<br> <span class="hljs-keyword">else</span><br> <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;<br>}<br></code></pre></td></tr></table></figure><h2 id="入栈出栈:"><a href="#入栈出栈:" class="headerlink" title="入栈出栈:"></a><strong>入栈出栈:</strong></h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-comment">// 新元素进栈</span><br><span class="hljs-function"><span class="hljs-type">bool</span> <span class="hljs-title">Push</span><span class="hljs-params">(SqStack &S, ElemType x)</span></span>{<br> <span class="hljs-comment">// 判断栈是否已满</span><br> <span class="hljs-keyword">if</span>(S.top == MaxSize - <span class="hljs-number">1</span>)<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;<br> S.data[++S.top] = x;<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;<br>}<br><br><span class="hljs-comment">// 出栈</span><br><span class="hljs-function"><span class="hljs-type">bool</span> <span class="hljs-title">Pop</span><span class="hljs-params">(SqStack &x, ElemType &x)</span></span>{<br> <span class="hljs-comment">// 判断栈是否为空</span><br> <span class="hljs-keyword">if</span>(S.top == <span class="hljs-number">-1</span>)<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;<br> x = S.data[S.top--];<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;<br>}<br></code></pre></td></tr></table></figure><h2 id="读取栈顶元素:"><a href="#读取栈顶元素:" class="headerlink" title="读取栈顶元素:"></a><strong>读取栈顶元素:</strong></h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-comment">// 读栈顶元素</span><br><span class="hljs-function"><span class="hljs-type">bool</span> <span class="hljs-title">GetTop</span><span class="hljs-params">(SqStack S, ElemType &x)</span></span>{<br> <span class="hljs-keyword">if</span>(S.top == <span class="hljs-number">-1</span>)<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;<br> x = S.data[S.top];<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;<br>}<br></code></pre></td></tr></table></figure><h2 id="共享栈(两个栈共享同一片空间):"><a href="#共享栈(两个栈共享同一片空间):" class="headerlink" title="共享栈(两个栈共享同一片空间):"></a><strong>共享栈(两个栈共享同一片空间):</strong></h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-meta">#<span class="hljs-keyword">define</span> MaxSize 10 <span class="hljs-comment">//定义栈中元素的最大个数</span></span><br><span class="hljs-keyword">typedef</span> <span class="hljs-keyword">struct</span>{<br> ElemType data[MaxSize];<span class="hljs-comment">//静态数组存放栈中元素</span><br> <span class="hljs-type">int</span> top0; <span class="hljs-comment">//0号栈栈顶指针</span><br> <span class="hljs-type">int</span> top1; <span class="hljs-comment">//1号栈栈顶指针</span><br>}ShStack;<br><br><span class="hljs-comment">// 初始化栈</span><br><span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">InitSqStack</span><span class="hljs-params">(ShStack &S)</span></span>{<br> S.top0 = <span class="hljs-number">-1</span>;<br> S.top1 = MaxSize;<br>}<br></code></pre></td></tr></table></figure><h1 id="二,链栈"><a href="#二,链栈" class="headerlink" title="二,链栈"></a>二,链栈</h1><h2 id="链栈的定义:"><a href="#链栈的定义:" class="headerlink" title="链栈的定义:"></a><strong>链栈的定义:</strong></h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-keyword">typedef</span> <span class="hljs-keyword">struct</span> <span class="hljs-title class_">Linknode</span>{<br> ElemType data;<span class="hljs-comment">//数据域</span><br> Linknode *next;<span class="hljs-comment">//指针域</span><br>}Linknode,*LiStack;<br><br><span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">testStack</span><span class="hljs-params">()</span></span>{<br> LiStack L;<span class="hljs-comment">//声明一个链栈</span><br>}<br></code></pre></td></tr></table></figure><h2 id="链栈的初始化:"><a href="#链栈的初始化:" class="headerlink" title="链栈的初始化:"></a><strong>链栈的初始化:</strong></h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-keyword">typedef</span> <span class="hljs-keyword">struct</span> <span class="hljs-title class_">Linknode</span>{<br> ElemType data;<br> Linknode *next;<br>}Linknode,*LiStack;<br><br><span class="hljs-comment">// 初始化栈</span><br><span class="hljs-function"><span class="hljs-type">bool</span> <span class="hljs-title">InitStack</span><span class="hljs-params">(LiStack &L)</span></span>{<br> L = (Linknode *)<span class="hljs-built_in">malloc</span>(<span class="hljs-built_in">sizeof</span>(Linknode));<br> <span class="hljs-keyword">if</span>(L == <span class="hljs-literal">NULL</span>)<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;<br> L->next = <span class="hljs-literal">NULL</span>;<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;<br>}<br><br><span class="hljs-comment">// 判断栈是否为空</span><br><span class="hljs-function"><span class="hljs-type">bool</span> <span class="hljs-title">isEmpty</span><span class="hljs-params">(LiStack &L)</span></span>{<br> <span class="hljs-keyword">if</span>(L->next == <span class="hljs-literal">NULL</span>)<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;<br> <span class="hljs-keyword">else</span><br> <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;<br>}<br></code></pre></td></tr></table></figure><h2 id="入栈出栈:-1"><a href="#入栈出栈:-1" class="headerlink" title="入栈出栈:"></a><strong>入栈出栈:</strong></h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-comment">// 新元素入栈</span><br><span class="hljs-function"><span class="hljs-type">bool</span> <span class="hljs-title">pushStack</span><span class="hljs-params">(LiStack &L,ElemType x)</span></span>{<br> Linknode *s = (Linknode *)<span class="hljs-built_in">malloc</span>(<span class="hljs-built_in">sizeof</span>(Linknode));<br> <span class="hljs-keyword">if</span>(s == <span class="hljs-literal">NULL</span>)<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;<br> s->data = x;<br> <span class="hljs-comment">// 头插法</span><br> s->next = L->next;<br> L->next = s;<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;<br>}<br><br><span class="hljs-comment">// 出栈</span><br><span class="hljs-function"><span class="hljs-type">bool</span> <span class="hljs-title">popStack</span><span class="hljs-params">(LiStack &L, <span class="hljs-type">int</span> &x)</span></span>{<br> <span class="hljs-comment">// 栈空不能出栈</span><br> <span class="hljs-keyword">if</span>(L->next == <span class="hljs-literal">NULL</span>)<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;<br> Linknode *s = L->next;<br> x = s->data;<br> L->next = s->next;<br> <span class="hljs-built_in">free</span>(s);<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;<br>}<br></code></pre></td></tr></table></figure><h1 id="三,顺序队列"><a href="#三,顺序队列" class="headerlink" title="三,顺序队列"></a>三,顺序队列</h1><h2 id="顺序队列的定义:"><a href="#顺序队列的定义:" class="headerlink" title="顺序队列的定义:"></a><strong>顺序队列的定义:</strong></h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-meta">#<span class="hljs-keyword">define</span> MaxSize 10;<span class="hljs-comment">//定义队列中元素的最大个数</span></span><br><span class="hljs-keyword">typedef</span> <span class="hljs-keyword">struct</span>{<br> ElemType data[MaxSize];<span class="hljs-comment">//用静态数组存放队列元素</span><br> <span class="hljs-type">int</span> front, rear; <span class="hljs-comment">//队头指针和队尾指针</span><br>}SqQueue;<br><br><span class="hljs-type">void</span> test{<br> SqQueue Q;<span class="hljs-comment">//声明一个队列</span><br>}<br></code></pre></td></tr></table></figure><h2 id="顺序队列的初始化:"><a href="#顺序队列的初始化:" class="headerlink" title="顺序队列的初始化:"></a><strong>顺序队列的初始化:</strong></h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-meta">#<span class="hljs-keyword">define</span> MaxSize 10;</span><br><span class="hljs-keyword">typedef</span> <span class="hljs-keyword">struct</span>{<br> ElemType data[MaxSize];<br> <span class="hljs-type">int</span> front, rear;<br>}SqQueue;<br><br><span class="hljs-comment">// 初始化队列</span><br><span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">InitQueue</span><span class="hljs-params">(SqQueue &Q)</span></span>{<br> <span class="hljs-comment">// 初始化时,队头、队尾指针指向0</span><br> <span class="hljs-comment">// 队尾指针指向的是即将插入数据的数组下标</span><br> <span class="hljs-comment">// 队头指针指向的是队头元素的数组下标</span><br> Q.rear = Q.front = <span class="hljs-number">0</span>;<br>}<br><br><span class="hljs-comment">// 判断队列是否为空</span><br><span class="hljs-function"><span class="hljs-type">bool</span> <span class="hljs-title">QueueEmpty</span><span class="hljs-params">(SqQueue Q)</span></span>{<br> <span class="hljs-keyword">if</span>(Q.rear == Q.front)<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;<br> <span class="hljs-keyword">else</span><br> <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;<br>}<br></code></pre></td></tr></table></figure><h2 id="入队出队(循环队列):"><a href="#入队出队(循环队列):" class="headerlink" title="入队出队(循环队列):"></a><strong>入队出队(循环队列):</strong></h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-comment">// 新元素入队</span><br><span class="hljs-function"><span class="hljs-type">bool</span> <span class="hljs-title">EnQueue</span><span class="hljs-params">(SqQueue &Q, ElemType x)</span></span>{<br> <span class="hljs-comment">// 如果队列已满直接返回</span><br> <span class="hljs-keyword">if</span>((Q.rear+<span class="hljs-number">1</span>)%MaxSize == Q.front)<span class="hljs-comment">//牺牲一个单元区分队空和队满</span><br><span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;<br> Q.data[Q.rear] = x;<br> Q.rear = (Q.rear+<span class="hljs-number">1</span>)%MaxSize;<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;<br>}<br><br><span class="hljs-comment">// 出队</span><br><span class="hljs-function"><span class="hljs-type">bool</span> <span class="hljs-title">DeQueue</span><span class="hljs-params">(SqQueue &Q, ElemType &x)</span></span>{<br> <span class="hljs-comment">// 如果队列为空直接返回</span><br> <span class="hljs-keyword">if</span>(Q.rear == Q.front)<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;<br> x = Q.data[Q.front];<br> Q.front = (Q.front+<span class="hljs-number">1</span>)%MaxSize;<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;<br>}<br></code></pre></td></tr></table></figure><h2 id="获得队头元素:"><a href="#获得队头元素:" class="headerlink" title="获得队头元素:"></a><strong>获得队头元素:</strong></h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-comment">// 获取队头元素并存入x</span><br><span class="hljs-function"><span class="hljs-type">bool</span> <span class="hljs-title">GetHead</span><span class="hljs-params">(SqQueue &Q, ElemType &x)</span></span>{<br> <span class="hljs-keyword">if</span>(Q.rear == Q.front)<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;<br> x = Q.data[Q.front];<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;<br>}<br></code></pre></td></tr></table></figure><h1 id="四,链队列"><a href="#四,链队列" class="headerlink" title="四,链队列"></a>四,链队列</h1><h2 id="链队列的定义:"><a href="#链队列的定义:" class="headerlink" title="链队列的定义:"></a><strong>链队列的定义:</strong></h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-comment">// 链式队列结点</span><br><span class="hljs-keyword">typedef</span> <span class="hljs-keyword">struct</span> <span class="hljs-title class_">LinkNode</span>{<br> ElemType data;<br> <span class="hljs-keyword">struct</span> <span class="hljs-title class_">LinkNode</span> *next;<br>}<br><br><span class="hljs-comment">// 链式队列</span><br><span class="hljs-keyword">typedef</span> <span class="hljs-keyword">struct</span>{<br> <span class="hljs-comment">// 头指针和尾指针</span><br> LinkNode *front, *rear;<br>}LinkQueue;<br></code></pre></td></tr></table></figure><h2 id="链队列的初始化(带头结点):"><a href="#链队列的初始化(带头结点):" class="headerlink" title="链队列的初始化(带头结点):"></a><strong>链队列的初始化(带头结点):</strong></h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-keyword">typedef</span> <span class="hljs-keyword">struct</span> <span class="hljs-title class_">LinkNode</span>{<br> ElemType data;<br> <span class="hljs-keyword">struct</span> <span class="hljs-title class_">LinkNode</span> *next;<br>}LinkNode;<br><br><span class="hljs-keyword">typedef</span> <span class="hljs-keyword">struct</span>{<br> LinkNode *front, *rear;<br>}LinkQueue;<br><br><span class="hljs-comment">// 初始化队列</span><br><span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">InitQueue</span><span class="hljs-params">(LinkQueue &Q)</span></span>{<br> <span class="hljs-comment">// 初始化时,front、rear都指向头结点</span><br> Q.front = Q.rear = (LinkNode *)<span class="hljs-built_in">malloc</span>(<span class="hljs-built_in">sizeof</span>(LinkNode));<br> Q.front -> next = <span class="hljs-literal">NULL</span>;<br>}<br><br><span class="hljs-comment">// 判断队列是否为空</span><br><span class="hljs-function"><span class="hljs-type">bool</span> <span class="hljs-title">IsEmpty</span><span class="hljs-params">(LinkQueue Q)</span></span>{<br> <span class="hljs-keyword">if</span>(Q.front == Q.rear)<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;<br> <span class="hljs-keyword">else</span><br> <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;<br>}<br></code></pre></td></tr></table></figure><h2 id="入队出队:"><a href="#入队出队:" class="headerlink" title="入队出队:"></a><strong>入队出队:</strong></h2><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-comment">// 新元素入队</span><br><span class="hljs-type">void</span> <span class="hljs-title function_">EnQueue</span><span class="hljs-params">(LinkQueue &Q, ElemType x)</span>{<br> LinkNode *s = (LinkNode *)<span class="hljs-built_in">malloc</span>(<span class="hljs-keyword">sizeof</span>(LinkNode));<br> s->data = x;<br> s->next = <span class="hljs-literal">NULL</span>;<br> Q.rear->next = s;<br> Q.rear = s;<br>}<br><br><span class="hljs-comment">// 队头元素出队</span><br><span class="hljs-type">bool</span> <span class="hljs-title function_">DeQueue</span><span class="hljs-params">(LinkQueue &Q, ElemType &x)</span>{<br> <span class="hljs-keyword">if</span>(Q.front == Q.rear)<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;<br> LinkNode *p = Q.front->next;<br> x = p->data;<br> Q.front->next = p->next;<br> <span class="hljs-comment">// 如果p是最后一个结点,则将队头指针也指向NULL</span><br> <span class="hljs-keyword">if</span>(Q.rear == p)<br> Q.rear = Q.front;<br> <span class="hljs-built_in">free</span>(p);<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;<br>}<br></code></pre></td></tr></table></figure><h2 id="以上是带头结点的链队列,下面是不带头结点的操作:"><a href="#以上是带头结点的链队列,下面是不带头结点的操作:" class="headerlink" title="以上是带头结点的链队列,下面是不带头结点的操作:"></a><strong>以上是带头结点的链队列,下面是不带头结点的操作:</strong></h2><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-keyword">typedef</span> <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">LinkNode</span>{</span><br> ElemType data;<br> <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">LinkNode</span> *<span class="hljs-title">next</span>;</span><br>}LinkNode;<br><br><span class="hljs-keyword">typedef</span> <span class="hljs-class"><span class="hljs-keyword">struct</span>{</span><br> LinkNode *front, *rear;<br>}LinkQueue;<br><br><span class="hljs-comment">// 初始化队列</span><br><span class="hljs-type">void</span> <span class="hljs-title function_">InitQueue</span><span class="hljs-params">(LinkQueue &Q)</span>{<br> <span class="hljs-comment">// 不带头结点的链队列初始化,头指针和尾指针都指向NULL</span><br> Q.front = <span class="hljs-literal">NULL</span>;<br> Q.rear = <span class="hljs-literal">NULL</span>;<br>}<br><br><span class="hljs-comment">// 判断队列是否为空</span><br><span class="hljs-type">bool</span> <span class="hljs-title function_">IsEmpty</span><span class="hljs-params">(LinkQueue Q)</span>{<br> <span class="hljs-keyword">if</span>(Q.front == <span class="hljs-literal">NULL</span>)<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;<br> <span class="hljs-keyword">else</span><br> <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;<br>}<br><br><span class="hljs-comment">// 新元素入队</span><br><span class="hljs-type">void</span> <span class="hljs-title function_">EnQueue</span><span class="hljs-params">(LinkQueue &Q, ElemType x)</span>{<br> LinkNode *s = (LinkNode *)<span class="hljs-built_in">malloc</span>(<span class="hljs-keyword">sizeof</span>(LinkNode));<br> s->data = x;<br> s->next = <span class="hljs-literal">NULL</span>;<br> <span class="hljs-comment">// 第一个元素入队时需要特别处理</span><br> <span class="hljs-keyword">if</span>(Q.front == <span class="hljs-literal">NULL</span>){<br> Q.front = s;<br> Q.rear = s;<br> }<span class="hljs-keyword">else</span>{<br> Q.rear->next = s;<br> Q.rear = s;<br> }<br>}<br><br><span class="hljs-comment">//队头元素出队</span><br><span class="hljs-type">bool</span> <span class="hljs-title function_">DeQueue</span><span class="hljs-params">(LinkQueue &Q, ElemType &x)</span>{<br> <span class="hljs-keyword">if</span>(Q.front == <span class="hljs-literal">NULL</span>)<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;<br> LinkNode *s = Q.front;<br> x = s->data;<br> <span class="hljs-keyword">if</span>(Q.front == Q.rear){<br> Q.front = Q.rear = <span class="hljs-literal">NULL</span>;<br> }<span class="hljs-keyword">else</span>{<br> Q.front = Q.front->next;<br> }<br> <span class="hljs-built_in">free</span>(s);<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;<br>}<br></code></pre></td></tr></table></figure><p>参考自:<a href="https://blog.csdn.net/qq_55593227/article/details/123598044">https://blog.csdn.net/qq_55593227/article/details/123598044</a></p>]]></content>
<categories>
<category>考研408</category>
</categories>
</entry>
<entry>
<title>数据结构之线性表代码</title>
<link href="/2024/02/02/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E4%B9%8B%E7%BA%BF%E6%80%A7%E8%A1%A8%E4%BB%A3%E7%A0%81/"/>
<url>/2024/02/02/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E4%B9%8B%E7%BA%BF%E6%80%A7%E8%A1%A8%E4%BB%A3%E7%A0%81/</url>
<content type="html"><![CDATA[<h1 id="一,顺序表"><a href="#一,顺序表" class="headerlink" title="一,顺序表"></a>一,顺序表</h1><h2 id="1-1-顺序表的实现"><a href="#1-1-顺序表的实现" class="headerlink" title="1.1 顺序表的实现"></a>1.1 顺序表的实现</h2><h3 id="静态实现:"><a href="#静态实现:" class="headerlink" title="静态实现:"></a><strong>静态实现:</strong></h3><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-meta">#<span class="hljs-keyword">define</span> MaxSize 10 <span class="hljs-comment">// 定义最大长度 </span></span><br><br><span class="hljs-keyword">typedef</span> <span class="hljs-keyword">struct</span> {<br><span class="hljs-type">int</span> data[MaxSize]; <span class="hljs-comment">// 使用静态的数组存放数据元素 </span><br><span class="hljs-type">int</span> length; <span class="hljs-comment">// 顺序表的当前长度 </span><br>}SqList;<br><br><span class="hljs-comment">// 初始化顺序表 </span><br><span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">InitList</span><span class="hljs-params">(SqList &L)</span> </span>{<br>L.length = <span class="hljs-number">0</span>; <span class="hljs-comment">// 顺序表初始长度为0 </span><br>}<br><br><span class="hljs-function"><span class="hljs-type">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>{<br>SqList L; <span class="hljs-comment">// 声明一个顺序表 </span><br><span class="hljs-built_in">InitList</span>(L); <span class="hljs-comment">// 初始化顺序表 </span><br><span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>}<br></code></pre></td></tr></table></figure><h3 id="动态实现:"><a href="#动态实现:" class="headerlink" title="动态实现:"></a><strong>动态实现:</strong></h3><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-meta">#<span class="hljs-keyword">define</span> MaxSize 10 <span class="hljs-comment">// 定义最大长度 </span></span><br><span class="hljs-meta">#<span class="hljs-keyword">define</span> InitSize 10 <span class="hljs-comment">// 顺序表的初始长度</span></span><br><br><span class="hljs-keyword">typedef</span> <span class="hljs-keyword">struct</span> {<br><span class="hljs-type">int</span> *data; <span class="hljs-comment">// 声明动态分配数组的指针 </span><br><span class="hljs-type">int</span> MaxSize; <span class="hljs-comment">// 顺序表的最大容量</span><br><span class="hljs-type">int</span> length; <span class="hljs-comment">// 顺序表的当前长度 </span><br>}SeqList;<br><br><span class="hljs-comment">// 初始化顺序表 </span><br><span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">InitList</span><span class="hljs-params">(SeqList &L)</span> </span>{<br><span class="hljs-comment">// 用malloc函数申请一片连续的存储空间 </span><br>L.data = (<span class="hljs-type">int</span> *)<span class="hljs-built_in">malloc</span>(InitSize * <span class="hljs-built_in">sizeof</span>(<span class="hljs-type">int</span>));<br>L.length = <span class="hljs-number">0</span>;<br>L.MaxSize = InitSize;<br>}<br><br><span class="hljs-comment">// 增加动态数组的长度 ,非重点</span><br><span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">IncreaseSize</span><span class="hljs-params">(SeqList &L, <span class="hljs-type">int</span> len)</span> </span>{<br><span class="hljs-type">int</span> *p = L.data;<br>L.data = (<span class="hljs-type">int</span> *)<span class="hljs-built_in">malloc</span>((L.MaxSize+len) * <span class="hljs-built_in">sizeof</span>(<span class="hljs-type">int</span>));<br><span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> i = <span class="hljs-number">0</span>; i < L.length; i++)<br>L.data[i] = p[i]; <span class="hljs-comment">// 将数据复制到新区域 </span><br>L.MaxSize = L.MaxSize + len; <span class="hljs-comment">// 顺序表最大长度增加len </span><br><span class="hljs-built_in">free</span>(p); <span class="hljs-comment">// 释放原来的内存空间 </span><br>}<br><br><span class="hljs-function"><span class="hljs-type">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>{<br>SeqList L; <span class="hljs-comment">// 声明一个顺序表 </span><br><span class="hljs-built_in">InitList</span>(L); <span class="hljs-comment">// 初始化顺序表 </span><br> ...<br><span class="hljs-built_in">IncreaseSize</span>(L, <span class="hljs-number">5</span>);<br><span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>}<br></code></pre></td></tr></table></figure><blockquote><p>malloc() 函数的作用:会申请一片存储空间,并返回存储空间第一个位置的地址,也就是该位置的指针。</p></blockquote><h2 id="1-2-顺序表的基本操作"><a href="#1-2-顺序表的基本操作" class="headerlink" title="1.2 顺序表的基本操作"></a>1.2 顺序表的基本操作</h2><h3 id="插入:"><a href="#插入:" class="headerlink" title="插入:"></a><strong>插入:</strong></h3><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-comment">// 在顺序表i位置插入e</span><br><span class="hljs-function"><span class="hljs-type">bool</span> <span class="hljs-title">ListInsert</span><span class="hljs-params">(SqList &L, <span class="hljs-type">int</span> i, <span class="hljs-type">int</span> e)</span> </span>{<br><span class="hljs-keyword">if</span> (i < <span class="hljs-number">1</span> || i > L.length+<span class="hljs-number">1</span>) <span class="hljs-comment">// 判断i的范围是否有效 </span><br><span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;<br><span class="hljs-keyword">if</span> (L.length >= MaxSize) <span class="hljs-comment">// 判断存储空间是否已满 </span><br><span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;<br><span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> j = L.length; j >= i; j--) <span class="hljs-comment">// 将第i个元素之后的元素后移 </span><br>L.data[j] = L.data[j<span class="hljs-number">-1</span>];<br>L.data[i<span class="hljs-number">-1</span>] = e; <span class="hljs-comment">// 在位置i处放入e </span><br>L.length++; <span class="hljs-comment">// 长度+1 </span><br><span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;<br>} <br></code></pre></td></tr></table></figure><p>时间复杂度:</p><ul><li>最好时间复杂度:O ( 1 )</li><li>最坏时间复杂度:O ( n )</li><li>平均时间复杂度:O ( n )</li></ul><h3 id="删除:"><a href="#删除:" class="headerlink" title="删除:"></a><strong>删除:</strong></h3><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-comment">// 删除顺序表i位置的数据并存入e</span><br><span class="hljs-function"><span class="hljs-type">bool</span> <span class="hljs-title">ListDelete</span><span class="hljs-params">(SqList &L, <span class="hljs-type">int</span> i, <span class="hljs-type">int</span> &e)</span> </span>{<br><span class="hljs-keyword">if</span> (i < <span class="hljs-number">1</span> || i > L.length) <span class="hljs-comment">// 判断i的范围是否有效</span><br><span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;<br>e = L.data[i<span class="hljs-number">-1</span>]; <span class="hljs-comment">// 将被删除的元素赋值给e </span><br><span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> j = i; j < L.length; j++) <span class="hljs-comment">//将第i个位置后的元素前移 </span><br>L.data[j<span class="hljs-number">-1</span>] = L.data[j];<br>L.length--;<br><span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>; <br>}<br></code></pre></td></tr></table></figure><p>时间复杂度:</p><ul><li>最好时间复杂度:O ( 1 )</li><li>最坏时间复杂度:O ( n )</li><li>平均时间复杂度:O ( n )</li></ul><h3 id="按位查找:"><a href="#按位查找:" class="headerlink" title="按位查找:"></a><strong>按位查找:</strong></h3><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-comment">// 静态分配的按位查找</span><br><span class="hljs-meta">#<span class="hljs-keyword">define</span> MaxSize 10</span><br><br><span class="hljs-function">ElemType <span class="hljs-title">GetElem</span><span class="hljs-params">(SqList L, <span class="hljs-type">int</span> i)</span> </span>{<br><span class="hljs-keyword">return</span> L.data[i<span class="hljs-number">-1</span>];<br>}<br></code></pre></td></tr></table></figure><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-comment">// 动态分配的按位查找</span><br><span class="hljs-meta">#<span class="hljs-keyword">define</span> InitSize 10</span><br><br><span class="hljs-function">ElemType <span class="hljs-title">GetElem</span><span class="hljs-params">(SeqList L, <span class="hljs-type">int</span> i)</span> </span>{<br><span class="hljs-keyword">return</span> L.data[i<span class="hljs-number">-1</span>];<br>}<br></code></pre></td></tr></table></figure><p>时间复杂度: O ( 1 )</p><h3 id="按值查找:"><a href="#按值查找:" class="headerlink" title="按值查找:"></a><strong>按值查找:</strong></h3><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-comment">// 查找第一个元素值为e的元素,并返回其位序 </span><br><span class="hljs-function"><span class="hljs-type">int</span> <span class="hljs-title">LocateElem</span><span class="hljs-params">(SqList L, ElemType e)</span> </span>{<br><span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> i = <span class="hljs-number">0</span>; i < L.length; i++)<br><span class="hljs-keyword">if</span> (L.data[i] == e)<br><span class="hljs-keyword">return</span> i+<span class="hljs-number">1</span>; <span class="hljs-comment">// 数组下标为i的元素值等于e,返回其位序i+1 </span><br><span class="hljs-keyword">return</span> <span class="hljs-number">0</span>; <span class="hljs-comment">// 没有查找到 </span><br>}<br></code></pre></td></tr></table></figure><blockquote><p>在《数据结构》考研初试中,手写代码可以直接用“==”,无论 ElemType 是基本数据类型还是结构类型</p></blockquote><p>时间复杂度:</p><ul><li>最好时间复杂度:O ( 1 )</li><li>最坏时间复杂度:O ( n )</li><li>平均时间复杂度:O ( n )</li></ul><h1 id="二,单链表"><a href="#二,单链表" class="headerlink" title="二,单链表"></a>二,单链表</h1><h2 id="2-1-单链表的实现"><a href="#2-1-单链表的实现" class="headerlink" title="2.1 单链表的实现"></a>2.1 单链表的实现</h2><h3 id="不带头结点的单链表:"><a href="#不带头结点的单链表:" class="headerlink" title="不带头结点的单链表:"></a><strong>不带头结点的单链表:</strong></h3><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-keyword">typedef</span> <span class="hljs-keyword">struct</span> <span class="hljs-title class_">LNode</span>{<br> ElemType data;<br> <span class="hljs-keyword">struct</span> <span class="hljs-title class_">LNode</span> *next;<br>}LNode, *LinkList;<br><br><span class="hljs-comment">//初始化一个空的单链表</span><br><span class="hljs-function"><span class="hljs-type">bool</span> <span class="hljs-title">InitList</span><span class="hljs-params">(LinkList &L)</span></span>{<br> L = <span class="hljs-literal">NULL</span>;<span class="hljs-comment">//空表,暂时还没有任何结点</span><br> <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;<br>}<br><br><span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">test</span><span class="hljs-params">()</span></span>{<br> LinkList L;<span class="hljs-comment">//声明一个指向单链表的头指针</span><br> <span class="hljs-comment">//初始化一个空表</span><br> <span class="hljs-built_in">InitList</span>(L);<br> ...<br>}<br><br><span class="hljs-comment">//判断单链表是否为空</span><br><span class="hljs-function"><span class="hljs-type">bool</span> <span class="hljs-title">Empty</span><span class="hljs-params">(LinkList L)</span></span>{<br> <span class="hljs-keyword">return</span> (L==<span class="hljs-literal">NULL</span>)<br>}<br></code></pre></td></tr></table></figure><h3 id="带头结点的单链表:"><a href="#带头结点的单链表:" class="headerlink" title="带头结点的单链表:"></a><strong>带头结点的单链表:</strong></h3><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-keyword">typedef</span> <span class="hljs-keyword">struct</span> <span class="hljs-title class_">LNode</span>{<br> ElemType data;<br> <span class="hljs-keyword">struct</span> <span class="hljs-title class_">LNode</span> *next;<br>}LNode, *LinkList;<br><br><span class="hljs-comment">// 初始化一个单链表(带头结点)</span><br><span class="hljs-function"><span class="hljs-type">bool</span> <span class="hljs-title">InitList</span><span class="hljs-params">(LinkList &L)</span></span>{<br> L = (LNode *)<span class="hljs-built_in">malloc</span>(<span class="hljs-built_in">sizeof</span>(LNode));<span class="hljs-comment">//分配一个头结点</span><br> <span class="hljs-keyword">if</span> (L == <span class="hljs-literal">NULL</span>)<span class="hljs-comment">//内存不足,分配失败</span><br> <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;<br> L->next = <span class="hljs-literal">NULL</span>;<span class="hljs-comment">//头结点之后暂时还没有结点</span><br> <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;<br>}<br><br><span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">test</span><span class="hljs-params">()</span></span>{<br> LinkList L;<span class="hljs-comment">//声明一个指向单链表的头指针</span><br> <span class="hljs-comment">//初始化一个空表</span><br> <span class="hljs-built_in">InitList</span>(L);<br> ...<br>}<br><br><span class="hljs-comment">//判断单链表是否为空</span><br><span class="hljs-function"><span class="hljs-type">bool</span> <span class="hljs-title">Empty</span><span class="hljs-params">(LinkList L)</span></span>{<br> <span class="hljs-keyword">if</span> (L->next == <span class="hljs-literal">NULL</span>)<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;<br> <span class="hljs-keyword">else</span><br> <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;<br>}<br></code></pre></td></tr></table></figure><h2 id="2-2-单链表的建立"><a href="#2-2-单链表的建立" class="headerlink" title="2.2 单链表的建立"></a>2.2 单链表的建立</h2><h3 id="尾插法建立单链表:"><a href="#尾插法建立单链表:" class="headerlink" title="尾插法建立单链表:"></a><strong>尾插法建立单链表:</strong></h3><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-comment">// 使用尾插法建立单链表L</span><br><span class="hljs-function">LinkList <span class="hljs-title">List_TailInsert</span><span class="hljs-params">(LinkList &L)</span></span>{<br> <span class="hljs-type">int</span> x;<span class="hljs-comment">//设ElemType为整型int</span><br> L = (LinkList)<span class="hljs-built_in">malloc</span>(<span class="hljs-built_in">sizeof</span>(LNode));<span class="hljs-comment">//建立头结点(初始化空表)</span><br> LNode *s, *r = L;<span class="hljs-comment">//r为表尾指针</span><br> <span class="hljs-built_in">scanf</span>(<span class="hljs-string">"%d"</span>, &x);<span class="hljs-comment">//输入要插入的结点的值</span><br> <span class="hljs-keyword">while</span>(x!=<span class="hljs-number">9999</span>){<span class="hljs-comment">//输入9999表示结束</span><br> s = (LNode *)<span class="hljs-built_in">malloc</span>(<span class="hljs-built_in">sizeof</span>(LNode));<br> s->data = x;<br> r->next = s;<br> r = s;<span class="hljs-comment">//r指针指向新的表尾结点</span><br> <span class="hljs-built_in">scanf</span>(<span class="hljs-string">"%d"</span>, &x);<br> }<br> r->next = <span class="hljs-literal">NULL</span>;<span class="hljs-comment">//尾结点指针置空</span><br> <span class="hljs-keyword">return</span> L;<br>}<br></code></pre></td></tr></table></figure><p>时间复杂度:O ( n )</p><h3 id="头插法建立单链表:"><a href="#头插法建立单链表:" class="headerlink" title="头插法建立单链表:"></a><strong>头插法建立单链表:</strong></h3><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-function">LinkList <span class="hljs-title">List_HeadInsert</span><span class="hljs-params">(LinkList &L)</span></span>{<span class="hljs-comment">//逆向建立单链表</span><br> LNode *s;<br> <span class="hljs-type">int</span> x;<br> L = (LinkList)<span class="hljs-built_in">malloc</span>(<span class="hljs-built_in">sizeof</span>(LNode));<span class="hljs-comment">//建立头结点</span><br> L->next = <span class="hljs-literal">NULL</span>;<span class="hljs-comment">//初始为空链表,这步很关键</span><br> <span class="hljs-built_in">scanf</span>(<span class="hljs-string">"%d"</span>, &x);<span class="hljs-comment">//输入要插入的结点的值</span><br> <span class="hljs-keyword">while</span>(x!=<span class="hljs-number">9999</span>){<span class="hljs-comment">//输入9999表结束</span><br> s = (LNode *)<span class="hljs-built_in">malloc</span>(<span class="hljs-built_in">sizeof</span>(LNode));<br> s->data = x;<br> s->next = L->next;<br> L->next = s;<br><span class="hljs-comment">//将新结点插入表中,L为头指针</span><br><span class="hljs-built_in">scanf</span>(<span class="hljs-string">"%d"</span>, &x);<br> }<br> <span class="hljs-keyword">return</span> L;<br>}<br></code></pre></td></tr></table></figure><h3 id="头插法实现链表的逆置:"><a href="#头插法实现链表的逆置:" class="headerlink" title="头插法实现链表的逆置:"></a><strong>头插法实现链表的逆置:</strong></h3><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-comment">// 将链表L中的数据逆置并返回</span><br><span class="hljs-function">LNode *<span class="hljs-title">Inverse</span><span class="hljs-params">(LNode *L)</span></span>{<br> LNode *p, *q;<br> p = L->next;<span class="hljs-comment">//p指针指向第一个结点</span><br> L->next = <span class="hljs-literal">NULL</span>;<span class="hljs-comment">//头结点置空</span><br> <span class="hljs-comment">// 依次判断p结点中的数据并采用头插法插到L链表中</span><br> <span class="hljs-keyword">while</span> (p != <span class="hljs-literal">NULL</span>){<br> q = p;<br> p = p->next;<br> q->next = L->next;<br> L->next = q;<br> }<br> <span class="hljs-keyword">return</span> L;<br>}<br></code></pre></td></tr></table></figure><h2 id="2-3-单链表的基本操作"><a href="#2-3-单链表的基本操作" class="headerlink" title="2.3 单链表的基本操作"></a>2.3 单链表的基本操作</h2><h3 id="按位序插入(带头结点):"><a href="#按位序插入(带头结点):" class="headerlink" title="按位序插入(带头结点):"></a><strong>按位序插入(带头结点):</strong></h3><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-keyword">typedef</span> <span class="hljs-keyword">struct</span> <span class="hljs-title class_">LNode</span>{<br> ElemType data;<br> <span class="hljs-keyword">struct</span> <span class="hljs-title class_">LNode</span> *next;<br>}LNode, *LinkList;<br><br><span class="hljs-comment">//在第i个位置插入元素e</span><br><span class="hljs-function"><span class="hljs-type">bool</span> <span class="hljs-title">ListInsert</span><span class="hljs-params">(LinkList &L, <span class="hljs-type">int</span> i, ElemType e)</span></span>{<br> <span class="hljs-keyword">if</span>(i<<span class="hljs-number">1</span>)<br> <span class="hljs-keyword">return</span> False;<br> LNode *p; <span class="hljs-comment">//指针p指向当前扫描到的结点</span><br> <span class="hljs-type">int</span> j=<span class="hljs-number">0</span>; <span class="hljs-comment">//当前p指向的是第几个结点</span><br> p = L; <span class="hljs-comment">//循环找到第i-1个结点</span><br> <span class="hljs-keyword">while</span>(p!=<span class="hljs-literal">NULL</span> && j<i<span class="hljs-number">-1</span>){ <span class="hljs-comment">//如果i>lengh,p最后会等于NULL</span><br> p = p->next;<br> j++;<br> }<br><span class="hljs-comment">//p值为NULL说明i值不合法</span><br> <span class="hljs-keyword">if</span> (p==<span class="hljs-literal">NULL</span>)<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;<br><span class="hljs-comment">//在第i-1个结点后插入新结点</span><br> LNode *s = (LNode *)<span class="hljs-built_in">malloc</span>(<span class="hljs-built_in">sizeof</span>(LNode));<br> s->data = e;<br> s->next = p->next;<br> p->next = s;<br><span class="hljs-comment">//将结点s连到p后</span><br> <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;<br>}<br></code></pre></td></tr></table></figure><p>时间复杂度:</p><ul><li>最好时间复杂度:O ( 1 )</li><li>最坏时间复杂度:O ( n )</li><li>平均时间复杂度:O ( n )</li></ul><h3 id="按位序插入(不带头结点):"><a href="#按位序插入(不带头结点):" class="headerlink" title="按位序插入(不带头结点):"></a><strong>按位序插入(不带头结点):</strong></h3><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-keyword">typedef</span> <span class="hljs-keyword">struct</span> <span class="hljs-title class_">LNode</span>{<br> ElemType data;<br> <span class="hljs-keyword">struct</span> <span class="hljs-title class_">LNode</span> *next;<br>}LNode, *LinkList;<br><br><span class="hljs-comment">//在第i个位置插入元素e</span><br><span class="hljs-function"><span class="hljs-type">bool</span> <span class="hljs-title">ListInsert</span><span class="hljs-params">(LinkList &L, <span class="hljs-type">int</span> i, ElemType e)</span></span>{<br><span class="hljs-comment">//判断i的合法性</span><br> <span class="hljs-keyword">if</span>(i<<span class="hljs-number">1</span>)<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;<br><span class="hljs-comment">//需要判断插入的位置是否是第1个</span><br> <span class="hljs-keyword">if</span>(i==<span class="hljs-number">1</span>){<br> LNode *s = (LNode *)<span class="hljs-built_in">malloc</span>(size <span class="hljs-built_in">of</span>(LNode));<br> s->data =e;<br> s->next =L;<br> L=s;<span class="hljs-comment">//头指针指向新结点</span><br> <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;<br> }<br><span class="hljs-comment">//i>1的情况与带头结点一样,唯一区别是j的初始值为1</span><br> LNode *p;<span class="hljs-comment">//指针p指向当前扫描到的结点</span><br> <span class="hljs-type">int</span> j=<span class="hljs-number">1</span>;<span class="hljs-comment">//当前p指向的是第几个结点</span><br> p = L;<br><span class="hljs-comment">//循环找到第i-1个结点</span><br> <span class="hljs-keyword">while</span>(p!=<span class="hljs-literal">NULL</span> && j<i<span class="hljs-number">-1</span>){<span class="hljs-comment">//如果i>lengh,p最后会等于NULL</span><br> p = p->next;<br> j++;<br> }<br><span class="hljs-comment">//p值为NULL说明i值不合法</span><br> <span class="hljs-keyword">if</span> (p==<span class="hljs-literal">NULL</span>)<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;<br><span class="hljs-comment">//在第i-1个结点后插入新结点</span><br> LNode *s = (LNode *)<span class="hljs-built_in">malloc</span>(<span class="hljs-built_in">sizeof</span>(LNode));<br> s->data = e;<br> s->next = p->next;<br> p->next = s;<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;<br>}<br></code></pre></td></tr></table></figure><p>时间复杂度:</p><ul><li>最好时间复杂度:O ( 1 )</li><li>最坏时间复杂度:O ( n )</li><li>平均时间复杂度:O ( n )</li></ul><blockquote><p>除非特别声明,否则之后的代码都默认为带头结点</p></blockquote><h3 id="指定结点的后插操作:"><a href="#指定结点的后插操作:" class="headerlink" title="指定结点的后插操作:"></a><strong>指定结点的后插操作:</strong></h3><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-keyword">typedef</span> <span class="hljs-keyword">struct</span> <span class="hljs-title class_">LNode</span>{<br> ElemType data;<br> <span class="hljs-keyword">struct</span> <span class="hljs-title class_">LNode</span> *next;<br>}LNode, *LinkList;<br><br><span class="hljs-comment">// 在结点p后插入元素e</span><br><span class="hljs-function"><span class="hljs-type">bool</span> <span class="hljs-title">InsertNextNode</span><span class="hljs-params">(LNode *p, ElemType e)</span></span>{<br> <span class="hljs-keyword">if</span>(p==<span class="hljs-literal">NULL</span>){<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;<br> }<br> LNode *s = (LNode *)<span class="hljs-built_in">malloc</span>(<span class="hljs-built_in">sizeof</span>(LNode));<br> <span class="hljs-keyword">if</span>(s==<span class="hljs-literal">NULL</span>)<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;<br> s->data = e;<br> s->next = p->next;<br> p->next = s;<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;<br>}<br><br><span class="hljs-comment">// 按位序插入的函数中可以直接调用后插操作</span><br><span class="hljs-function"><span class="hljs-type">bool</span> <span class="hljs-title">ListInsert</span><span class="hljs-params">(LinkList &L, <span class="hljs-type">int</span> i, ElemType e)</span></span>{<br> <span class="hljs-keyword">if</span>(i<<span class="hljs-number">1</span>)<br> <span class="hljs-keyword">return</span> False;<br> LNode *p;<br><span class="hljs-comment">//指针p指向当前扫描到的结点</span><br><span class="hljs-type">int</span> j=<span class="hljs-number">0</span>;<br><span class="hljs-comment">//当前p指向的是第几个结点</span><br> p = L;<br><span class="hljs-comment">//循环找到第i-1个结点</span><br> <span class="hljs-keyword">while</span>(p!=<span class="hljs-literal">NULL</span> && j<i<span class="hljs-number">-1</span>){<br><span class="hljs-comment">//如果i>lengh, p最后会等于NULL</span><br> p = p->next;<br> j++;<br> }<br> <span class="hljs-keyword">return</span> <span class="hljs-built_in">InsertNextNode</span>(p, e)<br>}<br></code></pre></td></tr></table></figure><p>时间复杂度:O ( 1 )</p><h3 id="指定结点的前插操作:"><a href="#指定结点的前插操作:" class="headerlink" title="指定结点的前插操作:"></a><strong>指定结点的前插操作:</strong></h3><blockquote><p>如果传入头指针,就可以循环整个链表找到指定结点p的前驱结点q,再对q进行后插操作;<br>如果不传入头指针,可以在指定结点p后插入一个结点s,并交换两个结点所保存的数据,从而变相实现指定结点的前插操作。</p></blockquote><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-keyword">typedef</span> <span class="hljs-keyword">struct</span> <span class="hljs-title class_">LNode</span>{<br> ElemType data;<br> <span class="hljs-keyword">struct</span> <span class="hljs-title class_">LNode</span> *next;<br>}LNode, *LinkList;<br><br><span class="hljs-comment">// 在结点p前插入元素e</span><br><span class="hljs-function"><span class="hljs-type">bool</span> <span class="hljs-title">InsertPriorNode</span><span class="hljs-params">(LNode *p, ElemType e)</span></span>{<br> <span class="hljs-keyword">if</span>(p==<span class="hljs-literal">NULL</span>)<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;<br> LNode *s = (LNode *)<span class="hljs-built_in">malloc</span>(<span class="hljs-built_in">sizeof</span>(LNode));<br><span class="hljs-comment">// 内存不足分配失败</span><br><span class="hljs-keyword">if</span>(s==<span class="hljs-literal">NULL</span>)<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;<br><span class="hljs-comment">// 将s插入结点p之后</span><br> s->next = p->next;<br> p->next = s;<br><span class="hljs-comment">// 交换两个结点中的数据</span><br> s->data = p->data;<br> p->data = e;<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;<br>}<br></code></pre></td></tr></table></figure><p>时间复杂度:O ( 1 )</p><h3 id="按位序删除:"><a href="#按位序删除:" class="headerlink" title="按位序删除:"></a><strong>按位序删除:</strong></h3><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-keyword">typedef</span> <span class="hljs-keyword">struct</span> <span class="hljs-title class_">LNode</span>{<br> ElemType data;<br> <span class="hljs-keyword">struct</span> <span class="hljs-title class_">LNode</span> *next;}LNode, *LinkList;<br><br><span class="hljs-comment">// 删除第i个结点并将其所保存的数据存入e</span><br><span class="hljs-function"><span class="hljs-type">bool</span> <span class="hljs-title">ListDelete</span><span class="hljs-params">(LinkList &L, <span class="hljs-type">int</span> i, ElemType &e)</span></span>{<br> <span class="hljs-keyword">if</span>(i<<span class="hljs-number">1</span>)<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;<br> LNode *p;<span class="hljs-comment">//指针p指向当前扫描到的结点</span><br> <span class="hljs-type">int</span> j=<span class="hljs-number">0</span>;<span class="hljs-comment">//当前p指向的是第几个结点</span><br> p = L;<br><span class="hljs-comment">//循环找到第i-1个结点</span><br> <span class="hljs-keyword">while</span>(p!=<span class="hljs-literal">NULL</span> && j<i<span class="hljs-number">-1</span>){<br><span class="hljs-comment">//如果i>lengh,p和p的后继结点会等于NULL</span><br> p = p->next;<br> j++;<br> }<br> <span class="hljs-keyword">if</span>(p==<span class="hljs-literal">NULL</span>)<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;<br> <span class="hljs-keyword">if</span>(p->next == <span class="hljs-literal">NULL</span>)<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;<br><span class="hljs-comment">//令q暂时保存被删除的结点</span><br> LNode *q = p->next;<br> e = q->data;<br> p->next = q->next;<br> <span class="hljs-built_in">free</span>(q)<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;<br>}<br></code></pre></td></tr></table></figure><p>时间复杂度:</p><ul><li>最好时间复杂度:O ( 1 )</li><li>最坏时间复杂度:O ( n )</li><li>平均时间复杂度:O ( n )</li></ul><h3 id="删除指定结点:"><a href="#删除指定结点:" class="headerlink" title="删除指定结点:"></a><strong>删除指定结点:</strong></h3><blockquote><p>如果传入头指针,就可以循环整个链表找到指定结点p的前驱结点q,再对p进行删除操作;<br>如果不传入头指针,可以把指定结点p的后继结点q删除,并使结点p保存结点q存储的数据,从而变相实现删除指定结点的操作。但是<strong>如果指定结点p没有后继结点,这么做会报错</strong>。</p></blockquote><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-comment">// 删除指定结点p</span><br><span class="hljs-function"><span class="hljs-type">bool</span> <span class="hljs-title">DeleteNode</span><span class="hljs-params">(LNode *p)</span></span>{<br> <span class="hljs-keyword">if</span>(p==<span class="hljs-literal">NULL</span>)<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;<br> LNode *q = p->next;<span class="hljs-comment">// 令q指向p的后继结点// 如果p是最后一个结点,则q指向NULL,继续执行就会报错</span><br> p->data = q->data;<br> p->next = q->next;<br> <span class="hljs-built_in">free</span>(q);<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;<br>}<br></code></pre></td></tr></table></figure><p>时间复杂度:O ( 1 )</p><h3 id="按位查找:-1"><a href="#按位查找:-1" class="headerlink" title="按位查找:"></a><strong>按位查找:</strong></h3><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-keyword">typedef</span> <span class="hljs-keyword">struct</span> <span class="hljs-title class_">LNode</span>{<br> ElemType data;<br> <span class="hljs-keyword">struct</span> <span class="hljs-title class_">LNode</span> *next;<br>}LNode, *LinkList;<br><br><span class="hljs-comment">// 查找指定位序i的结点并返回</span><br><span class="hljs-function">LNode * <span class="hljs-title">GetElem</span><span class="hljs-params">(LinkList L, <span class="hljs-type">int</span> i)</span></span>{<br> <span class="hljs-keyword">if</span>(i<<span class="hljs-number">0</span>)<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">NULL</span>;<br> LNode *p;<br> <span class="hljs-type">int</span> j=<span class="hljs-number">0</span>;<br> p = L;<br> <span class="hljs-keyword">while</span>(p!=<span class="hljs-literal">NULL</span> && j<i){<br> p = p->next;<br> j++;<br> }<br> <span class="hljs-keyword">return</span> p;<br>}<br><br><span class="hljs-comment">// 封装后的插入操作,在第i个位置插入元素e,可以调用查询操作和后插操作</span><br><span class="hljs-function"><span class="hljs-type">bool</span> <span class="hljs-title">ListInsert</span><span class="hljs-params">(LinkList &L, <span class="hljs-type">int</span> i, ElemType e)</span></span>{<br> <span class="hljs-keyword">if</span>(i<<span class="hljs-number">1</span>)<br> <span class="hljs-keyword">return</span> False;<br><span class="hljs-comment">// 找到第i-1个元素</span><br> LNode *p = <span class="hljs-built_in">GetElem</span>(L, i<span class="hljs-number">-1</span>);<br><span class="hljs-comment">// 在p结点后插入元素e</span><br><span class="hljs-keyword">return</span> <span class="hljs-built_in">InsertNextNode</span>(p, e)<br>}<br></code></pre></td></tr></table></figure><p>时间复杂度:</p><ul><li>最好时间复杂度:O ( 1 )</li><li>最坏时间复杂度:O ( n )</li><li>平均时间复杂度:O ( n )</li></ul><h3 id="按值查找:-1"><a href="#按值查找:-1" class="headerlink" title="按值查找:"></a><strong>按值查找:</strong></h3><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-comment">// 查找数据域为e的结点指针,否则返回NULL</span><br><span class="hljs-function">LNode * <span class="hljs-title">LocateElem</span><span class="hljs-params">(LinkList L, ElemType e)</span></span>{<br> LNode *P = L->next;<br> <span class="hljs-comment">// 从第一个结点开始查找数据域为e的结点</span><br> <span class="hljs-keyword">while</span>(p!=<span class="hljs-literal">NULL</span> && p->data != e){<br> p = p->next;<br> }<br> <span class="hljs-keyword">return</span> p;<br>}<br></code></pre></td></tr></table></figure><p>时间复杂度:</p><ul><li>最好时间复杂度:O ( 1 )</li><li>最坏时间复杂度:O ( n )</li><li>平均时间复杂度:O ( n )</li></ul><h3 id="计算单链表长度:"><a href="#计算单链表长度:" class="headerlink" title="计算单链表长度:"></a><strong>计算单链表长度:</strong></h3><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-comment">// 计算单链表的长度</span><br><span class="hljs-function"><span class="hljs-type">int</span> <span class="hljs-title">Length</span><span class="hljs-params">(LinkList L)</span></span>{<br> <span class="hljs-type">int</span> len=<span class="hljs-number">0</span>;<span class="hljs-comment">//统计表长</span><br> LNode *p = L;<br> <span class="hljs-keyword">while</span>(p->next != <span class="hljs-literal">NULL</span>){<br> p = p->next;<br> len++;<br> }<br> <span class="hljs-keyword">return</span> len;<br>}<br></code></pre></td></tr></table></figure><p>时间复杂度:O ( n )</p><h1 id="三,双链表"><a href="#三,双链表" class="headerlink" title="三,双链表"></a>三,双链表</h1><p><img src="/2024/02/02/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E4%B9%8B%E7%BA%BF%E6%80%A7%E8%A1%A8%E4%BB%A3%E7%A0%81/0.png"></p><h2 id="双链表的初始化-带头结点"><a href="#双链表的初始化-带头结点" class="headerlink" title="双链表的初始化 (带头结点)"></a><strong>双链表的初始化 (带头结点)</strong></h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-keyword">typedef</span> <span class="hljs-keyword">struct</span> <span class="hljs-title class_">DNode</span>{ <span class="hljs-comment">//定义双链表结点类型</span><br> ElemType data; <span class="hljs-comment">//数据域</span><br> <span class="hljs-keyword">struct</span> <span class="hljs-title class_">DNode</span> *prior, *next; <span class="hljs-comment">//前驱和后继指针</span><br>}DNode, *DLinklist;<br><br><span class="hljs-comment">// 初始化双链表</span><br><span class="hljs-function"><span class="hljs-type">bool</span> <span class="hljs-title">InitDLinkList</span><span class="hljs-params">(Dlinklist &L)</span></span>{<br> L = (DNode *)<span class="hljs-built_in">malloc</span>(<span class="hljs-built_in">sizeof</span>(DNode));<br> <span class="hljs-keyword">if</span>(L==<span class="hljs-literal">NULL</span>)<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;<br> L->prior = <span class="hljs-literal">NULL</span>;<span class="hljs-comment">//头结点的prior指针永远指向NULL</span><br> L->next = <span class="hljs-literal">NULL</span>;<span class="hljs-comment">//头结点之后暂时还没有结点,置空</span><br> <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;<br>}<br><br><span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">testDLinkList</span><span class="hljs-params">()</span></span>{<br> DLinklist L;<br> <span class="hljs-built_in">InitDLinkList</span>(L);<br> ...<br>}<br><br><span class="hljs-comment">// 判断双链表是否为空</span><br><span class="hljs-function"><span class="hljs-type">bool</span> <span class="hljs-title">Empty</span><span class="hljs-params">(DLinklist L)</span></span>{<br> <span class="hljs-keyword">if</span>(L->next == <span class="hljs-literal">NULL</span>)<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;<br> <span class="hljs-keyword">else</span><br> <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;<br>}<br></code></pre></td></tr></table></figure><h2 id="双链表的后插操作"><a href="#双链表的后插操作" class="headerlink" title="双链表的后插操作"></a><strong>双链表的后插操作</strong></h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-keyword">typedef</span> <span class="hljs-keyword">struct</span> <span class="hljs-title class_">DNode</span>{<br> ElemType data;<br> <span class="hljs-keyword">struct</span> <span class="hljs-title class_">DNode</span> *prior, *next;<br>}DNode, *DLinklist;<br><br><span class="hljs-comment">// 将结点s插入到结点p之后</span><br><span class="hljs-function"><span class="hljs-type">bool</span> <span class="hljs-title">InsertNextDNode</span><span class="hljs-params">(DNode *p, DNode *s)</span></span>{ <br> <span class="hljs-keyword">if</span>(p==<span class="hljs-literal">NULL</span> || s==<span class="hljs-literal">NULL</span>) <br> <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>; <br> s->next = p->next; <br> <span class="hljs-comment">// 判断结点p之后是否有后继结点 </span><br> <span class="hljs-keyword">if</span> (p->next != <span class="hljs-literal">NULL</span>) <br> p->next->prior = s; <br> s->prior = p; <br> p->next = s; <br> <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;<br>}<br></code></pre></td></tr></table></figure><blockquote><p>双链表的前插操作、按位序插入操作都可以转换成后插操作</p></blockquote><h2 id="双链表的删除操作"><a href="#双链表的删除操作" class="headerlink" title="双链表的删除操作"></a><strong>双链表的删除操作</strong></h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-comment">// 删除p结点的后继结点</span><br><span class="hljs-function"><span class="hljs-type">bool</span> <span class="hljs-title">DeletNextDNode</span><span class="hljs-params">(DNode *p)</span></span>{ <br> <span class="hljs-keyword">if</span>(p==<span class="hljs-literal">NULL</span>) <br> <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>; <br> <span class="hljs-comment">// 找到p的后继结点q </span><br> DNode *q =p->next; <br> <span class="hljs-keyword">if</span>(q==<span class="hljs-literal">NULL</span>) <br> <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>; <br> p->next = q->next; <br> <span class="hljs-keyword">if</span>(q->next != <span class="hljs-literal">NULL</span>) <br> q->next->prior=p; <br> <span class="hljs-built_in">free</span>(q); <br> <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;<br>}<br><br><span class="hljs-comment">// 销毁一个双链表</span><br><span class="hljs-function"><span class="hljs-type">bool</span> <span class="hljs-title">DestoryList</span><span class="hljs-params">(DLinklist &L)</span></span>{ <br> <span class="hljs-comment">// 循环释放各个数据结点 </span><br> <span class="hljs-keyword">while</span>(L->next != <span class="hljs-literal">NULL</span>){ <br> <span class="hljs-built_in">DeletNextDNode</span>(L); <br> <span class="hljs-built_in">free</span>(L); <br> <span class="hljs-comment">// 头指针置空 </span><br> L=<span class="hljs-literal">NULL</span>; <br> }<br>}<br></code></pre></td></tr></table></figure><h2 id="双链表的遍历"><a href="#双链表的遍历" class="headerlink" title="双链表的遍历"></a><strong>双链表的遍历</strong></h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-comment">// 向后遍历</span><br><span class="hljs-keyword">while</span>(p!=<span class="hljs-literal">NULL</span>){ <br> <span class="hljs-comment">// 对结点p做相应处理 </span><br> p = p->next;<br>}<br><br><span class="hljs-comment">// 向前遍历</span><br><span class="hljs-keyword">while</span>(p!=<span class="hljs-literal">NULL</span>){ <br> <span class="hljs-comment">// 对结点p做相应处理 </span><br> p = p->prior;<br>}<br><br><span class="hljs-comment">// 跳过头结点的遍历</span><br><span class="hljs-keyword">while</span>(p->prior!=<span class="hljs-literal">NULL</span>){ <br> <span class="hljs-comment">//对结点p做相应处理 </span><br> p = p->prior;<br>}<br></code></pre></td></tr></table></figure><blockquote><p>双链表不可随机存取,按位查找、按值查找操作都只能用遍历的方式实现。</p></blockquote><h1 id="四,循环链表"><a href="#四,循环链表" class="headerlink" title="四,循环链表"></a>四,循环链表</h1><p><img src="/2024/02/02/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E4%B9%8B%E7%BA%BF%E6%80%A7%E8%A1%A8%E4%BB%A3%E7%A0%81/1.png"></p><p><img src="/2024/02/02/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E4%B9%8B%E7%BA%BF%E6%80%A7%E8%A1%A8%E4%BB%A3%E7%A0%81/2.png"></p><h2 id="循环单链表的实现"><a href="#循环单链表的实现" class="headerlink" title="循环单链表的实现"></a><strong>循环单链表的实现</strong></h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-keyword">typedef</span> <span class="hljs-keyword">struct</span> <span class="hljs-title class_">LNode</span>{ <br> ElemType data; <br> <span class="hljs-keyword">struct</span> <span class="hljs-title class_">LNode</span> *next; <br>}DNode, *Linklist;<br><br><span class="hljs-comment">// 初始化循环单链表</span><br><span class="hljs-function"><span class="hljs-type">bool</span> <span class="hljs-title">InitList</span><span class="hljs-params">(LinkList &L)</span></span>{ <br> L = (LNode *)<span class="hljs-built_in">malloc</span>(<span class="hljs-built_in">sizeof</span>(LNode)); <br> <span class="hljs-keyword">if</span>(L==<span class="hljs-literal">NULL</span>) <br> <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>; <br> <span class="hljs-comment">// 最后一个结点的next指针指向头结点 </span><br> L->next = L; <br> <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;<br>}<br><br><span class="hljs-comment">// 判断循环单链表是否为空</span><br><span class="hljs-function"><span class="hljs-type">bool</span> <span class="hljs-title">Empty</span><span class="hljs-params">(LinkList L)</span></span>{ <br> <span class="hljs-keyword">if</span>(L->next == L) <br> <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>; <br> <span class="hljs-keyword">else</span> <br> <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;<br>}<br><br><span class="hljs-comment">// 判断结点p是否为循环单链表的表尾结点</span><br><span class="hljs-function"><span class="hljs-type">bool</span> <span class="hljs-title">isTail</span><span class="hljs-params">(LinkList L, LNode *p)</span></span>{ <br> <span class="hljs-keyword">if</span>(p->next == L) <br> <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>; <br> <span class="hljs-keyword">else</span> <br> <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;<br>}<br></code></pre></td></tr></table></figure><h2 id="循环双链表的实现"><a href="#循环双链表的实现" class="headerlink" title="循环双链表的实现"></a><strong>循环双链表的实现</strong></h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-keyword">typedef</span> <span class="hljs-keyword">struct</span> <span class="hljs-title class_">DNode</span>{ <br> ElemType data; <br> <span class="hljs-keyword">struct</span> <span class="hljs-title class_">DNode</span> *prior, *next; <br>}DNode, *DLinklist;<br><br><span class="hljs-comment">// 初始循环双链表</span><br><span class="hljs-function"><span class="hljs-type">bool</span> <span class="hljs-title">InitDLinkList</span><span class="hljs-params">(DLinklist &L)</span></span>{ <br> L = (DNode *) <span class="hljs-built_in">malloc</span>(<span class="hljs-built_in">sizeof</span>(DNode)); <br> <span class="hljs-keyword">if</span>(L==<span class="hljs-literal">NULL</span>) <br> <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>; <br> <span class="hljs-comment">// 头结点的prior指针指向最后一个结点,最后一个结点的next指针指向头结点 </span><br> L->prior = L; <br> L->next = L;<br>}<br><br><span class="hljs-comment">// 判断循环双链表是否为空</span><br><span class="hljs-function"><span class="hljs-type">bool</span> <span class="hljs-title">Empty</span><span class="hljs-params">(DLinklist L)</span></span>{ <br> <span class="hljs-keyword">if</span>(L->next == L) <br> <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>; <br> <span class="hljs-keyword">else</span> <br> <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;<br>}<br><br><span class="hljs-comment">// 判断结点p是否为循环双链表的表尾结点</span><br><span class="hljs-function"><span class="hljs-type">bool</span> <span class="hljs-title">isTail</span><span class="hljs-params">(DLinklist L, DNode *p)</span></span>{ <br> <span class="hljs-keyword">if</span>(p->next == L) <br> <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>; <br> <span class="hljs-keyword">else</span> <br> <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;<br>}<br></code></pre></td></tr></table></figure><h2 id="循环双链表的插入和删除操作"><a href="#循环双链表的插入和删除操作" class="headerlink" title="循环双链表的插入和删除操作"></a><strong>循环双链表的插入和删除操作</strong></h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-comment">// 将结点s插入到结点p之后</span><br><span class="hljs-function"><span class="hljs-type">bool</span> <span class="hljs-title">InsertNextDNode</span><span class="hljs-params">(DNode *p, DNode *s)</span></span>{ <br> s->next = p->next; <br> <span class="hljs-comment">//循环双链表不用担心p结点的下一个结点为空 </span><br> p->next->prior = s; <br> s->prior = p; <br> p->next = s;<br>}<br><br><span class="hljs-comment">// 删除p结点的后继结点</span><br><span class="hljs-function"><span class="hljs-type">bool</span> <span class="hljs-title">DeletNextDNode</span><span class="hljs-params">(DNode *p)</span></span>{ <br> <span class="hljs-comment">// 找到p的后继结点q </span><br> DNode *q =p->next; <br> <span class="hljs-comment">//循环双链表不用担心q结点的下一个结点为空 </span><br> p->next = q->next; <br> q->next->prior=p; <br> <span class="hljs-built_in">free</span>(q); <br> <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;<br>}<br></code></pre></td></tr></table></figure><p>参考自:<a href="https://blog.csdn.net/qq_55593227/article/details/123598044">https://blog.csdn.net/qq_55593227/article/details/123598044</a></p>]]></content>
<categories>
<category>考研408</category>
</categories>
</entry>
<entry>
<title>python程序带图片等资源打包</title>
<link href="/2024/01/12/python%E7%A8%8B%E5%BA%8F%E5%B8%A6%E5%9B%BE%E7%89%87%E7%AD%89%E8%B5%84%E6%BA%90%E6%89%93%E5%8C%85/"/>
<url>/2024/01/12/python%E7%A8%8B%E5%BA%8F%E5%B8%A6%E5%9B%BE%E7%89%87%E7%AD%89%E8%B5%84%E6%BA%90%E6%89%93%E5%8C%85/</url>
<content type="html"><![CDATA[<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-comment">#在打包时,都需要将终端运行地址切换到要打包文件的父目录下</span><br><span class="hljs-comment">#在终端中运行以下代码</span><br>cd 父目录地址<br></code></pre></td></tr></table></figure><h1 id="1,常规打包"><a href="#1,常规打包" class="headerlink" title="1,常规打包"></a>1,常规打包</h1><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs python">Pyinstaller -F py_word.py <span class="hljs-comment">#打包成单独exe,在文件夹dist中的单独文件</span><br><br>Pyinstaller -F -w py_word.py <span class="hljs-comment">#不带控制台的打包,不建议,会导致静默运行,只能从运行管理器中找到并停止</span><br><br>Pyinstaller -F -w -i chengzi.ico py_word.py <span class="hljs-comment">#打包指定exe图标打包</span><br><br>pyinstaller -F --uac-admin word.py <span class="hljs-comment">#打包的程序以管理员身份运行</span><br></code></pre></td></tr></table></figure><p>如果打包过大,可以使用anaconda创建虚拟环境只下载需要的第三方库。</p><h1 id="2,带资源打包"><a href="#2,带资源打包" class="headerlink" title="2,带资源打包"></a>2,带资源打包</h1><h2 id="2-1-首先解决的问题:打包后代码里资源的地址会因在不同环境下运行而不同。"><a href="#2-1-首先解决的问题:打包后代码里资源的地址会因在不同环境下运行而不同。" class="headerlink" title="2.1 首先解决的问题:打包后代码里资源的地址会因在不同环境下运行而不同。"></a>2.1 首先解决的问题:打包后代码里资源的地址会因在不同环境下运行而不同。</h2><p>首先需要将图片放到代码同级文件夹内,同时更新代码内的图片地址,这样做是为了后期能够批量打包图片等资源。</p><p>这里通过文件运行的绝对路径结合图片的相对路径来生成图片的绝对路径。将以下函数代码复制到打包代码中:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">def</span> <span class="hljs-title function_">get_resource_path</span>(<span class="hljs-params">relative_path</span>):<br> <span class="hljs-keyword">if</span> <span class="hljs-built_in">hasattr</span>(sys, <span class="hljs-string">'_MEIPASS'</span>):<br> <span class="hljs-keyword">return</span> os.path.join(sys._MEIPASS, relative_path)<br> <span class="hljs-keyword">return</span> os.path.join(os.path.abspath(<span class="hljs-string">"."</span>), relative_path)<br></code></pre></td></tr></table></figure><p>定义了函数后,将代码里的图片地址统一换为:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs python">get_resource_path(<span class="hljs-string">'原代码里的图片地址'</span>)<br></code></pre></td></tr></table></figure><h2 id="2-2-开始进行打包"><a href="#2-2-开始进行打包" class="headerlink" title="2.2 开始进行打包"></a>2.2 开始进行打包</h2><ol><li><code>-add-data</code>后面可以加=,也可以直接空格,效果一样。</li><li><code>-add-data</code>后面的参数值里,有两部分,用 <code>:</code> 或者 <code>;</code>隔开,前面是指打包前文件所在的位置,后面是指打包后你希望文件所在的位置。比如样例里的:<code>-add-data="image1.png:img"</code> 的意思是把当前目录里一个叫 “image1.png” 的文件打包进去,但是放在打包后的 “img” 目录下,也就是变成 img/image1.png,文件名不变。</li><li><code>-add-data</code>可以用好多次,也就是可以一个文件一个文件地加。</li><li>整个文件夹一起加:<code>-add-data 'images:images'</code> 也就是把当前目录下 images 文件夹里的文件都打包进去,打包后的目录也是 images 一样的文件夹下。</li></ol><p>最终在终端运行的代码:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs python">pyinstaller --add-data <span class="hljs-string">'images:images'</span> -F --uac-admin py_name.py<br></code></pre></td></tr></table></figure>]]></content>
<categories>
<category>基础工具</category>
</categories>
</entry>
<entry>
<title>人工智能学习导航</title>
<link href="/2024/01/10/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD%E5%AD%A6%E4%B9%A0%E5%AF%BC%E8%88%AA/"/>
<url>/2024/01/10/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD%E5%AD%A6%E4%B9%A0%E5%AF%BC%E8%88%AA/</url>
<content type="html"><![CDATA[<h1 id="1,机器学习算法python实现"><a href="#1,机器学习算法python实现" class="headerlink" title="1,机器学习算法python实现"></a>1,<a href="https://github.com/lawlite19/MachineLearning_Python?tab=readme-ov-file">机器学习算法python实现</a></h1><p>GitHub项目,讲解了机器学习算法的数学原理与python实现,做笔记必备。</p><h1 id="2,Hello算法"><a href="#2,Hello算法" class="headerlink" title="2,Hello算法"></a>2,<a href="https://www.hello-algo.com/">Hello算法</a></h1><p>数据结构类的算法的多方式实现,有c,python,c++等等,同时配备了可视化界面,形象讲解算法的原理与区别。</p><h1 id="3,可视化数据结构与算法"><a href="#3,可视化数据结构与算法" class="headerlink" title="3,可视化数据结构与算法"></a>3,<a href="https://visualgo.net/zh">可视化数据结构与算法</a></h1><p>一个单纯模拟数据结构算法的网站。</p><h1 id="4,菜鸟教程"><a href="#4,菜鸟教程" class="headerlink" title="4,菜鸟教程"></a>4,<a href="https://www.runoob.com/">菜鸟教程</a></h1><p>学计算机必备,各种语言与第三方库的讲解以及框架,数不胜数!</p><h1 id="5,神经网络与深度学习"><a href="#5,神经网络与深度学习" class="headerlink" title="5,神经网络与深度学习"></a>5,<a href="https://nndl.github.io/nndl-book.pdf">神经网络与深度学习</a></h1><p><strong>邱锡鹏</strong>教授出版,详细功能见网址上级GitHub仓库,具有以下特点:</p><p><strong>系统性</strong>:系统地整理了神经网络和深度学习的知识体系。鉴于深度学习涉及的知识点较多,本书从机器学习的基本概念、神经网络模型以及概率图模型三个层面来串联深度学习所涉及的知识点,使读者对深度学习技术的理解更具系统性、条理性和全面性。<br><strong>可读性</strong>:本书在编排上由浅入深,在语言表达上力求通俗易懂,并通过增加图例、示例以及必要的数学推导来理解抽象的概念。同时,附录简要介绍了本书所涉及的必要数学知识,便于读者查用。<br><strong>实践性</strong>:本书在网站上配套了针对每章知识点的编程练习,使得读者在学习过程中可以将理论和实践密切结合,加深对知识点的理解,并具备分析问题和解决问题的能力。</p><h1 id="6,小林coding"><a href="#6,小林coding" class="headerlink" title="6,小林coding"></a>6,<a href="https://xiaolincoding.com/">小林coding</a></h1><p>图解计算机网络、操作系统、计算机组成、数据库,让天下没有难懂的八股文!</p>]]></content>
<categories>
<category>人工智能</category>
</categories>
</entry>
<entry>
<title>GitHub desktop 基本用法</title>
<link href="/2024/01/09/GitHub%20desktop%E5%9F%BA%E6%9C%AC%E7%94%A8%E6%B3%95/"/>
<url>/2024/01/09/GitHub%20desktop%E5%9F%BA%E6%9C%AC%E7%94%A8%E6%B3%95/</url>
<content type="html"><![CDATA[<h1 id="一,仓库"><a href="#一,仓库" class="headerlink" title="一,仓库"></a>一,仓库</h1><h2 id="1-1新建仓库"><a href="#1-1新建仓库" class="headerlink" title="1.1新建仓库"></a>1.1新建仓库</h2><p> <strong>1</strong>,点击File,再点击new repository。</p><p><img src="/2024/01/09/GitHub%20desktop%E5%9F%BA%E6%9C%AC%E7%94%A8%E6%B3%95/Untitled.png"></p><p> <strong>2</strong>,通过新建仓库可以实时的在GitHub和GitHub desktop中创建一个空的仓库,你可以对新建的仓库进行各项设置。</p><p>包括仓库名字,仓库描述,仓库本地位置,自动创建readme文件,忽略文件的选择,以及开源许可证的选择。这里介绍后两个的详细内容:</p><p><img src="/2024/01/09/GitHub%20desktop%E5%9F%BA%E6%9C%AC%E7%94%A8%E6%B3%95/Untitled%201.png"></p><p> git ignore可以选择忽略文件,如果你有些文件并不想上传,那你就可以将其设置。</p><p> 以下是一个示例 .gitignore 文件:</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs markdown"><br><span class="hljs-section"># Ignore node<span class="hljs-emphasis">_modules folder 忽略文件夹</span></span><br><span class="hljs-emphasis"><span class="hljs-section">node_</span>modules/</span><br><br><span class="hljs-section"># Ignore build artifacts 忽略目录</span><br>build/<br>dist/<br><span class="hljs-emphasis">*.log</span><br><span class="hljs-emphasis"></span><br><span class="hljs-emphasis"># Ignore configuration files 忽略文件</span><br><span class="hljs-emphasis">.env</span><br><span class="hljs-emphasis">config.js</span><br><span class="hljs-emphasis"></span><br></code></pre></td></tr></table></figure><p>这将忽略 node_modules 文件夹、build 和 dist 目录、所有以 .log 结尾的文件以及 .env 和 config.js 文件。</p><p>license为许可证设置,设置许可证的目的是为了让别人可以合理合法地使用与修改我们的代码,有多种许可证可以选择,它们具有不同的权限设置。</p><p><img src="/2024/01/09/GitHub%20desktop%E5%9F%BA%E6%9C%AC%E7%94%A8%E6%B3%95/Untitled%202.png"></p><p>总结一下,MIT 最自由,简直就是没有任何限制,任何人都可以售卖我的软件,甚至可以用我的名字促销。BSD 和 Apache 协议也很自由,跟 MIT 的区别分别是不允许用作者本人名义促销和保护作者版权。GPL 可以说最霸道,对代码的修改部分也必须是 GPL 的,同时基于 GPL 代码而开发的代码也必须按照 GPL 发布,而 MPL ,也就是 Mozilla Public License 就温和一些,如果后续开发的代码中添加了新文件,同时新文件中也没有用到原来的代码,那么新文件可以不必继续沿用 MPL 。【<a href="https://zhuanlan.zhihu.com/p/51331026">如何为自己的 Github 项目选择开源许可证? - 知乎 (zhihu.com)</a>】</p><p> <strong>3</strong>,当你完成了前两步,你还需要点击Publish repository来上传仓库,并设置仓库<strong>是否公开</strong>(这很重要!)</p><p><img src="/2024/01/09/GitHub%20desktop%E5%9F%BA%E6%9C%AC%E7%94%A8%E6%B3%95/Untitled%203.png"></p><h2 id="1-2添加本地仓库"><a href="#1-2添加本地仓库" class="headerlink" title="1.2添加本地仓库"></a>1.2添加本地仓库</h2><p> 1,点击File,再点击Ddd local repository。</p><p><img src="/2024/01/09/GitHub%20desktop%E5%9F%BA%E6%9C%AC%E7%94%A8%E6%B3%95/Untitled%204.png"></p><p> 2,输入本地文件地址,但如果你的文件未初始化为git仓库,则需要点击create a repository来新建一个仓库(作用是将选定的文件初始化为git仓库)</p><p><img src="/2024/01/09/GitHub%20desktop%E5%9F%BA%E6%9C%AC%E7%94%A8%E6%B3%95/Untitled%205.png"></p><p> 3,点击后则与上面一样,进行各种参数填充。</p><p><img src="/2024/01/09/GitHub%20desktop%E5%9F%BA%E6%9C%AC%E7%94%A8%E6%B3%95/Untitled%206.png"></p><h2 id="1-3克隆仓库"><a href="#1-3克隆仓库" class="headerlink" title="1.3克隆仓库"></a>1.3克隆仓库</h2><p>1,点击File,再点击Clone repository。</p><p><img src="/2024/01/09/GitHub%20desktop%E5%9F%BA%E6%9C%AC%E7%94%A8%E6%B3%95/Untitled%207.png"></p><p> 2,选择需要克隆的仓库,如果你是要克隆别人的仓库,可以选择URL</p><p><img src="/2024/01/09/GitHub%20desktop%E5%9F%BA%E6%9C%AC%E7%94%A8%E6%B3%95/Untitled%208.png"></p><p><img src="/2024/01/09/GitHub%20desktop%E5%9F%BA%E6%9C%AC%E7%94%A8%E6%B3%95/Untitled%209.png"></p><h2 id="1-4编辑仓库"><a href="#1-4编辑仓库" class="headerlink" title="1.4编辑仓库"></a>1.4编辑仓库</h2><ul><li>点击open in ········,如果这个编辑器不是你喜欢的,你可以点击绿色的Options进行编辑器的选择。</li></ul><p><img src="/2024/01/09/GitHub%20desktop%E5%9F%BA%E6%9C%AC%E7%94%A8%E6%B3%95/Untitled%2010.png"></p><h2 id="1-5删除仓库"><a href="#1-5删除仓库" class="headerlink" title="1.5删除仓库"></a>1.5删除仓库</h2><ul><li>删除仓库<strong>并不会删除GitHub上的仓库</strong>,更多的作用是删除本地与GitHub的连接!</li></ul><p>如果你想切断GitHub与本地库的连接,你可以执行以下操作:</p><ol><li><p>删除本地库中的.git文件夹(这是一个隐藏文件夹,你需要启用显示隐藏文件夹选项)</p></li><li><p>如果你想从GitHub上删除该库,你可以在GitHub上进入该库,点击“Settings”,然后在“Danger Zone”中点击“Delete this repository”。</p></li></ol><p>这里推荐使用GitHub desktop进行删除操作:</p><p><img src="/2024/01/09/GitHub%20desktop%E5%9F%BA%E6%9C%AC%E7%94%A8%E6%B3%95/2023-05-07_232823.png"></p><p>右击需要删除的仓库</p><p><img src="/2024/01/09/GitHub%20desktop%E5%9F%BA%E6%9C%AC%E7%94%A8%E6%B3%95/Untitled%2011.png"></p><p>在被删除仓库页面,点击Repository,再点击Remove</p><p>你会看到如下页面,勾选下方选项框的话,会将你的仓库从计算机硬盘中移除;如果不勾选,只会在GitHub desktop(GitHub)上移除。</p><p><img src="/2024/01/09/GitHub%20desktop%E5%9F%BA%E6%9C%AC%E7%94%A8%E6%B3%95/Untitled%2012.png"></p><h1 id="二,版本控制"><a href="#二,版本控制" class="headerlink" title="二,版本控制"></a>二,版本控制</h1><h2 id="2-1更新版本"><a href="#2-1更新版本" class="headerlink" title="2.1更新版本"></a>2.1更新版本</h2><p> <strong>1</strong>,GitHub desktop会自动识别仓库里代码的变动,并且你可选择应用哪些改变。如果你改变了仓库链接的本地仓库文件,你可以在GitHub desktop的主页面上看到如下场景:</p><p><img src="/2024/01/09/GitHub%20desktop%E5%9F%BA%E6%9C%AC%E7%94%A8%E6%B3%95/Untitled%2013.png"></p><p>我在仓库中新建了‘版本更新.py’文件,并在其中写入了print(’dddd’)代码</p><p> <strong>2</strong>,可以看到左侧栏中出现了changes,你需要在左下角的summary中填入摘记(必填),还可以填入相关描述,填入后,你还需要点击Push origin上传:</p><p><img src="/2024/01/09/GitHub%20desktop%E5%9F%BA%E6%9C%AC%E7%94%A8%E6%B3%95/Untitled%2014.png"></p><p> <strong>3</strong>,这时你就可以在GitHub上看到你的仓库发生了变化:</p><p><img src="/2024/01/09/GitHub%20desktop%E5%9F%BA%E6%9C%AC%E7%94%A8%E6%B3%95/Untitled%2015.png"></p><h2 id="2-2项目回滚"><a href="#2-2项目回滚" class="headerlink" title="2.2项目回滚"></a>2.2项目回滚</h2><p><strong>1</strong>,你可以在History里看到每一次的版本变化:</p><p><img src="/2024/01/09/GitHub%20desktop%E5%9F%BA%E6%9C%AC%E7%94%A8%E6%B3%95/Untitled%2016.png"></p><p><strong>2</strong>,具体操作:</p><ul><li>点击History</li><li>选择要回滚的版本</li><li>右键选择Revert Changes in Commit</li><li>确认回滚信息并提交</li></ul><p><img src="/2024/01/09/GitHub%20desktop%E5%9F%BA%E6%9C%AC%E7%94%A8%E6%B3%95/Untitled%2017.png"></p><p>可以看到版本回到了最开始的样子。</p><h1 id="三,分支管理"><a href="#三,分支管理" class="headerlink" title="三,分支管理"></a>三,分支管理</h1><h2 id="3-1新建分支"><a href="#3-1新建分支" class="headerlink" title="3.1新建分支"></a>3.1新建分支</h2><ul><li>点击Current brance</li><li>点击New brance</li><li>然后为你的分支命名即可</li><li>在GitHub中查看分支</li></ul><p><img src="/2024/01/09/GitHub%20desktop%E5%9F%BA%E6%9C%AC%E7%94%A8%E6%B3%95/Untitled%2018.png"></p><p>创建分支</p><h2 id="3-2切换分支"><a href="#3-2切换分支" class="headerlink" title="3.2切换分支"></a>3.2切换分支</h2><p>点击即可</p><p><img src="/2024/01/09/GitHub%20desktop%E5%9F%BA%E6%9C%AC%E7%94%A8%E6%B3%95/Untitled%2019.png" alt="在GitHub desktop选择分支"></p><p><img src="/2024/01/09/GitHub%20desktop%E5%9F%BA%E6%9C%AC%E7%94%A8%E6%B3%95/Untitled%2020.png" alt="在GitHub查看与选择分支"></p><h2 id="3-3合并分支"><a href="#3-3合并分支" class="headerlink" title="3.3合并分支"></a>3.3合并分支</h2><ol><li><p>首先,在 GitHub Desktop 中打开你要合并的仓库。</p></li><li><p>点击左侧导航栏中的“分支”选项卡,找到你要合并的分支。</p></li><li><p>选择要合并的分支,右键点击该分支并选择“Merge into current branch”(合并到当前分支)选项。</p></li><li><p>确认合并操作,如果有冲突需要手动解决冲突。</p></li><li><p>点击“Commit merge”(提交合并)按钮。</p></li><li><p>最后点击“Push origin”(推送到远程仓库)按钮,将合并后的代码推送到远程仓库。</p></li></ol><p><img src="/2024/01/09/GitHub%20desktop%E5%9F%BA%E6%9C%AC%E7%94%A8%E6%B3%95/Untitled%2021.png"></p><h2 id="3-4删除分支"><a href="#3-4删除分支" class="headerlink" title="3.4删除分支"></a>3.4删除分支</h2><ul><li>右键删除即可</li></ul><p><img src="/2024/01/09/GitHub%20desktop%E5%9F%BA%E6%9C%AC%E7%94%A8%E6%B3%95/Untitled%2022.png"></p><h2 id="3-5比较分支"><a href="#3-5比较分支" class="headerlink" title="3.5比较分支"></a>3.5比较分支</h2><ul><li>在 GitHub Desktop 中打开你要合并的仓库。</li><li>点击Compare to brance</li></ul><p><img src="/2024/01/09/GitHub%20desktop%E5%9F%BA%E6%9C%AC%E7%94%A8%E6%B3%95/Untitled%2023.png"></p><ul><li>在左侧搜索需要对比的即可</li></ul><p><img src="/2024/01/09/GitHub%20desktop%E5%9F%BA%E6%9C%AC%E7%94%A8%E6%B3%95/Untitled%2024.png"></p><h2 id="3-6查看提交历史"><a href="#3-6查看提交历史" class="headerlink" title="3.6查看提交历史"></a>3.6查看提交历史</h2><ul><li>在想要查看的分支下点击Hitory</li></ul><p><img src="/2024/01/09/GitHub%20desktop%E5%9F%BA%E6%9C%AC%E7%94%A8%E6%B3%95/Untitled%2025.png"></p><h1 id="四,多人协作"><a href="#四,多人协作" class="headerlink" title="四,多人协作"></a>四,多人协作</h1><ol><li>创建GitHub仓库:首先,一个人(通常是项目的负责人)在GitHub上创建一个仓库,并将其与本地项目相关联。</li><li>邀请协作者:负责人可以通过在GitHub仓库的设置中添加协作者来邀请其他人加入项目。在协作者的GitHub帐户上,他们将收到邀请加入项目的通知。</li></ol><p><img src="/2024/01/09/GitHub%20desktop%E5%9F%BA%E6%9C%AC%E7%94%A8%E6%B3%95/Untitled%2026.png"></p><p>在仓库设置里,点击Collabarators即可</p><ol><li>克隆仓库:协作者使用GitHub Desktop<strong>克隆项目</strong>的仓库到本地。他们可以选择克隆到自己的计算机上的任意位置。</li><li>进行更改:每个协作者在本地进行代码更改或其他操作。他们可以使用GitHub Desktop的界面进行提交更改。</li><li>提交更改:协作者完成更改后,使用GitHub Desktop提交他们的更改到GitHub仓库。他们可以添加有关更改的说明和描述。</li><li><strong>解决冲突</strong>:如果两个或多个协作者在相同的文件的相同行进行了更改,可能会出现冲突。在这种情况下,GitHub Desktop会提醒协作者,让他们解决冲突。协作者可以使用GitHub Desktop提供的冲突解决工具来处理冲突。</li><li>更新本地仓库:<strong>协作者</strong>可以通过点击GitHub Desktop中的”Pull”按钮来获取最新的更改。这将从GitHub仓库中拉取其他协作者提交的更改并合并到本地仓库。</li></ol><p><img src="/2024/01/09/GitHub%20desktop%E5%9F%BA%E6%9C%AC%E7%94%A8%E6%B3%95/Untitled%2027.png"></p><ol start="6"><li>推送更改:协作者在本地完成更改后,可以使用GitHub Desktop的”Push”按钮将更改推送到GitHub仓库。这将把他们的更改上传到仓库并使其他协作者可见。</li></ol><p>通过这些步骤,多人可以使用GitHub Desktop进行协作开发,并实时共享和同步他们的更改。在整个过程中,GitHub Desktop提供了一个简单直观的界面,帮助协作者进行版本控制和协作。</p>]]></content>
<categories>
<category>基础工具</category>
</categories>
</entry>
</search>