-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathatom.xml
609 lines (340 loc) · 242 KB
/
atom.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
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>linkfqy</title>
<subtitle>A link to the past.</subtitle>
<link href="/atom.xml" rel="self"/>
<link href="http://oi.linkfqy.top/"/>
<updated>2021-08-24T13:10:08.396Z</updated>
<id>http://oi.linkfqy.top/</id>
<author>
<name>linkfqy</name>
</author>
<generator uri="http://hexo.io/">Hexo</generator>
<entry>
<title>数模国赛2020A题</title>
<link href="http://oi.linkfqy.top/posts/%E6%95%B0%E6%A8%A1%E5%9B%BD%E8%B5%9B2020A%E9%A2%98/"/>
<id>http://oi.linkfqy.top/posts/数模国赛2020A题/</id>
<published>2021-08-24T12:32:58.000Z</published>
<updated>2021-08-24T13:10:08.396Z</updated>
<content type="html"><![CDATA[<h1 id="第一问">第一问</h1><p>忽略电路板厚度,假定温区内部恒温</p><p>通过热传导方程得到不同温区之间的空隙中,温度在空间上线性分布</p><p>通过牛顿冷却定律和比热容公式解微分方程可知,物体在恒温环境下温度随时间的函数</p><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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"><span class="keyword">import</span> pylab <span class="keyword">as</span> plt</span><br><span class="line"><span class="keyword">import</span> pandas <span class="keyword">as</span> pd</span><br><span class="line"><span class="keyword">from</span> scipy.optimize <span class="keyword">import</span> curve_fit</span><br><span class="line">exc = pd.read_excel(<span class="string">"input.xlsx"</span>, usecols=range(<span class="number">0</span>, <span class="number">2</span>))</span><br><span class="line">data = exc.values</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">pos = np.array([[<span class="number">0</span>, <span class="number">0</span>], [<span class="number">25</span>, <span class="number">55.5</span>], [<span class="number">60.5</span>, <span class="number">91</span>], [<span class="number">96</span>, <span class="number">126.5</span>], [<span class="number">131.5</span>, <span class="number">162</span>], [<span class="number">167</span>, <span class="number">197.5</span>], [<span class="number">202.5</span>, <span class="number">233</span>], [<span class="number">238</span>, <span class="number">268.5</span>], [<span class="number">273.5</span>, <span class="number">304</span>], [<span class="number">309</span>, <span class="number">339.5</span>], [<span class="number">344.5</span>, <span class="number">375</span>], [<span class="number">380</span>, <span class="number">410.5</span>], [<span class="number">435.5</span>, <span class="number">460.5</span>]]</span><br><span class="line"> )</span><br><span class="line"></span><br><span class="line">ranx = np.array([[<span class="number">0</span>, pos[<span class="number">2</span>][<span class="number">0</span>]], [pos[<span class="number">2</span>][<span class="number">0</span>], pos[<span class="number">5</span>][<span class="number">1</span>]], [pos[<span class="number">5</span>][<span class="number">1</span>], pos[<span class="number">6</span>][<span class="number">0</span>]],</span><br><span class="line"> [pos[<span class="number">6</span>][<span class="number">0</span>], pos[<span class="number">6</span>][<span class="number">1</span>]], [pos[<span class="number">6</span>][<span class="number">1</span>], pos[<span class="number">7</span>][<span class="number">0</span>]], [</span><br><span class="line"> pos[<span class="number">7</span>][<span class="number">0</span>], pos[<span class="number">7</span>][<span class="number">1</span>]],</span><br><span class="line"> [pos[<span class="number">7</span>][<span class="number">1</span>], pos[<span class="number">8</span>][<span class="number">0</span>]], [pos[<span class="number">8</span>][<span class="number">0</span>], pos[<span class="number">9</span>][<span class="number">1</span>]], [</span><br><span class="line"> pos[<span class="number">9</span>][<span class="number">1</span>], pos[<span class="number">10</span>][<span class="number">1</span>]],</span><br><span class="line"> [pos[<span class="number">10</span>][<span class="number">1</span>], pos[<span class="number">12</span>][<span class="number">0</span>]]])</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">getab</span><span class="params">(i, tem)</span>:</span> <span class="comment"># 计算第i个小温区后的温度曲线T=ax+b</span></span><br><span class="line"> x1 = pos[i][<span class="number">1</span>]</span><br><span class="line"> x2 = pos[i+<span class="number">1</span>][<span class="number">0</span>]</span><br><span class="line"> t1 = tem[i]</span><br><span class="line"> t2 = tem[i+<span class="number">1</span>]</span><br><span class="line"> a = (t2-t1)/(x2-x1)</span><br><span class="line"> b = t1-a*x1</span><br><span class="line"> <span class="keyword">return</span> (a, b)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">getfx</span><span class="params">(x, tem)</span>:</span> <span class="comment"># 获取x位置的环境温度曲线f(x)=ax+b</span></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">0</span>, <span class="number">12</span>):</span><br><span class="line"> <span class="keyword">if</span> (pos[i][<span class="number">0</span>] <= x <span class="keyword">and</span> x <= pos[i][<span class="number">1</span>]):</span><br><span class="line"> <span class="keyword">return</span> (<span class="number">0</span>, tem[i])</span><br><span class="line"> <span class="keyword">elif</span> (pos[i][<span class="number">1</span>] <= x <span class="keyword">and</span> x <= pos[i+<span class="number">1</span>][<span class="number">0</span>]):</span><br><span class="line"> <span class="keyword">return</span> getab(i, tem=tem)</span><br><span class="line"> <span class="keyword">return</span> (<span class="number">-1</span>, <span class="number">-1</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">f</span><span class="params">(tt, lmd)</span>:</span> <span class="comment"># 用于拟合的函数</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">gettem</span><span class="params">(t)</span>:</span> <span class="comment"># 获取x时刻的零件温度,已知初值T(t0)=T0</span></span><br><span class="line"> <span class="comment"># a, b = (0, 175)</span></span><br><span class="line"> a, b = getfx(t[<span class="number">0</span>]*v, tem=tem)</span><br><span class="line"> c = (T0-a*v*t0+a*v/lmd-b)*np.exp(lmd*t0)</span><br><span class="line"> <span class="keyword">return</span> a*v*t-a*v/lmd+b+c*np.exp(-lmd*t)</span><br><span class="line"> <span class="keyword">return</span> gettem(tt)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>:</span><br><span class="line"> tem = np.array([<span class="number">25</span>, <span class="number">173</span>, <span class="number">173</span>, <span class="number">173</span>, <span class="number">173</span>, <span class="number">173</span>,</span><br><span class="line"> <span class="number">198</span>, <span class="number">230</span>, <span class="number">257</span>, <span class="number">257</span>, <span class="number">25</span>, <span class="number">25</span>, <span class="number">25</span>])</span><br><span class="line"> v = <span class="number">70</span>/<span class="number">60</span> <span class="comment"># 传送带速度,单位cm/s</span></span><br><span class="line"></span><br><span class="line"> tT = data</span><br><span class="line"> t = tT.T[<span class="number">0</span>]</span><br><span class="line"> T = tT.T[<span class="number">1</span>]</span><br><span class="line"> lmds = []</span><br><span class="line"> TT = []</span><br><span class="line"> x = t*v</span><br><span class="line"> lj, j = <span class="number">0</span>, <span class="number">0</span></span><br><span class="line"> <span class="keyword">for</span> ranxi <span class="keyword">in</span> ranx:</span><br><span class="line"> <span class="keyword">while</span> (j < len(x) <span class="keyword">and</span> x[j] <= ranxi[<span class="number">1</span>]):</span><br><span class="line"> j += <span class="number">1</span></span><br><span class="line"> t0 = t[lj]</span><br><span class="line"> T0 = T[lj]</span><br><span class="line"> popt, pcov = curve_fit(f, t[lj:j], T[lj:j])</span><br><span class="line"> lmds.extend(popt)</span><br><span class="line"> TT.extend(f(t[lj:j], lmd=popt))</span><br><span class="line"> lj = j</span><br><span class="line"> <span class="keyword">if</span> (j >= len(x)):</span><br><span class="line"> <span class="keyword">break</span></span><br><span class="line"></span><br><span class="line"> plt.scatter(t, T, s=<span class="number">1</span>)</span><br><span class="line"> plt.plot(t, TT, color=<span class="string">'r'</span>)</span><br><span class="line"> plt.savefig(<span class="string">'getlmd.png'</span>, dpi=<span class="number">500</span>)</span><br><span class="line"> plt.show()</span><br><span class="line"> print(lmds)</span><br></pre></td></tr></table></figure><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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"><span class="keyword">import</span> pylab <span class="keyword">as</span> plt</span><br><span class="line"><span class="keyword">import</span> pandas <span class="keyword">as</span> pd</span><br><span class="line"><span class="keyword">from</span> getlmd <span class="keyword">import</span> ranx, pos, getfx</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># lmd = 0.01442337549312217</span></span><br><span class="line">lmds = [<span class="number">0.008643609716781697</span>, <span class="number">0.02103327687676206</span>, <span class="number">0.010922351732360641</span>, <span class="number">0.014168584576603811</span>, <span class="number">0.01604373036324419</span>,</span><br><span class="line"> <span class="number">0.0269012209873633</span>, <span class="number">0.023523032208845447</span>, <span class="number">0.0190525180588788</span>, <span class="number">0.00079443137454158</span>, <span class="number">0.009429030064290005</span>]</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">gettem</span><span class="params">(t, t0, T0, lmd, v, tem)</span>:</span> <span class="comment"># 获取t时段的零件温度,已知初值T(t0)=T0</span></span><br><span class="line"> a, b = getfx(t[<span class="number">0</span>]*v, tem=tem)</span><br><span class="line"> c = (T0-a*v*t0+a*v/lmd-b)*np.exp(lmd*t0)</span><br><span class="line"> <span class="keyword">return</span> a*v*t-a*v/lmd+b+c*np.exp(-lmd*t)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">gettT</span><span class="params">(v, tem, dt=<span class="number">0.5</span>, fil=lambda x: x[<span class="number">1</span>] >= <span class="number">30</span>)</span>:</span> <span class="comment"># 计算温度曲线</span></span><br><span class="line"> t = np.arange(dt, pos[<span class="number">-1</span>][<span class="number">0</span>]/v, dt)</span><br><span class="line"> T = []</span><br><span class="line"> x = t*v</span><br><span class="line"> lj, j = <span class="number">0</span>, <span class="number">0</span></span><br><span class="line"> t0, T0 = <span class="number">0</span>, <span class="number">25</span></span><br><span class="line"> <span class="keyword">for</span> (i, ranxi) <span class="keyword">in</span> enumerate(ranx):</span><br><span class="line"> <span class="keyword">while</span> (j < len(x) <span class="keyword">and</span> x[j] <= ranxi[<span class="number">1</span>]):</span><br><span class="line"> j += <span class="number">1</span></span><br><span class="line"> Ti = gettem(t[lj:j], t0, T0, lmds[i], v=v, tem=tem)</span><br><span class="line"> T.extend(Ti)</span><br><span class="line"> lj = j</span><br><span class="line"> t0, T0 = t[j<span class="number">-1</span>], T[j<span class="number">-1</span>]</span><br><span class="line"> <span class="keyword">if</span> (j >= len(x)):</span><br><span class="line"> <span class="keyword">break</span></span><br><span class="line"></span><br><span class="line"> tT = np.array([t, T]).T</span><br><span class="line"> <span class="keyword">if</span> (fil != <span class="keyword">None</span>):</span><br><span class="line"> tT_f = filter(fil, tT)</span><br><span class="line"> tT = np.array(list(tT_f))</span><br><span class="line"> t, T = tT.T</span><br><span class="line"> <span class="keyword">return</span> (t, T, tT)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>:</span><br><span class="line"> tem = np.array([<span class="number">25</span>, <span class="number">173</span>, <span class="number">173</span>, <span class="number">173</span>, <span class="number">173</span>, <span class="number">173</span>,</span><br><span class="line"> <span class="number">198</span>, <span class="number">230</span>, <span class="number">257</span>, <span class="number">257</span>, <span class="number">25</span>, <span class="number">25</span>, <span class="number">25</span>])</span><br><span class="line"> v = <span class="number">78</span>/<span class="number">60</span> <span class="comment"># 传送带速度,单位cm/s</span></span><br><span class="line"></span><br><span class="line"> t, T, tT = gettT(v=v, tem=tem)</span><br><span class="line"> plt.plot(t, T)</span><br><span class="line"> plt.savefig(<span class="string">'sub1.png'</span>, dpi=<span class="number">500</span>)</span><br><span class="line"> plt.show()</span><br><span class="line"> res = pd.DataFrame(tT, columns=[<span class="string">"时间"</span>, <span class="string">"温度"</span>])</span><br><span class="line"> res.to_csv(<span class="string">'result.csv'</span>, index=<span class="keyword">False</span>, header=<span class="keyword">False</span>)</span><br><span class="line"> printtim = [(pos[<span class="number">3</span>][<span class="number">0</span>]+pos[<span class="number">3</span>][<span class="number">1</span>])/<span class="number">2</span>/v, (pos[<span class="number">6</span>][<span class="number">0</span>]+pos[<span class="number">6</span>][<span class="number">1</span>]) /</span><br><span class="line"> <span class="number">2</span>/v, (pos[<span class="number">7</span>][<span class="number">0</span>]+pos[<span class="number">7</span>][<span class="number">1</span>])/<span class="number">2</span>/v, pos[<span class="number">8</span>][<span class="number">1</span>]/v]</span><br><span class="line"> lmdid = [<span class="number">1</span>, <span class="number">3</span>, <span class="number">5</span>, <span class="number">7</span>]</span><br><span class="line"> j = <span class="number">1</span></span><br><span class="line"> <span class="keyword">for</span> (i, timei) <span class="keyword">in</span> enumerate(printtim):</span><br><span class="line"> <span class="keyword">while</span> (j < len(t) <span class="keyword">and</span> t[j] < timei):</span><br><span class="line"> j += <span class="number">1</span></span><br><span class="line"> <span class="keyword">if</span> j >= len(t):</span><br><span class="line"> <span class="keyword">break</span></span><br><span class="line"> print(gettem(np.array([timei]), t[j<span class="number">-1</span>], T[j<span class="number">-1</span>],</span><br><span class="line"> lmd=lmds[lmdid[i]], v=v, tem=tem))</span><br></pre></td></tr></table></figure><p>得到的各点温度:</p><figure class="highlight plain"><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><span class="line">[135.71310782]</span><br><span class="line">[169.75603785]</span><br><span class="line">[191.00134962]</span><br><span class="line">[223.82106867]</span><br></pre></td></tr></table></figure><p>炉温曲线:</p><p><img src="/posts/数模国赛2020A题/sub1.png"></p><h1 id="第二问">第二问</h1><p>大力枚举速度v,先大范围粗糙枚举,再小范围精确枚举</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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"><span class="keyword">import</span> pylab <span class="keyword">as</span> plt</span><br><span class="line"><span class="keyword">from</span> sub1 <span class="keyword">import</span> gettT</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">checkv</span><span class="params">(t, T, tT, dt=<span class="number">0.5</span>)</span>:</span></span><br><span class="line"> maxT = np.max(T)</span><br><span class="line"> <span class="keyword">if</span> <span class="keyword">not</span>(<span class="number">240</span> <= maxT <span class="keyword">and</span> maxT <= <span class="number">250</span>):</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">False</span></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">1</span>, len(T)):</span><br><span class="line"> <span class="keyword">if</span> np.abs((T[i]-T[i<span class="number">-1</span>])/dt) > <span class="number">3</span>:</span><br><span class="line"> print((i, T[i], T[i<span class="number">-1</span>], t[i], t[i<span class="number">-1</span>]))</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">False</span></span><br><span class="line"> <span class="keyword">if</span> (T[i<span class="number">-1</span>] < <span class="number">150</span> <span class="keyword">and</span> T[i] >= <span class="number">150</span>):</span><br><span class="line"> t1 = t[i]</span><br><span class="line"> <span class="keyword">if</span> (T[i<span class="number">-1</span>] < <span class="number">190</span> <span class="keyword">and</span> T[i] >= <span class="number">190</span>):</span><br><span class="line"> t2 = t[i]</span><br><span class="line"> <span class="keyword">if</span> (T[i<span class="number">-1</span>] < <span class="number">217</span> <span class="keyword">and</span> T[i] >= <span class="number">217</span>):</span><br><span class="line"> t3 = t[i]</span><br><span class="line"> <span class="keyword">if</span> (T[i<span class="number">-1</span>] >= <span class="number">217</span> <span class="keyword">and</span> T[i] < <span class="number">217</span>):</span><br><span class="line"> t4 = t[i]</span><br><span class="line"> <span class="keyword">if</span> <span class="keyword">not</span> (<span class="number">60</span> <= t2-t1 <span class="keyword">and</span> t2-t1 <= <span class="number">120</span>):</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">False</span></span><br><span class="line"> <span class="keyword">if</span> <span class="keyword">not</span> (<span class="number">40</span> <= t4-t3 <span class="keyword">and</span> t4-t3 <= <span class="number">90</span>):</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">False</span></span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">True</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">printlim</span><span class="params">(t, T, tT, dt=<span class="number">0.5</span>)</span>:</span> <span class="comment"># 输出各制程的极限值</span></span><br><span class="line"> maxT = np.max(T)</span><br><span class="line"> print(<span class="string">"maxT="</span>, maxT)</span><br><span class="line"> maxk = <span class="number">0</span></span><br><span class="line"> mink = <span class="number">0</span></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">1</span>, len(T)):</span><br><span class="line"> maxk = max((T[i]-T[i<span class="number">-1</span>])/dt, maxk)</span><br><span class="line"> mink = min((T[i]-T[i<span class="number">-1</span>])/dt, mink)</span><br><span class="line"> <span class="keyword">if</span> (T[i<span class="number">-1</span>] < <span class="number">150</span> <span class="keyword">and</span> T[i] >= <span class="number">150</span>):</span><br><span class="line"> t1 = t[i]</span><br><span class="line"> <span class="keyword">if</span> (T[i<span class="number">-1</span>] < <span class="number">190</span> <span class="keyword">and</span> T[i] >= <span class="number">190</span>):</span><br><span class="line"> t2 = t[i]</span><br><span class="line"> <span class="keyword">if</span> (T[i<span class="number">-1</span>] < <span class="number">217</span> <span class="keyword">and</span> T[i] >= <span class="number">217</span>):</span><br><span class="line"> t3 = t[i]</span><br><span class="line"> <span class="keyword">if</span> (T[i<span class="number">-1</span>] >= <span class="number">217</span> <span class="keyword">and</span> T[i] < <span class="number">217</span>):</span><br><span class="line"> t4 = t[i]</span><br><span class="line"> print(<span class="string">"maxk="</span>, maxk)</span><br><span class="line"> print(<span class="string">"mink="</span>, mink)</span><br><span class="line"> print(<span class="string">"t2-t1="</span>, t2-t1)</span><br><span class="line"> print(<span class="string">"t4-t3="</span>, t4-t3)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>:</span><br><span class="line"> tem = np.array([<span class="number">25</span>, <span class="number">182</span>, <span class="number">182</span>, <span class="number">182</span>, <span class="number">182</span>, <span class="number">182</span>,</span><br><span class="line"> <span class="number">203</span>, <span class="number">237</span>, <span class="number">254</span>, <span class="number">254</span>, <span class="number">25</span>, <span class="number">25</span>, <span class="number">25</span>])</span><br><span class="line"> maxv = <span class="number">0</span></span><br><span class="line"> dt = <span class="number">0.1</span></span><br><span class="line"> <span class="keyword">for</span> v <span class="keyword">in</span> np.linspace(<span class="number">65</span>/<span class="number">60</span>, <span class="number">100</span>/<span class="number">60</span>, num=<span class="number">35</span>*<span class="number">2</span>+<span class="number">1</span>): <span class="comment"># 间隔0.5</span></span><br><span class="line"> t, T, tT = gettT(v=v, dt=dt, tem=tem)</span><br><span class="line"> <span class="comment"># print("v={}".format(v))</span></span><br><span class="line"> <span class="keyword">if</span> (checkv(t, T, tT, dt)):</span><br><span class="line"> maxv = v</span><br><span class="line"> print(maxv*<span class="number">60</span>)</span><br><span class="line"> <span class="keyword">for</span> v <span class="keyword">in</span> np.linspace(<span class="number">70</span>/<span class="number">60</span>, <span class="number">75</span>/<span class="number">60</span>, num=<span class="number">5</span>*<span class="number">100</span>+<span class="number">1</span>): <span class="comment"># 间隔0.01</span></span><br><span class="line"> t, T, tT = gettT(v=v, dt=dt, tem=tem)</span><br><span class="line"> <span class="comment"># print("v={}".format(v))</span></span><br><span class="line"> <span class="keyword">if</span> (checkv(t, T, tT, dt)):</span><br><span class="line"> maxv = v</span><br><span class="line"> print(maxv*<span class="number">60</span>)</span><br><span class="line"> t, T, tT = gettT(v=maxv, dt=dt, tem=tem)</span><br><span class="line"> printlim(t, T, tT, dt=dt)</span><br><span class="line"> plt.plot(t, T)</span><br><span class="line"> plt.savefig(<span class="string">'sub2.png'</span>, dpi=<span class="number">500</span>)</span><br><span class="line"> plt.show()</span><br></pre></td></tr></table></figure><p>得到的各参数:</p><figure class="highlight plain"><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><span class="line">v1=72.0</span><br><span class="line">v2=72.33</span><br><span class="line">maxT= 240.00007138887304</span><br><span class="line">maxk= 2.658684542907963</span><br><span class="line">mink= -1.8523553812633509</span><br><span class="line">t2-t1= 103.69999999999999</span><br><span class="line">t4-t3= 82.90000000000006</span><br></pre></td></tr></table></figure><p>在最大速度下的炉温曲线:</p><p><img src="/posts/数模国赛2020A题/sub2.png"></p><h1 id="第三问">第三问</h1><p>把阴影面积作为估值函数,做模拟退火</p><p>调了<code>scikit-opt</code>的库</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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> sko.SA <span class="keyword">import</span> SA, SABoltzmann, SAFast</span><br><span class="line"><span class="keyword">from</span> sub1 <span class="keyword">import</span> gettT</span><br><span class="line"><span class="keyword">from</span> sub2 <span class="keyword">import</span> checkv</span><br><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"><span class="keyword">import</span> pandas <span class="keyword">as</span> pd</span><br><span class="line"><span class="keyword">import</span> pylab <span class="keyword">as</span> plt</span><br><span class="line">exc = pd.read_excel(<span class="string">"input.xlsx"</span>, usecols=range(<span class="number">0</span>, <span class="number">2</span>))</span><br><span class="line">data = exc.values</span><br><span class="line">data = data.T</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">getarea</span><span class="params">(dt, T)</span>:</span></span><br><span class="line"> res = <span class="number">0</span></span><br><span class="line"> maxT = max(T)</span><br><span class="line"> id = T.tolist().index(maxT)</span><br><span class="line"> <span class="keyword">for</span> (i, Ti) <span class="keyword">in</span> enumerate(T):</span><br><span class="line"> <span class="keyword">if</span> (Ti >= <span class="number">217</span> <span class="keyword">and</span> i <= id):</span><br><span class="line"> res += dt*(Ti<span class="number">-217</span>)</span><br><span class="line"> <span class="keyword">return</span> res</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">X2v</span><span class="params">(X)</span>:</span></span><br><span class="line"> <span class="keyword">return</span> (X[<span class="number">0</span>]*<span class="number">35</span>/<span class="number">20</span>+<span class="number">65</span>)/<span class="number">60</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">X2tem</span><span class="params">(X)</span>:</span></span><br><span class="line"> <span class="keyword">return</span> [<span class="number">25</span>]+[<span class="number">175</span>+X[<span class="number">1</span>]<span class="number">-10</span>]*<span class="number">5</span>+[<span class="number">195</span>+X[<span class="number">2</span>]<span class="number">-10</span>] + \</span><br><span class="line"> [<span class="number">235</span>+X[<span class="number">3</span>]<span class="number">-10</span>]+[<span class="number">255</span>+X[<span class="number">4</span>]<span class="number">-10</span>]*<span class="number">2</span>+[<span class="number">25</span>]*<span class="number">3</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">cost</span><span class="params">(X)</span>:</span> <span class="comment"># 计算模拟退火的代价函数即阴影面积</span></span><br><span class="line"> <span class="keyword">if</span> (X.min() < <span class="number">0</span> <span class="keyword">or</span> X.max() > <span class="number">20</span>): <span class="comment"># 判断输入向量是否合法</span></span><br><span class="line"> <span class="keyword">return</span> <span class="number">1e10</span>+np.abs(X.min()<span class="number">-0</span>)+np.abs(X.max()<span class="number">-20</span>)</span><br><span class="line"> v = X2v(X)</span><br><span class="line"> tem = X2tem(X)</span><br><span class="line"> t, T, tT = gettT(v=v, tem=tem, dt=<span class="number">0.1</span>)</span><br><span class="line"> <span class="keyword">if</span> (<span class="keyword">not</span> checkv(t, T, tT, dt=<span class="number">0.1</span>)): <span class="comment"># 判断是否满足制程界限</span></span><br><span class="line"> <span class="keyword">return</span> <span class="number">1e5</span></span><br><span class="line"> <span class="keyword">return</span> getarea(dt=<span class="number">0.1</span>, T=T)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>:</span><br><span class="line"> sa = SA(func=cost, x0=[<span class="number">0</span>]*<span class="number">5</span>, lb=<span class="number">0</span>, ub=<span class="number">20</span>, max_stay_counter=<span class="number">5000</span>, L=<span class="number">300</span>)</span><br><span class="line"> best_x, best_y = sa.run()</span><br><span class="line"> print(<span class="string">"best_x={}\nminArea={}"</span>.format(best_x, best_y))</span><br><span class="line"> v = X2v(best_x)</span><br><span class="line"> tem = X2tem(best_x)</span><br><span class="line"> print(<span class="string">"v={}\ntem={}\n"</span>.format(v*<span class="number">60</span>, tem))</span><br><span class="line"> t, T, tT = gettT(v=v, tem=tem, dt=<span class="number">0.1</span>)</span><br><span class="line"> plt.plot(t, T)</span><br><span class="line"> plt.show()</span><br><span class="line"> by_f = filter(<span class="keyword">lambda</span> x: x < <span class="number">1e3</span>, sa.best_y_history)</span><br><span class="line"> by = list(by_f)</span><br><span class="line"> plt.plot(pd.DataFrame(by).cummin(axis=<span class="number">0</span>)) <span class="comment"># 画出最小面积随迭代次数变化的曲线</span></span><br><span class="line"> plt.show()</span><br><span class="line"> plt.savefig(<span class="string">'sub3_2.png'</span>, dpi=<span class="number">500</span>)</span><br></pre></td></tr></table></figure><p><img src="/posts/数模国赛2020A题/sub3_2.png"></p><figure class="highlight plain"><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><span class="line">best_x=[1.06929985e+01 1.97873914e+01 5.68152357e+00 8.90629441e-03 1.99983037e+01]</span><br><span class="line">minArea=446.4150721594619</span><br><span class="line">v=83.71274730906958</span><br><span class="line">tem=[25, 184.78739135418277, 184.78739135418277, 184.78739135418277, 184.78739135418277, 184.78739135418277, 190.68152356719315, 225.00890629441466, 264.99830371980664, 264.99830371980664, 25, 25, 25]</span><br></pre></td></tr></table></figure><h1 id="第四问">第四问</h1><p>把炉温曲线中相同温度的点的时间做平均值,与峰值时间的平方和作为对称性的衡量标准</p><p>然后本问是多目标优化,即阴影面积和对称度</p><p>这里采用的是线性组合作为估值函数,经过多次尝试,发现面积变化始终不大,而对称性比较敏感,最终选择了1:10的比例赋权</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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> sko.SA <span class="keyword">import</span> SA</span><br><span class="line"><span class="keyword">from</span> sub1 <span class="keyword">import</span> gettT</span><br><span class="line"><span class="keyword">from</span> sub2 <span class="keyword">import</span> checkv</span><br><span class="line"><span class="keyword">from</span> sub3 <span class="keyword">import</span> getarea, X2tem, X2v</span><br><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"><span class="keyword">import</span> pandas <span class="keyword">as</span> pd</span><br><span class="line"><span class="keyword">import</span> pylab <span class="keyword">as</span> plt</span><br><span class="line"><span class="keyword">from</span> bisect <span class="keyword">import</span> bisect</span><br><span class="line">exc = pd.read_excel(<span class="string">"input.xlsx"</span>, usecols=range(<span class="number">0</span>, <span class="number">2</span>))</span><br><span class="line">data = exc.values</span><br><span class="line">data = data.T</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">getsy</span><span class="params">(tT)</span>:</span> <span class="comment"># 对称度估值</span></span><br><span class="line"> tT_f = filter(<span class="keyword">lambda</span> x: x[<span class="number">1</span>] >= <span class="number">127</span>, tT)</span><br><span class="line"> tT = np.array(list(tT_f))</span><br><span class="line"> t, T = tT.T.tolist()</span><br><span class="line"> maxT = max(T)</span><br><span class="line"> id = T.index(maxT)</span><br><span class="line"> mt = t[id]</span><br><span class="line"> res = <span class="number">0</span></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> range(id+<span class="number">1</span>, len(T)):</span><br><span class="line"> j = bisect(T, T[i], <span class="number">0</span>, id)</span><br><span class="line"> res += ((t[i]+t[j])/<span class="number">2</span>-mt)**<span class="number">2</span></span><br><span class="line"> <span class="keyword">return</span> res</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">cost</span><span class="params">(X)</span>:</span></span><br><span class="line"> <span class="keyword">if</span> (X.min() < <span class="number">0</span> <span class="keyword">or</span> X.max() > <span class="number">20</span>):</span><br><span class="line"> <span class="keyword">return</span> <span class="number">1e100</span>+np.abs(X.min()<span class="number">-0</span>)+np.abs(X.max()<span class="number">-20</span>)</span><br><span class="line"> v = X2v(X)</span><br><span class="line"> tem = X2tem(X)</span><br><span class="line"> t, T, tT = gettT(v=v, tem=tem, dt=dt)</span><br><span class="line"> <span class="keyword">if</span> (<span class="keyword">not</span> checkv(t, T, tT, dt=dt)):</span><br><span class="line"> <span class="keyword">return</span> <span class="number">1e50</span></span><br><span class="line"> <span class="keyword">return</span> getarea(dt=dt, T=T)+getsy(tT)*<span class="number">1e1</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>:</span><br><span class="line"> dt = <span class="number">0.1</span></span><br><span class="line"> sa = SA(func=cost, x0=[<span class="number">0</span>]*<span class="number">5</span>, lb=<span class="number">0</span>, ub=<span class="number">20</span>, max_stay_counter=<span class="number">5000</span>, L=<span class="number">300</span>)</span><br><span class="line"> best_x, best_y = sa.run()</span><br><span class="line"> print(<span class="string">"best_x={}\nbest_y={}"</span>.format(best_x, best_y))</span><br><span class="line"> v = X2v(best_x)</span><br><span class="line"> tem = X2tem(best_x)</span><br><span class="line"> print(<span class="string">"v={}\ntem={}\n"</span>.format(v*<span class="number">60</span>, tem))</span><br><span class="line"> t, T, tT = gettT(v=v, tem=tem, dt=<span class="number">0.1</span>)</span><br><span class="line"> print(<span class="string">"Area="</span>, getarea(dt, T))</span><br><span class="line"> print(<span class="string">"Sy="</span>, getsy(tT))</span><br><span class="line"> plt.plot(t, T)</span><br><span class="line"> plt.plot([<span class="number">0</span>, t.max()], [<span class="number">217</span>, <span class="number">217</span>], <span class="string">'--'</span>)</span><br><span class="line"> plt.savefig(<span class="string">'sub4.png'</span>, dpi=<span class="number">500</span>)</span><br><span class="line"> plt.show()</span><br><span class="line"> by_f = filter(<span class="keyword">lambda</span> x: x < <span class="number">1e30</span>, sa.best_y_history)</span><br><span class="line"> by = list(by_f)</span><br><span class="line"> plt.plot(pd.DataFrame(by).cummin(axis=<span class="number">0</span>)) <span class="comment"># 画出最小面积随迭代次数变化的曲线</span></span><br><span class="line"> plt.show()</span><br><span class="line"> plt.savefig(<span class="string">'sub4_2.png'</span>, dpi=<span class="number">500</span>)</span><br></pre></td></tr></table></figure><p><img src="/posts/数模国赛2020A题/sub4.png"></p><p><img src="/posts/数模国赛2020A题/sub4_2.png"></p><figure class="highlight plain"><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><span class="line">best_x=[12.12066253 2.29087199 0.94809455 19.92827282 19.99803738]</span><br><span class="line">best_y=167663.96859958651</span><br><span class="line">v=86.21115943067932</span><br><span class="line">tem=[25, 167.2908719854776, 167.2908719854776, 167.2908719854776, 167.2908719854776, 167.2908719854776, 185.94809454727962, 244.92827282463267, 264.998037383657, 264.998037383657, 25, 25, 25]</span><br><span class="line">Area= 446.41859958757425</span><br><span class="line">Sy= 16721.754999999896</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<h1 id="第一问">第一问</h1>
<p>忽略电路板厚度,假定温区内部恒温</p>
<p>通过热传导方程得到不同温区之间的空隙中,温度在空间上线性分布</p>
<p>通过牛顿冷却定律和比热容公式解微分方程可知,物体在恒温环境下温度随时间的函数</p>
<p>然后由
</summary>
<category term="题解" scheme="http://oi.linkfqy.top/categories/%E9%A2%98%E8%A7%A3/"/>
<category term="Python" scheme="http://oi.linkfqy.top/tags/Python/"/>
<category term="数模" scheme="http://oi.linkfqy.top/tags/%E6%95%B0%E6%A8%A1/"/>
</entry>
<entry>
<title>SciPy求微分方程数值解</title>
<link href="http://oi.linkfqy.top/posts/SciPy%E6%B1%82%E5%BE%AE%E5%88%86%E6%96%B9%E7%A8%8B%E6%95%B0%E5%80%BC%E8%A7%A3/"/>
<id>http://oi.linkfqy.top/posts/SciPy求微分方程数值解/</id>
<published>2021-08-14T12:01:12.000Z</published>
<updated>2021-08-14T16:02:07.440Z</updated>
<content type="html"><![CDATA[<h1 id="一阶微分方程组">一阶微分方程(组)</h1><p><code>scipy.integrate.odeint()</code>可以数值解一阶微分方程(组)</p><p>不同于微分方程的符号解,可以给出未知函数的表达式,数值解只能求得指定位置的函数值</p><p><code>sol=odeint(func, y0, t)</code></p><ul><li><code>func</code>:表示一个微分方程<span class="math inline">\(\frac{\text dy}{\text dt} = func(y, t)\)</span>,其中的<code>y</code>可以是向量,以表示微分方程组</li><li><code>y0</code>:未知函数的初值条件,表示<span class="math inline">\(y(t[0])=y_0\)</span>,即第一个自变量取值处的函数值,同样可以是向量</li><li><code>t</code>:自变量的取值序列</li></ul><p>返回值<code>sol</code>是一个<code>len(t)*len(y0)</code>的数组,表示每个取值位置的函数值</p><p>示例: <span class="math display">\[\begin{cases}y'=-2y+x^2+2x \\y(1)=2\end{cases}\]</span> 代码在下面一起给出</p><h1 id="高阶微分方程组">高阶微分方程(组)</h1><p>通过换元可以将高阶微分方程转化为一阶微分方程: <span class="math display">\[y_0=y \\y_1=y_0'=y' \\y_2=y_1'=y'' \\\dots \\y_k=y_{k-1}'=y^{(k)} \\\]</span> 这样就同样可以使用<code>odeint()</code>来获得数值解了</p><p>示例: <span class="math display">\[\begin{cases}y''+2y'+2y=0 \\y(0)=0, y'(0)=1\end{cases}\]</span> 先转化成: <span class="math display">\[\begin{cases}y_0'=y_1 \\y_1'=-2y_1-2y_0 \\y_0(0)=0, y_1(0)=1\end{cases}\]</span></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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"><span class="keyword">from</span> scipy.integrate <span class="keyword">import</span> odeint</span><br><span class="line"><span class="keyword">import</span> pylab <span class="keyword">as</span> plt</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">dy</span><span class="params">(y, x)</span>:</span></span><br><span class="line"> <span class="keyword">return</span> <span class="number">-2</span>*y+x**<span class="number">2</span>+<span class="number">2</span>*x</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">x = np.arange(<span class="number">1</span>, <span class="number">10.5</span>, <span class="number">0.5</span>)</span><br><span class="line">sol = odeint(dy, <span class="number">2</span>, x)</span><br><span class="line">print(sol.T)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">dy</span><span class="params">(y, x)</span>:</span></span><br><span class="line"> y0, y1 = y</span><br><span class="line"> <span class="keyword">return</span> [y1, <span class="number">-2</span>*y1 - <span class="number">2</span>*y0]</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">x = np.arange(<span class="number">0</span>, <span class="number">10</span>, <span class="number">0.1</span>)</span><br><span class="line">sol = odeint(dy, [<span class="number">0</span>, <span class="number">1</span>], x)</span><br><span class="line">plt.scatter(x, sol.T[<span class="number">0</span>], marker=<span class="string">'.'</span>) <span class="comment"># 只需要y的0阶导数据</span></span><br><span class="line">plt.savefig(<span class="string">'odeint.png'</span>, dpi=<span class="number">500</span>)</span><br><span class="line">plt.show()</span><br></pre></td></tr></table></figure><p>输出:</p><figure class="highlight plain"><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><span class="line">[[ 2. 2.08484933 2.9191691 4.18723381 5.77289452 7.63342241</span><br><span class="line"> 9.75309843 12.12613985 14.75041934 17.62515427 20.75005673 24.12502089</span><br><span class="line"> 27.7500077 31.62500278 35.75000104 40.1250004 44.75000015 49.62500006</span><br><span class="line"> 54.75000002]]</span><br></pre></td></tr></table></figure><p><img src="/posts/SciPy求微分方程数值解/odeint.png"></p><p>Lorenz模型的混沌效应</p><p>Lorenz方程: <span class="math display">\[\begin{cases}\dot x=\sigma(y-x) \\\dot y=\rho x-y-xz \\\dot z=xy-\beta z\end{cases}\]</span> 模拟<span class="math inline">\(\sigma=10,\rho=28,\beta=\frac 8 3\)</span>时<span class="math inline">\(t\in [0,50]\)</span>的运行轨迹,以及给初值微小扰动后解的偏差演化曲线</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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"><span class="keyword">from</span> scipy.integrate <span class="keyword">import</span> odeint</span><br><span class="line"><span class="keyword">import</span> pylab <span class="keyword">as</span> plt</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">lorenz</span><span class="params">(w, t)</span>:</span></span><br><span class="line"> sigma = <span class="number">10</span></span><br><span class="line"> rho = <span class="number">28</span></span><br><span class="line"> beta = <span class="number">8</span>/<span class="number">3</span></span><br><span class="line"> x, y, z = w</span><br><span class="line"> <span class="keyword">return</span> [sigma*(y-x), rho*x-y-x*z, x*y-beta*z]</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">t = np.arange(<span class="number">0</span>, <span class="number">50</span>, <span class="number">0.01</span>)</span><br><span class="line">sol1 = odeint(lorenz, [<span class="number">0.</span>, <span class="number">1.</span>, <span class="number">0.</span>], t)</span><br><span class="line">sol2 = odeint(lorenz, [<span class="number">0.</span>, <span class="number">1.0001</span>, <span class="number">0.</span>], t)</span><br><span class="line"></span><br><span class="line">ax1 = plt.subplot(<span class="number">121</span>, projection=<span class="string">'3d'</span>)</span><br><span class="line">ax1.plot(sol1[:, <span class="number">0</span>], sol1[:, <span class="number">1</span>], sol1[:, <span class="number">2</span>], linewidth=<span class="number">1</span>)</span><br><span class="line">ax2 = plt.subplot(<span class="number">122</span>, projection=<span class="string">'3d'</span>)</span><br><span class="line">ax2.plot(sol1[:, <span class="number">0</span>]-sol2[:, <span class="number">0</span>], sol1[:, <span class="number">1</span>] -</span><br><span class="line"> sol2[:, <span class="number">1</span>], sol1[:, <span class="number">2</span>]-sol2[:, <span class="number">2</span>], linewidth=<span class="number">1</span>)</span><br><span class="line">plt.savefig(<span class="string">'lorenz.png'</span>, dpi=<span class="number">500</span>)</span><br><span class="line">plt.show()</span><br></pre></td></tr></table></figure><p><img src="/posts/SciPy求微分方程数值解/lorenz.png"></p>]]></content>
<summary type="html">
<h1 id="一阶微分方程组">一阶微分方程(组)</h1>
<p><code>scipy.integrate.odeint()</code>可以数值解一阶微分方程(组)</p>
<p>不同于微分方程的符号解,可以给出未知函数的表达式,数值解只能求得指定位置的函数值</p>
</summary>
<category term="学习笔记" scheme="http://oi.linkfqy.top/categories/%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"/>
<category term="Python" scheme="http://oi.linkfqy.top/tags/Python/"/>
<category term="SciPy" scheme="http://oi.linkfqy.top/tags/SciPy/"/>
</entry>
<entry>
<title>SciPy实现高等数学数值解</title>
<link href="http://oi.linkfqy.top/posts/SciPy%E5%AE%9E%E7%8E%B0%E9%AB%98%E7%AD%89%E6%95%B0%E5%AD%A6%E6%95%B0%E5%80%BC%E8%A7%A3/"/>
<id>http://oi.linkfqy.top/posts/SciPy实现高等数学数值解/</id>
<published>2021-08-13T05:27:40.000Z</published>
<updated>2021-08-13T09:30:38.394Z</updated>
<content type="html"><![CDATA[<h1 id="求导">求导</h1><p><code>scipy.misc.derivative</code>可用于求任意函数的任意阶导数:</p><p><code>def derivative(func, x0, dx=1.0, n=1, order=3)</code></p><ul><li><code>func</code>:自定义的被求导函数<span class="math inline">\(f(x)\)</span></li><li><code>x0</code>:求导的位置,即求<span class="math inline">\(f^{(n)}(x_0)\)</span></li><li><code>dx</code>:用于微分的小量</li><li><code>n</code>:求导的阶数</li><li><code>order</code>:用于求导的采样点个数,必须为>=n+1的奇数</li></ul><p>示例:</p><p>画出<span class="math inline">\(\cos\sqrt{x^2+1}\)</span>及其在<span class="math inline">\(0\)</span>点处的<span class="math inline">\(1,3,5\)</span>阶泰勒展开式 <span class="math display">\[f(x)=f(x_0)+f'(x_0)(x-x_0)+\frac{f''(x_0)}{2!}(x-x_0)^2+\dots+\frac{f^{(i)}(x_0)}{i!}(x-x_0)^i+\dots\]</span></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><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><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"><span class="keyword">from</span> scipy.misc <span class="keyword">import</span> derivative</span><br><span class="line"><span class="keyword">import</span> pylab <span class="keyword">as</span> plt</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">f</span><span class="params">(x)</span>:</span></span><br><span class="line"> <span class="keyword">return</span> np.cos(np.sqrt(x**<span class="number">2</span>+<span class="number">1</span>))</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">fac</span><span class="params">(x)</span>:</span></span><br><span class="line"> <span class="keyword">if</span> (x <= <span class="number">1</span>):</span><br><span class="line"> <span class="keyword">return</span> <span class="number">1</span></span><br><span class="line"> <span class="keyword">return</span> fac(x<span class="number">-1</span>)*x</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">dx = <span class="number">1e-4</span></span><br><span class="line">x = np.linspace(<span class="number">-5</span>, <span class="number">5</span>, <span class="number">100</span>)</span><br><span class="line">y = f(x)</span><br><span class="line">plt.plot(x, y, <span class="string">'r-'</span>, linewidth=<span class="number">2</span>)</span><br><span class="line">now = f(np.zeros(<span class="number">100</span>))</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">1</span>, <span class="number">6</span>):</span><br><span class="line"> now += derivative(f, <span class="number">0</span>, dx, i, order=<span class="number">7</span>)*(x**i)/fac(i)</span><br><span class="line"> <span class="keyword">if</span> (i <span class="keyword">in</span> [<span class="number">1</span>, <span class="number">3</span>, <span class="number">5</span>]):</span><br><span class="line"> plt.plot(x, now, <span class="string">'b--'</span>)</span><br><span class="line">plt.ylim((<span class="number">-2</span>, <span class="number">1</span>))</span><br><span class="line">plt.savefig(<span class="string">"derivative.png"</span>, dpi=<span class="number">500</span>)</span><br><span class="line">plt.show()</span><br></pre></td></tr></table></figure><p><img src="/posts/SciPy实现高等数学数值解/derivative.png"></p><h1 id="定积分">定积分</h1><h2 id="一重积分">一重积分</h2><p><code>scipy.integrate.quad</code>可以求任意函数的一重积分</p><p><code>quad(func, a, b)</code>表示求函数<code>func</code>从<code>a</code>到<code>b</code>的一重积分</p><p>示例:</p><p>求<span class="math inline">\(\int_0^\infty e^{-x}\sin(x^2+2)\)</span></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><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><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"><span class="keyword">from</span> scipy.integrate <span class="keyword">import</span> quad</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">f</span><span class="params">(x)</span>:</span></span><br><span class="line"> <span class="keyword">return</span> np.exp(-x)*np.sin(x**<span class="number">2</span>+<span class="number">2</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">print(quad(f, <span class="number">0</span>, np.inf))</span><br></pre></td></tr></table></figure><p>输出:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">(0.37378979243874044, 1.3876530327162045e-08)</span><br></pre></td></tr></table></figure><p>返回的值分别是积分结果和绝对误差</p><h2 id="多重积分">多重积分</h2><p><code>scipy.integrate.dblquad</code>和<code>scipy.integrate.tplquad</code>分别能够求二重和三重积分</p><p><code>dblquad(func,a,b,gfun,hfun)</code>表示<span class="math inline">\(\int_a^b \text dx \int_{gfun(x)}^{hfun(x)} func(x,y) \text dy\)</span></p><p><code>tplquad(func,a,b,gfun,hfun,qfun,rfun)</code>表示<span class="math inline">\(\int_a^b \text dx \int_{gfun(x)}^{hfun(x)} \text dy \int_{qfun(x,y)}^{rfun(x,y)} func(x,y,z) \text dz\)</span></p><p>返回值和<code>quad</code>一致</p><p>需要注意的是,<code>func</code>定义的参数顺序必须是<code>func(x,y,z)</code></p><h1 id="非线性方程组">非线性方程(组)</h1><p><code>scipy.optimize.fsolve</code>可以解非线性方程(组)</p><p><code>fsolve(func,x0)</code>表示求<span class="math inline">\(func(x)=0\)</span>的根,迭代初值<code>x0</code></p><p>若要解方程组,可将<code>func(x)</code>的<code>x</code>定义为向量</p><p>示例: <span class="math display">\[x^3+1.1x^2+0.9x-1.4=0 \\\begin{cases}5x_2+3=0 \\4x_1^2-2\sin(x_2x_3)=0 \\x_2x_3-1.5=0\end{cases}\]</span></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><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><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"><span class="keyword">from</span> scipy.optimize <span class="keyword">import</span> fsolve</span><br><span class="line"></span><br><span class="line">print(fsolve(<span class="keyword">lambda</span> x: x**<span class="number">3</span>+<span class="number">1.1</span>*x**<span class="number">2</span>+<span class="number">0.9</span>*x<span class="number">-1.4</span>, <span class="number">0</span>))</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">f</span><span class="params">(x)</span>:</span></span><br><span class="line"> x1, x2, x3 = x.tolist()</span><br><span class="line"> <span class="keyword">return</span> [<span class="number">5</span>*x2+<span class="number">3</span>, <span class="number">4</span>*x1**<span class="number">2</span> - <span class="number">2</span>*np.sin(x2*x3), x2*x3 - <span class="number">1.5</span>]</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">print(fsolve(f, [<span class="number">1</span>, <span class="number">1</span>, <span class="number">1</span>]))</span><br></pre></td></tr></table></figure><p>输出:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">[0.67065731]</span><br><span class="line">[-0.70622057 -0.6 -2.5 ]</span><br></pre></td></tr></table></figure><h1 id="求极值点">求极值点</h1><p><code>scipy.optimize.minimize</code>是求非线性规划的函数,若不加约束,即可求任意函数(一元,多元)的极小值点</p><p><code>minimize(func,x0)</code>表示求<span class="math inline">\(func(x)=0\)</span>的最小值,迭代初值<code>x0</code></p><p>返回的是一个<code>result</code>类,可以调用成员以获取相应信息</p><p>示例: <span class="math display">\[f_1(x)=e^x\cos(2x) \\f_2(x_1,x_2)=100(x_2-x_1^2)^2+(1-x_1)^2\]</span></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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"><span class="keyword">from</span> scipy.optimize <span class="keyword">import</span> minimize</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">f1</span><span class="params">(x)</span>:</span></span><br><span class="line"> <span class="keyword">return</span> np.exp(x)*np.cos(<span class="number">2</span>*x)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">f2</span><span class="params">(x)</span>:</span></span><br><span class="line"> x1, x2 = x.tolist()</span><br><span class="line"> <span class="keyword">return</span> <span class="number">100</span>*(x2-x1**<span class="number">2</span>)**<span class="number">2</span>+(<span class="number">1</span>-x1)**<span class="number">2</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">print(minimize(f1, <span class="number">0</span>), <span class="string">'\n'</span>)</span><br><span class="line">print(minimize(f2, [<span class="number">2</span>, <span class="number">2</span>]))</span><br></pre></td></tr></table></figure><p>输出:</p><figure class="highlight plain"><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><span class="line"> fun: -0.2344426467071059</span><br><span class="line">hess_inv: array([[0.85441485]])</span><br><span class="line"> jac: array([-1.86264515e-08])</span><br><span class="line"> message: 'Optimization terminated successfully.'</span><br><span class="line"> nfev: 14</span><br><span class="line"> nit: 5</span><br><span class="line"> njev: 7</span><br><span class="line"> status: 0</span><br><span class="line"> success: True</span><br><span class="line"> x: array([-1.33897255]) </span><br><span class="line"></span><br><span class="line"> fun: 1.8932893809017893e-11</span><br><span class="line">hess_inv: array([[0.51675994, 1.03186494],</span><br><span class="line"> [1.03186494, 2.0655726 ]])</span><br><span class="line"> jac: array([ 5.27380711e-06, -2.50575298e-06])</span><br><span class="line"> message: 'Optimization terminated successfully.'</span><br><span class="line"> nfev: 105</span><br><span class="line"> nit: 30</span><br><span class="line"> njev: 35</span><br><span class="line"> status: 0</span><br><span class="line"> success: True</span><br><span class="line"> x: array([0.99999565, 0.99999129])</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<h1 id="求导">求导</h1>
<p><code>scipy.misc.derivative</code>可用于求任意函数的任意阶导数:</p>
<p><code>def derivative(func, x0, dx=1.0, n=1, order=3)</code
</summary>
<category term="学习笔记" scheme="http://oi.linkfqy.top/categories/%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"/>
<category term="Python" scheme="http://oi.linkfqy.top/tags/Python/"/>
<category term="SciPy" scheme="http://oi.linkfqy.top/tags/SciPy/"/>
</entry>
<entry>
<title>NumPy解线性代数问题</title>
<link href="http://oi.linkfqy.top/posts/NumPy%E8%A7%A3%E7%BA%BF%E6%80%A7%E4%BB%A3%E6%95%B0%E9%97%AE%E9%A2%98/"/>
<id>http://oi.linkfqy.top/posts/NumPy解线性代数问题/</id>
<published>2021-08-11T15:51:32.000Z</published>
<updated>2021-08-12T15:05:31.680Z</updated>
<content type="html"><![CDATA[<h1 id="矩阵运算">矩阵运算</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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy.linalg <span class="keyword">as</span> la</span><br><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line">a = np.array([[<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>]])</span><br><span class="line">b = np.array([[<span class="number">4</span>], [<span class="number">5</span>], [<span class="number">6</span>]])</span><br><span class="line">print(la.norm(a)) <span class="comment"># a的二范数,即模长</span></span><br><span class="line">print(b@a) <span class="comment"># 即a.dot(b),可表示点乘(一维数组)和矩阵乘法(二维数组)</span></span><br><span class="line">a = np.reshape(a, <span class="number">-1</span>)</span><br><span class="line">b = np.reshape(b, <span class="number">-1</span>)</span><br><span class="line">print(np.inner(a, b)) <span class="comment"># a,b的内积,两参数的shape必须为(n,)(1维)</span></span><br><span class="line">print(np.cross(a, b)) <span class="comment"># a,b的叉乘</span></span><br><span class="line"></span><br><span class="line">A = np.arange(<span class="number">1</span>, <span class="number">17</span>).reshape(<span class="number">4</span>, <span class="number">4</span>)</span><br><span class="line">B = np.eye(<span class="number">4</span>) <span class="comment"># 4阶单位矩阵</span></span><br><span class="line">print(la.det(A)) <span class="comment"># 行列式</span></span><br><span class="line">print(la.matrix_rank(A)) <span class="comment"># 秩</span></span><br><span class="line">print(A.T) <span class="comment"># 转置阵</span></span><br><span class="line">print(la.inv(A+<span class="number">10</span>*B)) <span class="comment"># (A+10*B)的逆矩阵</span></span><br><span class="line">print(A@B)</span><br><span class="line">print(np.c_[A, B]) <span class="comment"># 横向分块矩阵</span></span><br><span class="line">print(np.r_[A, B]) <span class="comment"># 纵向分块矩阵</span></span><br><span class="line">print(A[<span class="number">0</span>:<span class="number">2</span>, <span class="number">0</span>:<span class="number">2</span>]) <span class="comment"># 矩阵切片,左上角2*2的子矩阵</span></span><br><span class="line">print(np.delete(A, <span class="number">3</span>, axis=<span class="number">0</span>)) <span class="comment"># 删除某(些)行(0)或列(1)</span></span><br><span class="line">print(np.delete(A, [<span class="number">0</span>, <span class="number">2</span>], axis=<span class="number">1</span>))</span><br><span class="line">print(np.delete(A, [<span class="number">0</span>, <span class="number">2</span>])) <span class="comment"># 默认按一维顺序删除单点</span></span><br></pre></td></tr></table></figure><p>输出:</p><figure class="highlight plain"><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></pre></td><td class="code"><pre><span class="line">3.7416573867739413</span><br><span class="line">[[ 4 8 12]</span><br><span class="line"> [ 5 10 15]</span><br><span class="line"> [ 6 12 18]]</span><br><span class="line">32</span><br><span class="line">[-3 6 -3]</span><br><span class="line">4.7331654313261276e-30</span><br><span class="line">2</span><br><span class="line">[[ 1 5 9 13]</span><br><span class="line"> [ 2 6 10 14]</span><br><span class="line"> [ 3 7 11 15]</span><br><span class="line"> [ 4 8 12 16]]</span><br><span class="line">[[ 0.11277778 0.00333333 -0.00611111 -0.01555556]</span><br><span class="line"> [-0.005 0.09 -0.015 -0.02 ]</span><br><span class="line"> [-0.02277778 -0.02333333 0.07611111 -0.02444444]</span><br><span class="line"> [-0.04055556 -0.03666667 -0.03277778 0.07111111]]</span><br><span class="line">[[ 1. 2. 3. 4.]</span><br><span class="line"> [ 5. 6. 7. 8.]</span><br><span class="line"> [ 9. 10. 11. 12.]</span><br><span class="line"> [13. 14. 15. 16.]]</span><br><span class="line">[[ 1. 2. 3. 4. 1. 0. 0. 0.]</span><br><span class="line"> [ 5. 6. 7. 8. 0. 1. 0. 0.]</span><br><span class="line"> [ 9. 10. 11. 12. 0. 0. 1. 0.]</span><br><span class="line"> [13. 14. 15. 16. 0. 0. 0. 1.]]</span><br><span class="line">[[ 1. 2. 3. 4.]</span><br><span class="line"> [ 5. 6. 7. 8.]</span><br><span class="line"> [ 9. 10. 11. 12.]</span><br><span class="line"> [13. 14. 15. 16.]</span><br><span class="line"> [ 1. 0. 0. 0.]</span><br><span class="line"> [ 0. 1. 0. 0.]</span><br><span class="line"> [ 0. 0. 1. 0.]</span><br><span class="line"> [ 0. 0. 0. 1.]]</span><br><span class="line">[[1 2]</span><br><span class="line"> [5 6]]</span><br><span class="line">[[ 1 2 3 4]</span><br><span class="line"> [ 5 6 7 8]</span><br><span class="line"> [ 9 10 11 12]]</span><br><span class="line">[[ 2 4]</span><br><span class="line"> [ 6 8]</span><br><span class="line"> [10 12]</span><br><span class="line"> [14 16]]</span><br><span class="line">[ 2 4 5 6 7 8 9 10 11 12 13 14 15 16]</span><br></pre></td></tr></table></figure><h1 id="解线性方程组">解线性方程组</h1><h2 id="齐次线性方程组的基础解系">齐次线性方程组的基础解系</h2><p><code>scipy.linalg.null_space()</code>可以获得基础解系 <span class="math display">\[\begin{cases}x_1 -5x_2 +2x_3 -3x_4=0 \\5x_1 +3x_2 +6x_3 -x_4=0 \\2_1 +4x_2 +2x_3 +x_4=0 \\\end{cases}\]</span> 的基础解系:</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><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"><span class="keyword">from</span> scipy.linalg <span class="keyword">import</span> null_space</span><br><span class="line">A = np.array([[<span class="number">1</span>, <span class="number">-5</span>, <span class="number">2</span>, <span class="number">-3</span>], [<span class="number">5</span>, <span class="number">3</span>, <span class="number">6</span>, <span class="number">-1</span>], [<span class="number">2</span>, <span class="number">4</span>, <span class="number">2</span>, <span class="number">1</span>]])</span><br><span class="line">print(null_space(A)) <span class="comment"># 零空间,即基础解系</span></span><br></pre></td></tr></table></figure><p>输出:</p><figure class="highlight plain"><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><span class="line">[[ 0.79428706 -0.07832183]</span><br><span class="line"> [-0.19204896 -0.36561063]</span><br><span class="line"> [-0.52695834 0.38844091]</span><br><span class="line"> [ 0.23353839 0.84220438]]</span><br></pre></td></tr></table></figure><p>两个列向量即为基础解系</p><h2 id="非齐次线性方程组解">非齐次线性方程组解</h2><p><code>numpy.linalg.pinv()</code>可以求矩阵的伪逆矩阵,这样对于形如<span class="math inline">\(Ax=b\)</span>的线性方程组,<code>pinv(A)@b</code>就可以得到一组解</p><p>一般地,当方程组有:</p><ul><li>无穷多组解,得到的是最小范数解</li><li>唯一解,得到的是唯一的那组解</li><li>无解,得到的是最小二乘解<span class="math inline">\(x^*\)</span>,即满足<span class="math inline">\(|Ax^*-b|^2\)</span>最小的解</li></ul><h1 id="特征值与特征向量">特征值与特征向量</h1><p><code>numpy.linalg.eig()</code>可以得到矩阵的特征值和特征向量</p><p>返回二元组分别是特征值和特征向量的list,特征向量表示为列向量</p><p>例如: $$ A=,</p><p>P=,</p><p>=$$ 验证<span class="math inline">\(P^{-1}AP=\Lambda\)</span></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><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"><span class="keyword">from</span> numpy.linalg <span class="keyword">import</span> eig</span><br><span class="line">A = np.array([[<span class="number">0</span>, <span class="number">-2</span>, <span class="number">2</span>], [<span class="number">-2</span>, <span class="number">-3</span>, <span class="number">4</span>], [<span class="number">2</span>, <span class="number">4</span>, <span class="number">-3</span>]])</span><br><span class="line">values, vectors = eig(A)</span><br><span class="line">print(values)</span><br><span class="line">print(vectors)</span><br><span class="line">print(np.linalg.inv(vectors)@A@vectors)</span><br></pre></td></tr></table></figure><p>输出:</p><figure class="highlight plain"><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><span class="line">[ 1. -8. 1.]</span><br><span class="line">[[ 0.94280904 -0.33333333 -0.2981424 ]</span><br><span class="line"> [-0.23570226 -0.66666667 0.74535599]</span><br><span class="line"> [ 0.23570226 0.66666667 0.59628479]]</span><br><span class="line">[[ 1.00000000e+00 -6.10622664e-16 -1.11022302e-16]</span><br><span class="line"> [ 0.00000000e+00 -8.00000000e+00 -4.44089210e-16]</span><br><span class="line"> [-5.55111512e-17 4.44089210e-16 1.00000000e+00]]</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<h1 id="矩阵运算">矩阵运算</h1>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="lin
</summary>
<category term="学习笔记" scheme="http://oi.linkfqy.top/categories/%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"/>
<category term="Python" scheme="http://oi.linkfqy.top/tags/Python/"/>
<category term="NumPy" scheme="http://oi.linkfqy.top/tags/NumPy/"/>
</entry>
<entry>
<title>Python实现拟合</title>
<link href="http://oi.linkfqy.top/posts/Python%E5%AE%9E%E7%8E%B0%E6%8B%9F%E5%90%88/"/>
<id>http://oi.linkfqy.top/posts/Python实现拟合/</id>
<published>2021-08-07T13:30:55.000Z</published>
<updated>2021-08-07T15:22:15.173Z</updated>
<content type="html"><![CDATA[<p>拟合:给定<span class="math inline">\(n\)</span>个数据点,求一<span class="math inline">\(f(x)\)</span>使其与数据点最“接近”,即: <span class="math display">\[J=\sum_{i=1}^n(fx_i-y_i)^2\]</span> 最小,称为最小二乘拟合。</p><p>往往需要提前指定<span class="math inline">\(f(x)\)</span>的类型,常用的有某次多项式、双曲函数、指数函数等</p><p><code>scipy.optimize.curve_fit</code>可以实现任意类型函数的拟合</p><p>用法:</p><p><code>curve_fit(f, xdata, ydata, p0=None)</code></p><ul><li><code>f</code>为一函数:<code>f(x,...)</code>,<code>x</code>为自变量,后面的参数全为拟合函数的待定参数</li><li><code>xdata</code>和<code>ydata</code>是数据点的坐标向量</li><li><code>p0</code>为待定参数的初值向量</li><li>D维情形,x是D维向量,<code>xdata</code>是D维向量构成的序列,p0同</li></ul><p>返回二元组<code>(popt,pcov)</code>:</p><ul><li><code>popt</code>:一维数组,表示拟合函数的参数</li><li><code>pcov</code>:二维阵列,<code>popt</code>的估计协方差。对角线提供参数估计的方差。</li></ul><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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"><span class="keyword">from</span> scipy.optimize <span class="keyword">import</span> curve_fit</span><br><span class="line"><span class="keyword">import</span> pylab <span class="keyword">as</span> plt</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">f</span><span class="params">(x, a, b, c)</span>:</span> <span class="keyword">return</span> a*x**<span class="number">2</span>+b*x+c</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">x = np.arange(<span class="number">0</span>, <span class="number">1.1</span>, <span class="number">0.1</span>)</span><br><span class="line">y = np.array([<span class="number">-0.447</span>, <span class="number">1.978</span>, <span class="number">3.28</span>, <span class="number">6.16</span>, <span class="number">7.08</span>,</span><br><span class="line"> <span class="number">7.34</span>, <span class="number">7.66</span>, <span class="number">9.56</span>, <span class="number">9.48</span>, <span class="number">9.30</span>, <span class="number">11.2</span>])</span><br><span class="line">popt, pcov = curve_fit(f, x, y)</span><br><span class="line">print(<span class="string">"a={}, b={}, c={}"</span>.format(*popt)) <span class="comment"># 打印参数</span></span><br><span class="line">print(<span class="string">"f(0.25)={},f(0.35)={}"</span>.format(</span><br><span class="line"> *f(np.array([<span class="number">0.25</span>, <span class="number">0.35</span>]), *popt))) <span class="comment"># 打印预测值</span></span><br><span class="line">plt.scatter(x, y)</span><br><span class="line">xn = np.linspace(<span class="number">0</span>, <span class="number">1</span>, <span class="number">100</span>)</span><br><span class="line">yn = f(xn, *popt)</span><br><span class="line">plt.plot(xn, yn)</span><br><span class="line">plt.savefig(<span class="string">'1.png'</span>, dpi=<span class="number">500</span>), plt.show()</span><br></pre></td></tr></table></figure><p>输出:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">a=-9.810839009366013, b=20.129292913034863, c=-0.03167107877459929</span><br><span class="line">f(0.25)=4.387474711398741,f(0.35)=5.811753662140266</span><br></pre></td></tr></table></figure><p><img src="/posts/Python实现拟合/1.png"></p><p>对曲面<span class="math inline">\(z=e^{-\frac{(x-\mu_1)^2+(y-\mu_2)^2}{2\sigma^2}}\)</span>添加噪声,再进行拟合,其中<span class="math inline">\(\mu_1=1,\mu_2=2,\sigma=3\)</span></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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"><span class="keyword">from</span> scipy.optimize <span class="keyword">import</span> curve_fit</span><br><span class="line"><span class="keyword">import</span> pylab <span class="keyword">as</span> plt</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">f</span><span class="params">(x, u1, u2, sgm)</span>:</span></span><br><span class="line"> <span class="keyword">return</span> np.exp(-((x[<span class="number">0</span>]-u1)**<span class="number">2</span>+(x[<span class="number">1</span>]-u2)**<span class="number">2</span>)/(<span class="number">2</span>*sgm**<span class="number">2</span>))</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">x = np.linspace(<span class="number">-6</span>, <span class="number">6</span>, <span class="number">200</span>)</span><br><span class="line">y = np.linspace(<span class="number">-8</span>, <span class="number">8</span>, <span class="number">300</span>)</span><br><span class="line">X, Y = np.meshgrid(x, y) <span class="comment"># 获得网格坐标矩阵</span></span><br><span class="line">X = np.reshape(X, (<span class="number">1</span>, <span class="number">-1</span>))</span><br><span class="line">Y = np.reshape(Y, (<span class="number">1</span>, <span class="number">-1</span>)) <span class="comment"># 降维</span></span><br><span class="line">xy = np.vstack((X, Y)) <span class="comment"># 转换成坐标点序列的形式</span></span><br><span class="line">z = f(xy, <span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>) <span class="comment"># 求原始函数的各点值</span></span><br><span class="line">zr = z+<span class="number">0.2</span>*np.random.normal(size=z.shape) <span class="comment"># 生成噪声数据</span></span><br><span class="line">popt, pcov = curve_fit(f, xy, zr)</span><br><span class="line">print(<span class="string">"u1={}, u2={}, sgm={}"</span>.format(*popt)) <span class="comment"># 打印参数</span></span><br><span class="line">zn = f(xy, *popt) <span class="comment"># 求拟合函数的各点值</span></span><br><span class="line">X = np.reshape(X, (<span class="number">200</span>, <span class="number">300</span>))</span><br><span class="line">Y = np.reshape(Y, (<span class="number">200</span>, <span class="number">300</span>))</span><br><span class="line">zn = np.reshape(zn, (<span class="number">200</span>, <span class="number">300</span>))</span><br><span class="line">ax = plt.axes(projection=<span class="string">'3d'</span>)</span><br><span class="line">ax.plot_surface(X, Y, zn, cmap=<span class="string">'gist_rainbow'</span>)</span><br><span class="line">plt.savefig(<span class="string">'2.png'</span>, dpi=<span class="number">500</span>), plt.show()</span><br></pre></td></tr></table></figure><p>输出:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">u1=1.0055785483402968, u2=2.002582704331591, sgm=3.0134682873777496</span><br></pre></td></tr></table></figure><p><img src="/posts/Python实现拟合/2.png"></p>]]></content>
<summary type="html">
<p>拟合:给定<span class="math inline">\(n\)</span>个数据点,求一<span class="math inline">\(f(x)\)</span>使其与数据点最“接近”,即: <span class="math display">\[
</summary>
<category term="学习笔记" scheme="http://oi.linkfqy.top/categories/%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"/>
<category term="Python" scheme="http://oi.linkfqy.top/tags/Python/"/>
<category term="SciPy" scheme="http://oi.linkfqy.top/tags/SciPy/"/>
</entry>
<entry>
<title>Python实现插值</title>
<link href="http://oi.linkfqy.top/posts/Python%E5%AE%9E%E7%8E%B0%E6%8F%92%E5%80%BC/"/>
<id>http://oi.linkfqy.top/posts/Python实现插值/</id>
<published>2021-08-06T16:04:37.000Z</published>
<updated>2021-08-07T07:12:05.611Z</updated>
<content type="html"><![CDATA[<p>插值:求一函数<span class="math inline">\(f(x)\)</span>使其穿过给定的所有数据点<span class="math inline">\((x_i,y_i)\)</span></p><p>在数据分析中很有用</p><h1 id="拉格朗日插值lagrange">拉格朗日插值(Lagrange)</h1><p>拉格朗日插值的<span class="math inline">\(f(x)\)</span>为<span class="math inline">\(n-1\)</span>次多项式,<span class="math inline">\(n\)</span>为数据点个数</p><p>可以证明,任意<span class="math inline">\(n\)</span>个数据点的<span class="math inline">\(n-1\)</span>次插值函数存在且唯一</p><p>具体来说, <span class="math display">\[f(x)=\sum_{i=0}^n l_i(x)y_i \\l_i(x)=\prod_{j=0,j\neq i}^n \frac {x-x_j} {x_i-x_j}\]</span> 由此公式容易用Python实现拉格朗日插值</p><p>但是一次性将所有数据点进行插值,次数过高,不仅复杂度高,误差也大,因此常进行分段插值,即用分段函数表示<span class="math inline">\(f(x)\)</span></p><h1 id="样条插值spline">样条插值(spline)</h1><p>单纯的分段插值得到的函数性质往往不够好(光滑性)</p><p>对于划分:<span class="math inline">\(\Delta:a=x_0<x_1<\dots<x_n=b\)</span>,<span class="math inline">\(m\)</span>阶样条插值函数需要满足:</p><ul><li>在每个小区间<span class="math inline">\([x_i,x_{i+1}](i=0,1,\dots,n-1)\)</span>上是<span class="math inline">\(m\)</span>次多项式</li><li>在区间<span class="math inline">\([a,b]\)</span>上具有<span class="math inline">\(m-1\)</span>阶导数</li></ul><p>显然阶梯插值为0阶样条插值,折线插值为1阶样条插值</p><p>一般直接使用<code>scipy.interpolate</code>实现的样条插值</p><h1 id="scipy.interpolate求解插值问题"><code>scipy.interpolate</code>求解插值问题</h1><h2 id="一维插值interp1d">一维插值(<code>interp1d</code>)</h2><p><code>interp1d(x,y,kind='linear')</code></p><p>前两个参数为数据点向量,kind指定插值方法:</p><table><thead><tr class="header"><th style="text-align: center;">kind</th><th style="text-align: center;">说明</th></tr></thead><tbody><tr class="odd"><td style="text-align: center;"><code>'next','previous'</code></td><td style="text-align: center;">阶梯插值,值为最近的前/后一个<span class="math inline">\(y_i\)</span></td></tr><tr class="even"><td style="text-align: center;"><code>'zero', 'linear', 'quadratic', 'cubic'</code></td><td style="text-align: center;">0,1,2,3阶样条插值</td></tr><tr class="odd"><td style="text-align: center;"><code>0,1,2,3,5,...</code></td><td style="text-align: center;">用<code>int</code>指定样条插值的阶数,3以上只能为奇数</td></tr></tbody></table><p>返回一个插值函数,可以传入<span class="math inline">\(x\)</span>返回<span class="math inline">\(f(x)\)</span>,也可以传入<span class="math inline">\(\vec x\)</span>返回<span class="math inline">\(f(\vec x)\)</span></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><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><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"><span class="keyword">import</span> matplotlib.pyplot <span class="keyword">as</span> plt</span><br><span class="line"><span class="keyword">from</span> scipy.interpolate <span class="keyword">import</span> interp1d</span><br><span class="line">x = np.arange(<span class="number">0</span>, <span class="number">25</span>, <span class="number">2</span>)</span><br><span class="line">y = np.array([<span class="number">12</span>, <span class="number">9</span>, <span class="number">9</span>, <span class="number">10</span>, <span class="number">18</span>, <span class="number">24</span>, <span class="number">28</span>, <span class="number">27</span>, <span class="number">25</span>, <span class="number">20</span>, <span class="number">18</span>, <span class="number">15</span>, <span class="number">13</span>])</span><br><span class="line">xnew = np.linspace(<span class="number">0</span>, <span class="number">24</span>, <span class="number">500</span>)</span><br><span class="line">f0 = interp1d(x, y, <span class="number">0</span>) <span class="comment"># 'zero'</span></span><br><span class="line">y0 = f0(xnew)</span><br><span class="line">f1 = interp1d(x, y)</span><br><span class="line">y1 = f1(xnew)</span><br><span class="line">f3 = interp1d(x, y, <span class="string">'cubic'</span>)</span><br><span class="line">y3 = f3(xnew)</span><br><span class="line">f5 = interp1d(x, y, <span class="number">5</span>)</span><br><span class="line">y5 = f5(xnew)</span><br><span class="line">plt.rc(<span class="string">'font'</span>, size=<span class="number">16</span>)</span><br><span class="line">plt.rc(<span class="string">'font'</span>, family=<span class="string">'SimHei'</span>)</span><br><span class="line">plt.subplot(<span class="number">221</span>), plt.plot(xnew, y0), plt.xlabel(<span class="string">"(A)分段阶梯插值"</span>)</span><br><span class="line">plt.subplot(<span class="number">222</span>), plt.plot(xnew, y1), plt.xlabel(<span class="string">"(B)分段线性插值"</span>)</span><br><span class="line">plt.subplot(<span class="number">223</span>), plt.plot(xnew, y3), plt.xlabel(<span class="string">"(C)三次样条插值"</span>)</span><br><span class="line">plt.subplot(<span class="number">224</span>), plt.plot(xnew, y5), plt.xlabel(<span class="string">"(D)五次样条插值"</span>)</span><br><span class="line">plt.savefig(<span class="string">"interp1d.png"</span>, dpi=<span class="number">500</span>), plt.show()</span><br></pre></td></tr></table></figure><p><img src="/posts/Python实现插值/interp1d.png"></p><h2 id="二维插值interp2d">二维插值(<code>interp2d</code>)</h2><p><code>interp2d(x,y,z,kind='linear')</code>接受网格分布的数据点进行插值</p><p>x,y为坐标向量,z为数据矩阵</p><p>返回一个插值函数,输入x,y向量即可获得数据矩阵</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><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><span class="line"><span class="keyword">from</span> IPython.core.pylabtools <span class="keyword">import</span> figsize</span><br><span class="line"><span class="keyword">import</span> matplotlib.pyplot <span class="keyword">as</span> plt</span><br><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"><span class="keyword">from</span> scipy.interpolate <span class="keyword">import</span> interp2d</span><br><span class="line"><span class="keyword">from</span> mpl_toolkits <span class="keyword">import</span> mplot3d</span><br><span class="line">z = np.loadtxt(<span class="string">"data.txt"</span>)</span><br><span class="line">x = np.arange(<span class="number">0</span>, <span class="number">1500</span>, <span class="number">100</span>)</span><br><span class="line">y = np.arange(<span class="number">1200</span>, <span class="number">-100</span>, <span class="number">-100</span>) <span class="comment"># 文件里的y是倒序输入的</span></span><br><span class="line">f = interp2d(x, y, z, kind=<span class="string">'cubic'</span>)</span><br><span class="line">xn = np.linspace(<span class="number">0</span>, <span class="number">1400</span>, <span class="number">141</span>)</span><br><span class="line">yn = np.linspace(<span class="number">0</span>, <span class="number">1200</span>, <span class="number">121</span>)</span><br><span class="line">zn = f(xn, yn)</span><br><span class="line">plt.rc(<span class="string">'font'</span>, size=<span class="number">16</span>)</span><br><span class="line">plt.subplot(<span class="number">1</span>, <span class="number">2</span>, <span class="number">1</span>)</span><br><span class="line">plt.contour(xn, yn, zn)</span><br><span class="line">plt.xlabel(<span class="string">'$x$'</span>), plt.ylabel(<span class="string">'$y$'</span>, rotation=<span class="number">90</span>)</span><br><span class="line">ax = plt.subplot(<span class="number">1</span>, <span class="number">2</span>, <span class="number">2</span>, projection=<span class="string">'3d'</span>)</span><br><span class="line">X, Y = np.meshgrid(xn, yn)</span><br><span class="line">ax.plot_surface(X, Y, zn, cmap=<span class="string">'viridis'</span>)</span><br><span class="line">ax.set_xlabel(<span class="string">'$x$'</span>), ax.set_ylabel(<span class="string">'$y$'</span>), ax.set_zlabel(<span class="string">'$z$'</span>)</span><br><span class="line">plt.savefig(<span class="string">'interp2d.png'</span>, dpi=<span class="number">500</span>), plt.show()</span><br></pre></td></tr></table></figure><p><img src="/posts/Python实现插值/interp2d.png"></p><h2 id="散点插值griddata">散点插值(<code>griddata</code>)</h2><p>若数据点并无分布规律,可用<code>griddata</code>进行插值</p><p>可处理任意D维的数据点</p><p><code>griddata(points, values, xi, method='linear')</code></p><p><code>points</code>为数据点位置(D维向量)的序列,<code>values</code>为数据点值的序列</p><p><code>xi</code>为需要插值的空间,形式与<code>points</code>相同,或用格点坐标矩阵的D元组表示</p><p><code>method</code>插值方法:<code>'nearest','linear','cubic'</code>分别对应0,1,3阶插值</p><p>返回<code>xi</code>中的数据值</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><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><span class="line"><span class="keyword">from</span> mpl_toolkits <span class="keyword">import</span> mplot3d</span><br><span class="line"><span class="keyword">import</span> matplotlib.pyplot <span class="keyword">as</span> plt</span><br><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"><span class="keyword">from</span> scipy.interpolate <span class="keyword">import</span> griddata</span><br><span class="line">x = np.array([<span class="number">129</span>, <span class="number">140</span>, <span class="number">103.5</span>, <span class="number">88</span>, <span class="number">185.5</span>, <span class="number">195</span>, <span class="number">105</span>,</span><br><span class="line"> <span class="number">157.5</span>, <span class="number">107.5</span>, <span class="number">77</span>, <span class="number">81</span>, <span class="number">162</span>, <span class="number">162</span>, <span class="number">117.5</span>])</span><br><span class="line">y = np.array([<span class="number">7.5</span>, <span class="number">141.5</span>, <span class="number">23</span>, <span class="number">147</span>, <span class="number">22.5</span>, <span class="number">137.5</span>, <span class="number">85.5</span>, -</span><br><span class="line"> <span class="number">6.5</span>, <span class="number">-81</span>, <span class="number">3</span>, <span class="number">56.5</span>, <span class="number">-66.5</span>, <span class="number">84</span>, <span class="number">-33.5</span>])</span><br><span class="line">z = -np.array([<span class="number">4</span>, <span class="number">8</span>, <span class="number">6</span>, <span class="number">8</span>, <span class="number">6</span>, <span class="number">8</span>, <span class="number">8</span>, <span class="number">9</span>, <span class="number">9</span>, <span class="number">8</span>, <span class="number">8</span>, <span class="number">9</span>, <span class="number">4</span>, <span class="number">9</span>])</span><br><span class="line">xy = np.array([x, y]).T</span><br><span class="line">xn = np.linspace(x.min(), x.max(), <span class="number">100</span>)</span><br><span class="line">yn = np.linspace(y.min(), y.max(), <span class="number">100</span>)</span><br><span class="line">X, Y = np.meshgrid(xn, yn)</span><br><span class="line">zn = griddata(xy, z, (X, Y), method=<span class="string">'nearest'</span>)</span><br><span class="line">ax = plt.subplot(<span class="number">121</span>, projection=<span class="string">'3d'</span>)</span><br><span class="line">ax.plot_surface(X, Y, zn, cmap=<span class="string">'viridis'</span>)</span><br><span class="line">ax.set_xlabel(<span class="string">'$x$'</span>), ax.set_ylabel(<span class="string">'$y$'</span>), ax.set_zlabel(<span class="string">'$z$'</span>)</span><br><span class="line">plt.subplot(<span class="number">122</span>)</span><br><span class="line">a = plt.contourf(X, Y, zn, <span class="number">8</span>, cmap=plt.cm.Spectral)</span><br><span class="line">plt.clabel(plt.contour(xn, yn, zn))</span><br><span class="line">plt.colorbar(a)</span><br><span class="line">plt.savefig(<span class="string">'griddata.png'</span>, dpi=<span class="number">500</span>), plt.show()</span><br></pre></td></tr></table></figure><p><img src="/posts/Python实现插值/griddata.png"></p>]]></content>
<summary type="html">
<p>插值:求一函数<span class="math inline">\(f(x)\)</span>使其穿过给定的所有数据点<span class="math inline">\((x_i,y_i)\)</span></p>
<p>在数据分析中很有用</p>
<h1 id=
</summary>
<category term="学习笔记" scheme="http://oi.linkfqy.top/categories/%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"/>
<category term="Python" scheme="http://oi.linkfqy.top/tags/Python/"/>
<category term="SciPy" scheme="http://oi.linkfqy.top/tags/SciPy/"/>
</entry>
<entry>
<title>SciPy解非线性规划</title>
<link href="http://oi.linkfqy.top/posts/SciPy%E8%A7%A3%E9%9D%9E%E7%BA%BF%E6%80%A7%E8%A7%84%E5%88%92/"/>
<id>http://oi.linkfqy.top/posts/SciPy解非线性规划/</id>
<published>2021-08-05T15:59:25.000Z</published>
<updated>2021-08-05T16:51:59.725Z</updated>
<content type="html"><![CDATA[<p>与线性规划不同,非线性规划的目标函数和约束都不一定是线性的</p><p>因此最优解也不一定在可行域边界上,一般而言用迭代算法得到的也只是局部最优解</p><p>标准模型如下: <span class="math display">\[\min f(\vec x) \\\text{s.t.}\begin{cases} g_i(\vec x) \geq 0,\ \ \ i=1,2,...,m, \\ h_i(\vec x) = 0,\ \ \ i=1,2,...,l,\end{cases}\]</span> <code>scipy.optimize.minimize</code>可以解决非线性规划问题</p><p>用法:</p><p><code>minimize(fun,x0,bounds=None,constraints=None)</code></p><p>其中<code>fun</code>为目标函数,输入一个向量<span class="math inline">\(\vec x\)</span>返回对应值</p><p><code>x0</code>为迭代初值,决定是否能取到全局最优解</p><p><code>bounds</code>与线性规划的<code>linprog</code>一样</p><p><code>constraints</code>为约束条件,具体实现为单个dict或dict的序列,每个dict应有两个键值:</p><ul><li><p><code>type</code>:字符串<code>'eq'</code>和<code>'ineq'</code>之一,表示该约束为等号约束或不等号约束</p></li><li><p><code>fun</code>:函数,传入向量<span class="math inline">\(\vec x\)</span>,返回约束式的左值,在可行解中该值大于等于0(不等号约束)/等于0(等号约束)</p><p>特别地,若有一系列约束为线性约束,则可将一系列右值视为一个向量,利用<code>numpy.array</code>重载的比较符号,</p><p>将这些约束缩为一个,即<code>lambda x:b-A@x</code></p></li></ul>]]></content>
<summary type="html">
<p>与线性规划不同,非线性规划的目标函数和约束都不一定是线性的</p>
<p>因此最优解也不一定在可行域边界上,一般而言用迭代算法得到的也只是局部最优解</p>
<p>标准模型如下: <span class="math display">\[
\min f(\vec x)
</summary>
<category term="学习笔记" scheme="http://oi.linkfqy.top/categories/%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"/>
<category term="Python" scheme="http://oi.linkfqy.top/tags/Python/"/>
<category term="SciPy" scheme="http://oi.linkfqy.top/tags/SciPy/"/>
</entry>
<entry>
<title>SciPy解决线性规划问题</title>
<link href="http://oi.linkfqy.top/posts/SciPy%E8%A7%A3%E5%86%B3%E7%BA%BF%E6%80%A7%E8%A7%84%E5%88%92%E9%97%AE%E9%A2%98/"/>
<id>http://oi.linkfqy.top/posts/SciPy解决线性规划问题/</id>
<published>2021-08-04T12:25:14.000Z</published>
<updated>2021-08-04T15:55:17.828Z</updated>
<content type="html"><![CDATA[<p><code>scipy.optimize.linprog</code>可以解决线性规划问题</p><p>标准模型: <span class="math display">\[\min_x \ z= c^T x, \\ \mbox{s.t.} \ \begin{cases} A x \leq b,\\ A_{eq} x = b_{eq},\\ l \leq x \leq u . \end{cases}\]</span> 其中<span class="math inline">\(A\)</span>和<span class="math inline">\(A_{eq}\)</span>分别是不等约束和等号约束的系数矩阵,<span class="math inline">\(l\)</span>和<span class="math inline">\(u\)</span>是上下界向量</p><p>用法:</p><p><code>linprog(c, A=None, b=None, Aeq=None, beq=None, bounds=None)</code></p><p>前5个参数对应标准模型,bounds是一个由<code>(li,ui)</code>组成的序列,表示每个<code>xi</code>的边界</p><p>当<code>bounds</code>为<code>None</code>时,默认下界全为0,上界全为正无穷</p><p>返回的对象记为<code>res</code>,具有以下属性:</p><p><code>res.fun</code>为目标函数的最小值,<code>res.x</code>为最优解</p><p>示例: <span class="math display">\[\min_x \ z= -x_1+4x_2, \\ \mbox{s.t.} \ \begin{cases} -3x_1+x_2 \leq 6,\\ x_1+2x_2 \leq 4,\\ x_2 \geq -3 . \end{cases}\]</span></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><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><span class="line"><span class="keyword">from</span> scipy.optimize <span class="keyword">import</span> linprog</span><br><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line">c = [<span class="number">-1</span>, <span class="number">4</span>]</span><br><span class="line">A = [[<span class="number">-3</span>, <span class="number">1</span>], [<span class="number">1</span>, <span class="number">2</span>]]</span><br><span class="line">b = [<span class="number">6</span>, <span class="number">4</span>]</span><br><span class="line">bounds = [[<span class="keyword">None</span>, <span class="keyword">None</span>], [<span class="number">-3</span>, <span class="keyword">None</span>]]</span><br><span class="line"><span class="comment"># A = [[-3, 1], [1, 2], [0, -1]]</span></span><br><span class="line"><span class="comment"># b = [6, 4, 3]</span></span><br><span class="line"><span class="comment"># bounds = [[None, None], [None, None]] # 与bounds=None区别</span></span><br><span class="line">res = linprog(c, A, b, <span class="keyword">None</span>, <span class="keyword">None</span>, bounds)</span><br><span class="line">print(res.fun)</span><br><span class="line">print(res.x)</span><br></pre></td></tr></table></figure><p>输出:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">-21.99999984082492</span><br><span class="line">[ 9.99999989 -2.99999999]</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<p><code>scipy.optimize.linprog</code>可以解决线性规划问题</p>
<p>标准模型: <span class="math display">\[
\min_x \ z= c^T x, \\
\mbox{s.t.} \
</summary>
<category term="学习笔记" scheme="http://oi.linkfqy.top/categories/%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"/>
<category term="Python" scheme="http://oi.linkfqy.top/tags/Python/"/>
<category term="SciPy" scheme="http://oi.linkfqy.top/tags/SciPy/"/>
</entry>
<entry>
<title>SymPy实现高等数学符号解</title>
<link href="http://oi.linkfqy.top/posts/SymPy%E5%AE%9E%E7%8E%B0%E9%AB%98%E7%AD%89%E6%95%B0%E5%AD%A6%E7%AC%A6%E5%8F%B7%E8%A7%A3/"/>
<id>http://oi.linkfqy.top/posts/SymPy实现高等数学符号解/</id>
<published>2021-08-03T01:42:19.000Z</published>
<updated>2021-08-04T01:44:00.847Z</updated>
<content type="html"><![CDATA[<p>一些前置知识:</p><p><code>x=symbols('x')</code>声明变量<span class="math inline">\(x\)</span></p><p><code>y.subs(x,x0)</code><span class="math inline">\(y\)</span>是<span class="math inline">\(x\)</span>的表达式时,带入<span class="math inline">\(x=x_0\)</span>的值</p><p><code>y.n()</code>常量表达式求浮点值</p><h1 id="求极限">求极限</h1><p><code>limit(e, z, z0, dir="+")</code></p><p><span class="math inline">\(e\)</span>是<span class="math inline">\(z\)</span>的表达式,求<span class="math inline">\(e(z)\)</span>在<span class="math inline">\(z_0\)</span>处的极限,<span class="math inline">\(\text{dir}\)</span>可以指定是<span class="math inline">\(z_0^+\)</span>还是<span class="math inline">\(z_0^-\)</span></p><p>以下计算了<span class="math inline">\(\lim_{x\rightarrow 0}\frac{\sin x}x\)</span>,<span class="math inline">\(\lim_{x\rightarrow \infty} (1+\frac 1 x)^x\)</span>,<span class="math inline">\(\lim_{x\rightarrow 0}\sin(\frac 1 x)\)</span>三个极限</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><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> sympy <span class="keyword">import</span> *</span><br><span class="line">x = symbols(<span class="string">'x'</span>)</span><br><span class="line">print(limit(sin(x)/x, x, <span class="number">0</span>))</span><br><span class="line">print(limit(pow(<span class="number">1</span>+<span class="number">1</span>/x, x), x, oo))</span><br><span class="line">print(limit(sin(<span class="number">1</span>/x), x, <span class="number">0</span>))</span><br></pre></td></tr></table></figure><p>输出:</p><figure class="highlight plain"><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><span class="line">1</span><br><span class="line">E</span><br><span class="line">AccumBounds(-1, 1)</span><br></pre></td></tr></table></figure><h1 id="求导数">求导数</h1><p><code>diff(expr,x1,n1,x2,n2,...)</code></p><p>表达式<code>expr</code>依次对<code>xi</code>求<code>ni</code>阶偏导,<code>ni</code>不写默认为1</p><p><span class="math inline">\(z=\sin x+x^2e^y\)</span>,求<span class="math inline">\(\frac{\partial^2 z}{\partial x^2},\frac{\partial z}{\partial y},\frac{\partial^2 z}{\partial x\partial y}\)</span></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><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> sympy <span class="keyword">import</span> *</span><br><span class="line">x, y = symbols(<span class="string">"x y"</span>)</span><br><span class="line">z = sin(x)+x**<span class="number">2</span>*exp(y)</span><br><span class="line">print(diff(z, x, <span class="number">2</span>))</span><br><span class="line">print(diff(z, y))</span><br><span class="line">print(diff(z, x, y))</span><br></pre></td></tr></table></figure><p>输出:</p><figure class="highlight plain"><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><span class="line">2*exp(y) - sin(x)</span><br><span class="line">x**2*exp(y)</span><br><span class="line">2*x*exp(y)</span><br></pre></td></tr></table></figure><h1 id="级数求和">级数求和</h1><p><code>summation(expr,(i,a,b))</code></p><p>expr是关于i的函数,求<span class="math inline">\(\sum_{i=a}^b expr(i)\)</span></p><p>示例:<span class="math inline">\(\sum_{k=1}^n k^2\)</span>和<span class="math inline">\(\sum_{k=1}^\infty \frac 1 {k^2}\)</span></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><span class="line"><span class="keyword">from</span> sympy <span class="keyword">import</span> *</span><br><span class="line">k, n = symbols(<span class="string">'k n'</span>)</span><br><span class="line">print(factor(summation(k**<span class="number">2</span>, (k, <span class="number">1</span>, n)))) <span class="comment"># 计算结果因式分解</span></span><br><span class="line">print(summation(<span class="number">1</span>/k**<span class="number">2</span>, (k, <span class="number">1</span>, oo)))</span><br></pre></td></tr></table></figure><p>输出:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">n*(n + 1)*(2*n + 1)/6</span><br><span class="line">pi**2/6</span><br></pre></td></tr></table></figure><h1 id="泰勒展开">泰勒展开</h1><p><code>series(expr, x=None, x0=0, n=6, dir="+")</code></p><p><span class="math inline">\(expr\)</span>是<span class="math inline">\(x\)</span>的表达式,在<span class="math inline">\(x_0\)</span>处的<span class="math inline">\(n\)</span>阶展开,<span class="math inline">\(\text{dir}\)</span>可以指定是<span class="math inline">\(x_0^+\)</span>还是<span class="math inline">\(x_0^-\)</span></p><p>下面演示了<span class="math inline">\(\sin x\)</span>在0点的3,5,7阶泰勒展开式</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><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><span class="line"><span class="keyword">from</span> pylab <span class="keyword">import</span> rc</span><br><span class="line"><span class="keyword">from</span> sympy <span class="keyword">import</span> *</span><br><span class="line"><span class="keyword">from</span> sympy.plotting <span class="keyword">import</span> *</span><br><span class="line">rc(<span class="string">'font'</span>, size=<span class="number">16</span>)</span><br><span class="line">x = symbols(<span class="string">'x'</span>)</span><br><span class="line">y = sin(x)</span><br><span class="line">yi = list(range(<span class="number">8</span>))</span><br><span class="line"><span class="keyword">for</span> k <span class="keyword">in</span> range(<span class="number">3</span>, <span class="number">8</span>, <span class="number">2</span>):</span><br><span class="line"> print(series(y, x, <span class="number">0</span>, k))</span><br><span class="line"> yi[k] = series(y, x, <span class="number">0</span>, k).removeO() <span class="comment"># 带有余项的表达式无法作图</span></span><br><span class="line">plot(y, yi[<span class="number">3</span>], yi[<span class="number">5</span>], yi[<span class="number">7</span>], (x, <span class="number">0</span>, <span class="number">2</span>),</span><br><span class="line"> xlabel=<span class="string">'$x$'</span>, ylabel=<span class="string">'$y$'</span>).save(<span class="string">'series.png'</span>)</span><br></pre></td></tr></table></figure><p>输出:</p><figure class="highlight plain"><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><span class="line">x + O(x**3)</span><br><span class="line">x - x**3/6 + O(x**5)</span><br><span class="line">x - x**3/6 + x**5/120 + O(x**7)</span><br></pre></td></tr></table></figure><p><img src="/posts/SymPy实现高等数学符号解/series.png"></p><h1 id="积分">积分</h1><p>不定积分:</p><p><code>integrate(f,x)</code></p><p>相当于<span class="math inline">\(\int f(x)\mathrm d x\)</span></p><p>定积分:</p><p><code>integrate(f,(x,a,b))</code></p><p>相当于<span class="math inline">\(\int_a^b f(x)\mathrm d x\)</span></p><p>以下代码求解<span class="math inline">\(\int_0^\pi \sin(2x)\mathrm d x,\int_0^{+\infty} \frac {\sin(x)} x\mathrm d x,\int \sin(x)e^x\mathrm d x\)</span></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><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> sympy <span class="keyword">import</span> *</span><br><span class="line">x = symbols(<span class="string">'x'</span>)</span><br><span class="line">print(integrate(sin(<span class="number">2</span>*x), (x, <span class="number">0</span>, pi)))</span><br><span class="line">print(integrate(sin(x)/x, (x, <span class="number">0</span>, oo)))</span><br><span class="line">print(integrate(sin(x)*exp(x), x))</span><br></pre></td></tr></table></figure><p>输出:</p><figure class="highlight plain"><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><span class="line">0</span><br><span class="line">pi/2</span><br><span class="line">exp(x)*sin(x)/2 - exp(x)*cos(x)/2</span><br></pre></td></tr></table></figure><h1 id="解代数方程组">解代数方程(组)</h1><p><code>solve(expr,x)</code></p><p>求解方程<span class="math inline">\(expr=0\)</span>,其中<span class="math inline">\(x\)</span>是自变量</p><p>返回一个list存放所有的根</p><p><code>solve([...,expr_i,...],[...,x_i,...])</code></p><p>求解方程组,其中<span class="math inline">\(expr_i\)</span>对应<span class="math inline">\(x_i\)</span></p><p>返回一个list存放所有根,每个根用一个tuple表示,对应此根所有各个变量的值</p><p><code>roots(expr,x)</code></p><p>返回一个dict,表示每个根以及它的重数</p><p>示例: <span class="math display">\[x^3-1=0 \\(x-2)^2(x-1)^3=0 \\\begin{equation} \begin{cases} x^2+y^2=1 \\ x-y=0 \end{cases}\end{equation}\]</span></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><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> sympy <span class="keyword">import</span> *</span><br><span class="line">x, y = symbols(<span class="string">"x y"</span>)</span><br><span class="line">print(solve(x**<span class="number">3</span><span class="number">-1</span>, x))</span><br><span class="line">print(solve((x<span class="number">-2</span>)**<span class="number">2</span>*(x<span class="number">-1</span>)**<span class="number">3</span>, x))</span><br><span class="line">print(roots((x<span class="number">-2</span>)**<span class="number">2</span>*(x<span class="number">-1</span>)**<span class="number">3</span>, x))</span><br><span class="line">print(solve([x**<span class="number">2</span>+y**<span class="number">2</span><span class="number">-1</span>, x-y], [x, y]))</span><br></pre></td></tr></table></figure><p>输出:</p><figure class="highlight plain"><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><span class="line">[1, -1/2 - sqrt(3)*I/2, -1/2 + sqrt(3)*I/2]</span><br><span class="line">[1, 2]</span><br><span class="line">{2: 2, 1: 3}</span><br><span class="line">[(-sqrt(2)/2, -sqrt(2)/2), (sqrt(2)/2, sqrt(2)/2)]</span><br></pre></td></tr></table></figure><h1 id="微分方程组的通解">微分方程(组)的通解</h1><p>微分方程中的<span class="math inline">\(y\)</span>是关于<span class="math inline">\(x\)</span>的函数,而且是未知函数,而非未知量,因此要将<span class="math inline">\(y\)</span>声明为Function</p><p><code>y=Function('y')</code></p><p><code>y=symbols('y',cls=Function)</code></p><p>两种写法都是可以的</p><p><code>dsolve(eq,f(x),ics=)</code>,其中<code>eq</code>是关于<code>f(x)</code>的表达式,求解<span class="math inline">\(eq=0\)</span></p><p>ics可以以一个dict指定f(x)的初值</p><p>示例: <span class="math display">\[y''-5y'+6y=0 \\y''-5y'+6y=xe^{2x} \\y''-5y'+6y=0,y(0)=1,y'(0)=0 \\y''-5y'+6y=xe^{2x},y(0)=1,y(2)=0\]</span></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><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><span class="line"><span class="keyword">from</span> sympy <span class="keyword">import</span> *</span><br><span class="line">x = symbols(<span class="string">'x'</span>)</span><br><span class="line">y = Function(<span class="string">'y'</span>)</span><br><span class="line">eq1 = diff(y(x), x, <span class="number">2</span>)<span class="number">-5</span>*diff(y(x), x)+<span class="number">6</span>*y(x)</span><br><span class="line">eq2 = diff(y(x), x, <span class="number">2</span>)<span class="number">-5</span>*diff(y(x), x)+<span class="number">6</span>*y(x)-x*exp(<span class="number">2</span>*x)</span><br><span class="line">print(dsolve(eq1, y(x)))</span><br><span class="line">print(dsolve(eq2, y(x)))</span><br><span class="line">print(dsolve(eq1, y(x), ics={y(<span class="number">0</span>): <span class="number">1</span>, diff(y(x), x).subs(x, <span class="number">0</span>): <span class="number">0</span>}))</span><br><span class="line">print(dsolve(eq2, y(x), ics={y(<span class="number">0</span>): <span class="number">1</span>, y(<span class="number">2</span>): <span class="number">0</span>}))</span><br></pre></td></tr></table></figure><p>输出:</p><figure class="highlight plain"><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><span class="line">Eq(y(x), (C1 + C2*exp(x))*exp(2*x))</span><br><span class="line">Eq(y(x), (C1 + C2*exp(x) - x**2/2 - x)*exp(2*x))</span><br><span class="line">Eq(y(x), (3 - 2*exp(x))*exp(2*x))</span><br><span class="line">Eq(y(x), (-x**2/2 - x - 3*exp(x)/(1 - exp(2)) + (4 - exp(2))/(1 - exp(2)))*exp(2*x))</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<p>一些前置知识:</p>
<p><code>x=symbols('x')</code>声明变量<span class="math inline">\(x\)</span></p>
<p><code>y.subs(x,x0)</code><span class="math
</summary>
<category term="学习笔记" scheme="http://oi.linkfqy.top/categories/%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"/>
<category term="Python" scheme="http://oi.linkfqy.top/tags/Python/"/>
<category term="SymPy" scheme="http://oi.linkfqy.top/tags/SymPy/"/>
</entry>
<entry>
<title>SymPy符号制图</title>
<link href="http://oi.linkfqy.top/posts/SymPy%E7%AC%A6%E5%8F%B7%E5%88%B6%E5%9B%BE/"/>
<id>http://oi.linkfqy.top/posts/SymPy符号制图/</id>
<published>2021-08-02T07:03:59.000Z</published>
<updated>2021-08-03T01:43:38.730Z</updated>
<content type="html"><![CDATA[<p>与Matplotlib不同,SymPy无需离散的数据,仅需符号表达式即可制图</p><h1 id="二维曲线">二维曲线</h1><p>单个图像:</p><p><code>plot(expr, range, **kwargs)</code></p><p>其中<code>expr</code>为表达式,表达式由<code>sympy.abc</code>导入的符号组成</p><p><code>range</code>为三元组<code>(x,l,r)</code>,指定了自变量以及上下界</p><p><code>**kwargs</code>指定的参数与<code>matplotlib</code>类似,这里不做过多介绍</p><p>多个图像在同一范围:</p><p><code>plot(expr1, expr2, ..., range, **kwargs)</code></p><p>多个图像在不同范围:</p><p><code>plot((expr1, range1), (expr2, range2), ..., **kwargs)</code></p><p>以下代码画出了<span class="math inline">\(y_1=2\sin x,\ x\in [-6,6]\)</span>和<span class="math inline">\(y_2=\cos(x+\frac \pi 4),\ x\in [-5,5]\)</span>的图像</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><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> sympy.plotting <span class="keyword">import</span> plot</span><br><span class="line"><span class="keyword">from</span> sympy.abc <span class="keyword">import</span> x, pi</span><br><span class="line"><span class="keyword">from</span> sympy.functions <span class="keyword">import</span> sin, cos</span><br><span class="line">p = plot((<span class="number">2</span>*sin(x), (x, <span class="number">-6</span>, <span class="number">6</span>)), (cos(x+pi/<span class="number">4</span>), (x, <span class="number">-5</span>, <span class="number">5</span>)),</span><br><span class="line"> show=<span class="keyword">False</span>, xlabel=<span class="string">'$x$'</span>, ylabel=<span class="string">'$y$'</span>)</span><br><span class="line">p.save(<span class="string">"plot.png"</span>)</span><br><span class="line">p.show()</span><br></pre></td></tr></table></figure><p><img src="/posts/SymPy符号制图/plot.png"></p><h1 id="三维曲线">三维曲线</h1><p><span class="math inline">\(z=\sin(\sqrt{x^2+y^2})\)</span></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><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><span class="line"><span class="keyword">from</span> pylab <span class="keyword">import</span> rc</span><br><span class="line"><span class="keyword">from</span> sympy.plotting <span class="keyword">import</span> plot3d</span><br><span class="line"><span class="keyword">from</span> sympy.abc <span class="keyword">import</span> x, y</span><br><span class="line"><span class="keyword">from</span> sympy.functions <span class="keyword">import</span> sin, sqrt</span><br><span class="line">rc(<span class="string">'font'</span>, size=<span class="number">16</span>)</span><br><span class="line">p = plot3d(sin(sqrt(x**<span class="number">2</span>+y**<span class="number">2</span>)), show=<span class="keyword">False</span>, xlabel=<span class="string">'$x$'</span>, ylabel=<span class="string">'$y$'</span>)</span><br><span class="line">p.save(<span class="string">'plot3d.png'</span>)</span><br><span class="line">p.show()</span><br></pre></td></tr></table></figure><p><img src="/posts/SymPy符号制图/plot3d.png"></p><h1 id="隐函数画图">隐函数画图</h1><p>用<code>sumpy.Eq</code>表示一个方程</p><p><code>Eq(expr_a,expr_b)</code>表示等式两边分别是<code>expr_a,expr_b</code></p><p><code>Eq(expr)</code>等价于<code>Eq(expr,0)</code></p><p><span class="math inline">\((x-1)^2+(y-2)^2-4=0\)</span></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><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><span class="line"><span class="keyword">from</span> pylab <span class="keyword">import</span> rc</span><br><span class="line"><span class="keyword">from</span> sympy <span class="keyword">import</span> plot_implicit, Eq</span><br><span class="line"><span class="keyword">from</span> sympy.abc <span class="keyword">import</span> x, y</span><br><span class="line">rc(<span class="string">'font'</span>, size=<span class="number">16</span>)</span><br><span class="line">p = plot_implicit(Eq((x<span class="number">-1</span>)**<span class="number">2</span>+(y<span class="number">-2</span>)**<span class="number">2</span><span class="number">-4</span>), show=<span class="keyword">False</span>,</span><br><span class="line"> xlabel=<span class="string">'$x$'</span>, ylabel=<span class="string">'$y$'</span>)</span><br><span class="line">p.save(<span class="string">'plot_implicit.png'</span>)</span><br><span class="line">p.show()</span><br></pre></td></tr></table></figure><p><img src="/posts/SymPy符号制图/plot_implicit.png"></p>]]></content>
<summary type="html">
<p>与Matplotlib不同,SymPy无需离散的数据,仅需符号表达式即可制图</p>
<h1 id="二维曲线">二维曲线</h1>
<p>单个图像:</p>
<p><code>plot(expr, range, **kwargs)</code></p>
<p>其中
</summary>
<category term="学习笔记" scheme="http://oi.linkfqy.top/categories/%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"/>
<category term="Python" scheme="http://oi.linkfqy.top/tags/Python/"/>
<category term="Sympy" scheme="http://oi.linkfqy.top/tags/Sympy/"/>
</entry>
<entry>
<title>Python使用Matplotlib作图</title>
<link href="http://oi.linkfqy.top/posts/Python%E4%BD%BF%E7%94%A8Matplotlib%E4%BD%9C%E5%9B%BE/"/>
<id>http://oi.linkfqy.top/posts/Python使用Matplotlib作图/</id>
<published>2021-08-01T12:43:30.000Z</published>
<updated>2021-08-03T01:43:55.801Z</updated>
<content type="html"><![CDATA[<p><code>Matplotlib.pyplot</code>将原本面向对象的作图操作封装成函数,使之更近似于MATLAB的交互式命令</p><p>只要有离散的数据,就可以做出柱状、散点、饼状、折线、3D图形等可视化图表</p><h1 id="柱状图bar">柱状图(bar)</h1><p><code>pyplot.bar()</code>只需提供两个数组作为各数据的横纵坐标,即可生成柱状图</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><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><span class="line"><span class="keyword">from</span> matplotlib <span class="keyword">import</span> rcParams</span><br><span class="line"><span class="keyword">from</span> matplotlib.pyplot <span class="keyword">import</span> *</span><br><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line">y = np.array((<span class="number">2100</span>, <span class="number">3000</span>, <span class="number">4000</span>))</span><br><span class="line">x = np.array([<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>])</span><br><span class="line">width = <span class="number">0.2</span></span><br><span class="line">rc(<span class="string">'font'</span>, size=<span class="number">16</span>)</span><br><span class="line">bar(x, y, width) <span class="comment"># 指定柱宽</span></span><br><span class="line">ylabel(<span class="string">"消费数据"</span>)</span><br><span class="line">xticks(x, [<span class="string">"用户A"</span>, <span class="string">"用户B"</span>, <span class="string">"用户C"</span>], rotation=<span class="number">20</span>) <span class="comment"># 将x标签改为用户名,并旋转20度显示</span></span><br><span class="line">rcParams[<span class="string">'font.sans-serif'</span>] = [<span class="string">'SimHei'</span>] <span class="comment"># 设置中文字体,否则会乱码</span></span><br><span class="line">savefig(<span class="string">'bar.png'</span>, dpi=<span class="number">500</span>)</span><br><span class="line">show() <span class="comment"># 显示在屏幕</span></span><br></pre></td></tr></table></figure><p>效果图:</p><p><img src="/posts/Python使用Matplotlib作图/bar.png"></p><p>若要显示负号,需<code>rcParams['axes.unicode_minus']=False</code></p><h1 id="散点图scatter">散点图(scatter)</h1><p>与<code>bar</code>类似</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><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><span class="line"><span class="keyword">from</span> numpy.linalg.linalg <span class="keyword">import</span> _eigvalsh_dispatcher</span><br><span class="line"><span class="keyword">from</span> pylab <span class="keyword">import</span> * <span class="comment"># pylab=pyplot+部分numpy函数</span></span><br><span class="line">x = array(range(<span class="number">1</span>, <span class="number">8</span>))</span><br><span class="line">y = <span class="string">"27.0 26.5 26.3 26.1 25.7 25.3 24.8"</span></span><br><span class="line">y = <span class="string">","</span>.join(y.split())</span><br><span class="line">y = array(eval(y))</span><br><span class="line">scatter(x, y, marker=<span class="string">'*'</span>) <span class="comment"># 用星形显示散点</span></span><br><span class="line">savefig(<span class="string">"scatter.png"</span>, dpi=<span class="number">500</span>)</span><br><span class="line">show()</span><br></pre></td></tr></table></figure><p><img src="/posts/Python使用Matplotlib作图/scatter.png"></p><h1 id="折线图plot">折线图(plot)</h1><p>基本用法为<code>plot(x,y,s)</code>,前两个参数为数据点的横纵坐标,s为指定线条颜色、线条样式和数据点形状的字符串</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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"><span class="keyword">from</span> matplotlib.pyplot <span class="keyword">import</span> *</span><br><span class="line">x = np.linspace(<span class="number">0</span>, <span class="number">2</span>*np.pi, <span class="number">200</span>)</span><br><span class="line">y1 = np.sin(x)</span><br><span class="line">y2 = np.cos(pow(x, <span class="number">2</span>))</span><br><span class="line">rc(<span class="string">'font'</span>, size=<span class="number">16</span>)</span><br><span class="line"><span class="comment"># rc('text', usetex=True) # 可以用LaTeX字体显示</span></span><br><span class="line">plot(x, y1, <span class="string">'r-'</span>, label=<span class="string">'$sin(x)$'</span>, linewidth=<span class="number">2</span>) <span class="comment"># 红色实线</span></span><br><span class="line">plot(x, y2, <span class="string">'b--'</span>, label=<span class="string">'$cos(x^2)$'</span>) <span class="comment"># 蓝色虚线</span></span><br><span class="line">xlabel(<span class="string">'$x$'</span>)</span><br><span class="line">ylabel(<span class="string">'$y$'</span>, rotation=<span class="number">0</span>) <span class="comment"># y标签默认旋转90度</span></span><br><span class="line">rc(<span class="string">'legend'</span>, loc=<span class="string">'lower left'</span>) <span class="comment"># 图例在左下显示</span></span><br><span class="line">legend()</span><br><span class="line">savefig(<span class="string">'plot.png'</span>, dpi=<span class="number">500</span>)</span><br><span class="line">show()</span><br></pre></td></tr></table></figure><p><img src="/posts/Python使用Matplotlib作图/plot.png"></p><h1 id="饼状图pie">饼状图(pie)</h1><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><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><span class="line"><span class="keyword">from</span> matplotlib <span class="keyword">import</span> rcParams</span><br><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"><span class="keyword">from</span> matplotlib.pyplot <span class="keyword">import</span> *</span><br><span class="line">a = np.array([<span class="number">124</span>, <span class="number">45</span>, <span class="number">72</span>, <span class="number">87</span>, <span class="number">11</span>])</span><br><span class="line">pie(a, labels=[<span class="string">"A产品"</span>, <span class="string">"B产品"</span>, <span class="string">"C产品"</span>, <span class="string">"D产品"</span>, <span class="string">"E产品"</span>])</span><br><span class="line">title(<span class="string">"销售额分析"</span>)</span><br><span class="line">rcParams[<span class="string">'font.sans-serif'</span>] = [<span class="string">'SimHei'</span>]</span><br><span class="line">savefig(<span class="string">"pie.png"</span>, dpi=<span class="number">500</span>)</span><br><span class="line">show()</span><br></pre></td></tr></table></figure><p><img src="/posts/Python使用Matplotlib作图/pie.png"></p><h1 id="子窗口subplot">子窗口(subplot)</h1><p><code>subplot(nrows, ncols, index)</code></p><p>前两个参数将整个窗口分为<code>nrows*ncols</code>的区域</p><p>函数返回从上到下,从左到右的第<code>index</code>个区域(从1开始)</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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"><span class="keyword">from</span> matplotlib.pyplot <span class="keyword">import</span> *</span><br><span class="line">x = np.linspace(<span class="number">0</span>, <span class="number">2</span>*np.pi, <span class="number">200</span>)</span><br><span class="line">y1 = np.sin(x)</span><br><span class="line">y2 = np.cos(x)</span><br><span class="line">y3 = np.sin(x*x)</span><br><span class="line">rc(<span class="string">'font'</span>, size=<span class="number">16</span>)</span><br><span class="line">ax1 = subplot(<span class="number">2</span>, <span class="number">2</span>, <span class="number">1</span>) <span class="comment"># 创建左上窗口</span></span><br><span class="line">ax1.plot(x, y1, <span class="string">'r'</span>, label=<span class="string">'$sin(x)$'</span>)</span><br><span class="line">legend()</span><br><span class="line"></span><br><span class="line">ax2 = subplot(<span class="number">2</span>, <span class="number">2</span>, <span class="number">2</span>) <span class="comment"># 创建右上窗口</span></span><br><span class="line">ax2.plot(x, y2, <span class="string">'b--'</span>, label=<span class="string">'$cos(x)$'</span>)</span><br><span class="line">legend()</span><br><span class="line"></span><br><span class="line">ax3 = subplot(<span class="number">2</span>, <span class="number">1</span>, <span class="number">2</span>) <span class="comment"># 创建下方窗口</span></span><br><span class="line">ax3.plot(x, y3, <span class="string">'k--'</span>, label=<span class="string">'$sin(x^2)$'</span>)</span><br><span class="line">legend()</span><br><span class="line">savefig(<span class="string">'subplot.png'</span>, dpi=<span class="number">500</span>)</span><br><span class="line">show()</span><br></pre></td></tr></table></figure><p><img src="/posts/Python使用Matplotlib作图/subplot.png"></p><p>上方的两个窗口分别占据了2*2划分的前两个区域</p><p>下方窗口占据了2*1划分的第二个区域</p><h1 id="三维曲线plot3d">三维曲线(plot3D)</h1><p>以下代码画出<span class="math inline">\(x=t\sin t,y=t\cos t,z=t\)</span>的图形</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><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><span class="line"><span class="keyword">from</span> matplotlib.pyplot <span class="keyword">import</span> *</span><br><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line">ax = axes(projection=<span class="string">'3d'</span>) <span class="comment"># 先设置三维模式</span></span><br><span class="line">z = np.linspace(<span class="number">0</span>, <span class="number">100</span>, <span class="number">1000</span>)</span><br><span class="line">x = np.sin(z)*z</span><br><span class="line">y = np.cos(z)*z</span><br><span class="line">ax.plot3D(x, y, z, <span class="string">'k'</span>)</span><br><span class="line">savefig(<span class="string">'plot3D.png'</span>, dpi=<span class="number">500</span>)</span><br><span class="line">show()</span><br></pre></td></tr></table></figure><p><img src="/posts/Python使用Matplotlib作图/plot3D.png"></p><h1 id="三维曲面plot_surfaceplot_wireframe">三维曲面(plot_surface,plot_wireframe)</h1><p><code>plot_surface</code>生成表面图形,<code>plot_wireframe</code>生成网格图形</p><p>生成三维曲面时,需指定网格坐标(描点坐标)</p><p>以下代码画出<span class="math inline">\(z=\sin (\sqrt{x^2+y^2})\)</span>的图形</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><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><span class="line"><span class="keyword">from</span> matplotlib.pyplot <span class="keyword">import</span> *</span><br><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line">x = np.linspace(<span class="number">-6</span>, <span class="number">6</span>, <span class="number">30</span>)</span><br><span class="line">y = np.linspace(<span class="number">-6</span>, <span class="number">6</span>, <span class="number">30</span>)</span><br><span class="line">X, Y = np.meshgrid(x, y) <span class="comment"># 生成网格坐标矩阵</span></span><br><span class="line">Z = np.sin(np.sqrt(X**<span class="number">2</span>+Y**<span class="number">2</span>))</span><br><span class="line"></span><br><span class="line">ax1 = subplot(<span class="number">1</span>, <span class="number">2</span>, <span class="number">1</span>, projection=<span class="string">'3d'</span>)</span><br><span class="line">ax1.plot_surface(X, Y, Z, cmap=<span class="string">'viridis'</span>) <span class="comment"># 使用viridis的配色创建表面图形</span></span><br><span class="line">ax1.set_xlabel(<span class="string">'x'</span>)</span><br><span class="line">ax1.set_ylabel(<span class="string">'y'</span>)</span><br><span class="line">ax1.set_zlabel(<span class="string">'z'</span>)</span><br><span class="line"></span><br><span class="line">ax2 = subplot(<span class="number">1</span>, <span class="number">2</span>, <span class="number">2</span>, projection=<span class="string">'3d'</span>)</span><br><span class="line">ax2.plot_wireframe(X, Y, Z, color=<span class="string">'c'</span>)</span><br><span class="line">ax2.set_xlabel(<span class="string">'x'</span>)</span><br><span class="line">ax2.set_ylabel(<span class="string">'y'</span>)</span><br><span class="line">ax2.set_zlabel(<span class="string">'z'</span>)</span><br><span class="line"></span><br><span class="line">savefig(<span class="string">'plot_surface.png'</span>, dpi=<span class="number">500</span>)</span><br><span class="line">show()</span><br></pre></td></tr></table></figure><p><img src="/posts/Python使用Matplotlib作图/plot_surface.png"></p><h1 id="等高线图contour">等高线图(contour)</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><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> matplotlib.pyplot <span class="keyword">import</span> *</span><br><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line">z = np.loadtxt(<span class="string">"data.txt"</span>) <span class="comment"># 从文件导入高程数据</span></span><br><span class="line">x = np.arange(<span class="number">0</span>, <span class="number">1500</span>, <span class="number">100</span>)</span><br><span class="line">y = np.arange(<span class="number">1200</span>, <span class="number">-10</span>, <span class="number">-100</span>)</span><br><span class="line">contr = contour(x, y, z)</span><br><span class="line">clabel(contr) <span class="comment"># 标注高度</span></span><br><span class="line">savefig(<span class="string">'contour.png'</span>, dpi=<span class="number">500</span>)</span><br><span class="line">show()</span><br></pre></td></tr></table></figure><p><img src="/posts/Python使用Matplotlib作图/contour.png"></p><h1 id="向量图quiver">向量图(quiver)</h1><p>以下代码画出向量场<span class="math inline">\(\vec A=(y\cos x,y\sin x)\)</span></p><p><code>quiver(x, y, vx, vy)</code>分别接收两个网格坐标矩阵,以及向量场的xy分量</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><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><span class="line"><span class="keyword">from</span> matplotlib.pyplot <span class="keyword">import</span> *</span><br><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line">x = np.linspace(<span class="number">0</span>, <span class="number">15</span>, <span class="number">11</span>)</span><br><span class="line">y = np.linspace(<span class="number">0</span>, <span class="number">10</span>, <span class="number">12</span>)</span><br><span class="line">x, y = np.meshgrid(x, y)</span><br><span class="line">vx = y*np.cos(x)</span><br><span class="line">vy = y*np.sin(x)</span><br><span class="line">quiver(x, y, vx, vy)</span><br><span class="line">savefig(<span class="string">'quiver.png'</span>, dpi=<span class="number">500</span>)</span><br><span class="line">show()</span><br></pre></td></tr></table></figure><p><img src="/posts/Python使用Matplotlib作图/quiver.png"></p>]]></content>
<summary type="html">
<p><code>Matplotlib.pyplot</code>将原本面向对象的作图操作封装成函数,使之更近似于MATLAB的交互式命令</p>
<p>只要有离散的数据,就可以做出柱状、散点、饼状、折线、3D图形等可视化图表</p>
<h1 id="柱状图bar">柱状图(
</summary>
<category term="学习笔记" scheme="http://oi.linkfqy.top/categories/%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"/>
<category term="Python" scheme="http://oi.linkfqy.top/tags/Python/"/>
<category term="Matplotlib" scheme="http://oi.linkfqy.top/tags/Matplotlib/"/>
</entry>
<entry>
<title>LitePal使用指南</title>
<link href="http://oi.linkfqy.top/posts/LitePal%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97/"/>
<id>http://oi.linkfqy.top/posts/LitePal使用指南/</id>
<published>2021-05-03T09:19:42.000Z</published>
<updated>2021-05-03T09:19:47.991Z</updated>
<content type="html"><![CDATA[<h1 id="litepal使用指南">LitePal使用指南</h1><p>我们项目中只涉及轻量级的数据库操作,因此使用LitePal中封装好的接口可以大大简化操作</p><p><strong>建议全程使用LitePal进行开发</strong></p><p><a href="https://github.com/guolindev/LitePal" target="_blank" rel="noopener">github地址</a></p><h2 id="配置环境">配置环境</h2><p><strong>注意:以下有些步骤是我已经完成的,请务必先将本地工程更新至仓库中的最新版本</strong></p><p>在<code>app/build.gradle</code>中添加对LitePal的引用:</p><figure class="highlight plain"><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><span class="line">dependencies {</span><br><span class="line"> implementation 'org.litepal.guolindev:core:3.2.3'</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>注意使用最新版本3.2.3</p><p>在<code>assets</code>中创建<code>litepal.xml</code>:</p><figure class="highlight plain"><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><span class="line"><?xml version="1.0" encoding="utf-8"?></span><br><span class="line"><litepal></span><br><span class="line"> <dbname value="main" /></span><br><span class="line"> <version value="1" /></span><br><span class="line"> <list></span><br><span class="line"> <mapping class="com.hitsz.eazytime.model.Todo" /></span><br><span class="line"> </list></span><br><span class="line"></litepal></span><br></pre></td></tr></table></figure><p>其中<code>dbname</code>指定数据库名,<code>version</code>指定数据库版本(增减数据表、增减数据表字段、改变字段类型等操作都必须增加版本号)</p><p>在<code>list</code>中使用<code>mapping</code>标签关联每个数据表</p><p>在<code>AndroidManifest.xml</code>配置:</p><figure class="highlight plain"><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><span class="line"><manifest></span><br><span class="line"> <application</span><br><span class="line"> android:name="org.litepal.LitePalApplication"</span><br><span class="line"> ...</span><br><span class="line"> ></span><br><span class="line"> ...</span><br><span class="line"> </application></span><br><span class="line"></manifest></span><br></pre></td></tr></table></figure><h2 id="创建数据表">创建数据表</h2><p>LitePal将数据表和java类一一对应,因此对对象的操作就很容易转化成对数据表的操作</p><p>在<code>com.hitsz.eazytime.model</code>包下新增一个java文件用于定义类:</p><figure class="highlight plain"><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></pre></td><td class="code"><pre><span class="line">public class Todo extends LitePalSupport {</span><br><span class="line"> private String title;</span><br><span class="line"> private Date startTime;</span><br><span class="line"> private Date endTime;</span><br><span class="line"> int id;</span><br><span class="line"> </span><br><span class="line"> public Todo(){</span><br><span class="line"> //构造函数</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> public String getTitle() {</span><br><span class="line"> return title;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> public void setTitle(String title) {</span><br><span class="line"> this.title = title;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> public Date getStartTime() {</span><br><span class="line"> return startTime;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> public void setStartTime(Date startTime) {</span><br><span class="line"> this.startTime = startTime;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> public Date getEndTime() {</span><br><span class="line"> return endTime;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> public void setEndTime(Date endTime) {</span><br><span class="line"> this.endTime = endTime;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> public int getId() {</span><br><span class="line"> return id;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>LitePal支持的数据类型一共有8种:<code>int、short、long、float、double、boolean、String、Date</code></p><p><code>id</code>字段:无论类中定义与否,数据表里都会存在,且作为自增主键使用,但在类中定义<code>id</code>及<code>getId</code>可以方便查询</p><p><strong>代码规范:类中的所有成员必须以private定义,取值和修改必须经过get和set函数</strong></p><p><strong>注意:新版本LitePal的数据表类应当继承自<code>LitePalSupport</code>而非<code>DataSupport</code></strong></p><p><strong>注意:修改了类的定义后,请务必增加数据库的版本号,否则对类的更改无法应用至数据库</strong></p><h2 id="增查删改">增查删改</h2><p>这部分在《第一行代码》和<a href="https://blog.csdn.net/guolin_blog/category_2522725.html" target="_blank" rel="noopener">作者博客</a>里有较详细的介绍,这里有重点地讲一下</p><h3 id="增">增</h3><p>一般new一个新的对象出来,然后save就可以了</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Todo todo=new Todo(...);</span><br><span class="line">todo.save();</span><br></pre></td></tr></table></figure><h3 id="查">查</h3><p><strong>注意:新版的查询使用<code>LitePal</code>而非<code>DataSupport</code></strong></p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">List<Todo> todos = LitePal.select(...).where(...).order(...).limit(...).offset(...).find(Todo.class)</span><br></pre></td></tr></table></figure><p>以上连缀无固定顺序,也可不写其中的某些连缀</p><p>注:LitePal本身支持关联表的激进查询,但不推荐使用,合理的写法是在类中实现一个返回关联字段的函数,详细请看作者博客</p><h3 id="删">删</h3><p>没什么要说的,见作者博客</p><h3 id="改">改</h3><p>没什么要说的,见作者博客</p>]]></content>
<summary type="html">
<h1 id="litepal使用指南">LitePal使用指南</h1>
<p>我们项目中只涉及轻量级的数据库操作,因此使用LitePal中封装好的接口可以大大简化操作</p>
<p><strong>建议全程使用LitePal进行开发</strong></p>
<p><a
</summary>
<category term="Android" scheme="http://oi.linkfqy.top/categories/Android/"/>
<category term="数据库" scheme="http://oi.linkfqy.top/tags/%E6%95%B0%E6%8D%AE%E5%BA%93/"/>
</entry>
<entry>
<title>简易版git教程</title>
<link href="http://oi.linkfqy.top/posts/%E7%AE%80%E6%98%93%E7%89%88Git%E6%95%99%E7%A8%8B/"/>
<id>http://oi.linkfqy.top/posts/简易版Git教程/</id>
<published>2021-03-30T14:07:25.000Z</published>
<updated>2021-03-30T14:25:24.253Z</updated>
<content type="html"><![CDATA[<h1 id="简易版git教程">简易版git教程</h1><p>这是写给大一立项小组成员看的简易版git教程</p><p>我们做这个项目只需要一些基本的git命令就可以了,因此这里教大家10min速成git</p><h2 id="准备工作">准备工作</h2><ul><li>GitHub和git的关系</li></ul><p>git是版本管理工具,适合多人合作,储存代码的地方叫做仓库,仓库可以在本地,也可以在学校的服务器上,GitHub是个托管仓库的网站,大家经常把代码放在GitHub上</p><p>在<a href="https://git-scm.com/downloads" target="_blank" rel="noopener">这里</a>下载并安装git,看不懂就一直点next就行</p><p>git是一个命令行工具,要使用它只能敲对应的命令</p><p>下面介绍的命令均在对应目录下的命令行中执行</p><ul><li>如何在当前目录下打开命令行?<ul><li>如图在任务管理器路径前敲CMD即可</li></ul></li></ul><p><img src="/posts/简易版Git教程/1.png"></p><h2 id="git-clone">git clone</h2><p>clone是将网络上的仓库克隆到本地的操作</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git clone "https://github.com/linkfqy/EazyTime.git"</span><br></pre></td></tr></table></figure><p>上面的命令将我们项目的工程文件clone至当前目录</p><p>当前目录会生成一个EazyTime文件夹即工程文件夹,打开它并重新打开命令行,<strong>后续命令均在此文件夹中进行</strong></p><p>clone到本地后,你就可以对工程文件进行编辑了,可以任意增加想要的功能</p><h2 id="git-add">git add</h2><p>一般来说,我们只希望自己工作的那部分文件能够更新到仓库,而无关紧要的修改不应影响他人</p><p>因此需要对工作文件进行add</p><p>add命令将指定的文件或目录添加至<strong>本地</strong>的暂存区,只有add过的文件才能被提交,add过的文件还可以修改,也可以再次add,最终提交的文件以最后一次add的版本为准</p><p>如:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git add "README.md"</span><br></pre></td></tr></table></figure><p>以上命令将<code>README.md</code>文件添加至<strong>本地</strong>的暂存区</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git add "app\src\main\java"</span><br></pre></td></tr></table></figure><p>以上命令将<code>app\src\main\java</code>整个文件夹添加至<strong>本地</strong>的暂存区</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git add *</span><br></pre></td></tr></table></figure><p>以上命令将<strong>所有文件</strong>添加至本地的暂存区</p><p><strong>注意:不要随意使用以上命令!因为这会将你对工程做的所有修改(而非仅属于你的那部分工作)都添加!一旦push,会对所有人共用的仓库产生影响!</strong></p><p>合适的做法是,仅add自己工作所属的目录,如:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git add "app\src\main\java\com\hitsz\eazytime\ui\todo"</span><br></pre></td></tr></table></figure><h2 id="git-status">git status</h2><p><code>git status</code>命令用于显示工作目录和暂存区的状态。</p><p>使用此命令能看到哪些<strong>修改</strong>被暂存到了, 哪些没有,哪些<strong>文件</strong>还没被add。<code>git status</code>不显示已经<code>commit</code>到项目历史中去的信息。</p><p>“<em>Changes to be committed</em>”所列的是已add过的文件版本 “<em>Changed but not updated</em>”所列的是add过但被修改,尚未再次add的文件 “<em>Untracked files</em>”中所列的是尚未add的文件</p><figure class="highlight plain"><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><span class="line">Changes to be committed:</span><br><span class="line"> (use "git restore --staged <file>..." to unstage)</span><br><span class="line"> modified: README.md</span><br><span class="line"></span><br><span class="line">Changes not staged for commit:</span><br><span class="line"> (use "git add <file>..." to update what will be committed)</span><br><span class="line"> (use "git restore <file>..." to discard changes in working directory)</span><br><span class="line"> modified: README.md</span><br></pre></td></tr></table></figure><p>以上表示<code>README.md</code>被add过一个版本,但之后又修改过,可以再次add以添加新的版本</p><p>同时也提示你:</p><ul><li>想要舍弃已add的版本,使用<code>git restore --staged "README.md"</code>命令</li><li>想要还原对<code>README.md</code>的修改,使用<code>git restore "README.md"</code>将文件变为最后一次add的版本</li></ul><h2 id="git-commit">git commit</h2><p><code>commit</code>命令将暂存区的内容添加到<strong>本地</strong>仓库中</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git commit -m "message"</span><br></pre></td></tr></table></figure><p>上面的message是对此次提交的注释,可以写点关于这次提交干了啥的解释</p><h2 id="git-push">git push</h2><p>终于到了最后一步,将本地所作的修改提交至GitHub上的仓库</p><p><strong>注意:之前的操作都是本地的,不push大家是看不到你的工作的</strong></p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git push</span><br></pre></td></tr></table></figure><p>一句话将本地仓库提交至GitHub</p><p>如果想要提交对应分支,则:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git push origin main</span><br></pre></td></tr></table></figure><p>将本地的main分支提交至GitHub</p><p>第一次push可能会弹出登录窗口,登录github账号就可以正常提交了</p>]]></content>
<summary type="html">
<h1 id="简易版git教程">简易版git教程</h1>
<p>这是写给大一立项小组成员看的简易版git教程</p>
<p>我们做这个项目只需要一些基本的git命令就可以了,因此这里教大家10min速成git</p>
<h2 id="准备工作">准备工作</h2>
</summary>
<category term="杂" scheme="http://oi.linkfqy.top/categories/%E6%9D%82/"/>
<category term="git" scheme="http://oi.linkfqy.top/tags/git/"/>
</entry>
<entry>
<title>EazyTime开发笔记</title>
<link href="http://oi.linkfqy.top/posts/EazyTime/"/>
<id>http://oi.linkfqy.top/posts/EazyTime/</id>
<published>2021-03-29T15:12:08.000Z</published>
<updated>2021-03-30T14:15:00.600Z</updated>
<content type="html"><![CDATA[]]></content>
<summary type="html">
</summary>
<category term="学习笔记" scheme="http://oi.linkfqy.top/categories/%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"/>
</entry>
<entry>
<title>Python学习笔记</title>
<link href="http://oi.linkfqy.top/posts/Python%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"/>
<id>http://oi.linkfqy.top/posts/Python学习笔记/</id>
<published>2021-03-25T15:35:00.000Z</published>
<updated>2021-03-27T02:33:17.483Z</updated>
<content type="html"><![CDATA[<h2 id="section">3.25</h2><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><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><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">ListNode</span>:</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">__init__</span><span class="params">(self, val=<span class="number">0</span>, next=None)</span>:</span></span><br><span class="line"> self.val = val</span><br><span class="line"> self.next = next</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">set</span><span class="params">(self, L)</span>:</span></span><br><span class="line"> self=ListNode(val=L[<span class="number">0</span>])</span><br><span class="line"> now = self</span><br><span class="line"> <span class="keyword">for</span> x <span class="keyword">in</span> L[<span class="number">1</span>:]:</span><br><span class="line"> now.next = ListNode(val=x)</span><br><span class="line"> now = now.next</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">print</span><span class="params">(self)</span>:</span></span><br><span class="line"> now = self</span><br><span class="line"> <span class="keyword">while</span> (now != <span class="keyword">None</span>):</span><br><span class="line"> print(<span class="string">'%d '</span> % (now.val))</span><br><span class="line"> now = now.next</span><br><span class="line"> print(<span class="string">'\n'</span>)</span><br><span class="line"> </span><br><span class="line">a=ListNode()</span><br><span class="line">a.set([<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>])</span><br><span class="line">a.print() <span class="comment"># 输出0</span></span><br></pre></td></tr></table></figure><p>可见,<code>a.set()</code>并没有改变a的值,不得其解</p><p>看了这篇<a href="https://www.cnblogs.com/pythonista/p/11178705.html" target="_blank" rel="noopener">文章</a></p><p>豁然开朗,之前理解有误的原因是自动把C++的赋值与Python混淆了</p><p>Python的变量,其实是C++意义上的指针</p><p>下面摘录几段:</p><hr><h3 id="构造函数返回指针">构造函数返回指针</h3><p><strong>Python 的构造函数将构造匿名对象,且返回此对象的一个指针。</strong></p><p>这是 Python 与指针的第一个重要联系。</p><p>用代码描述,对于Python代码:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sampleNum = <span class="number">0</span></span><br></pre></td></tr></table></figure><p>其不类似于 C++ 代码:</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">int</span> sampleNum = <span class="number">0</span>;</span><br></pre></td></tr></table></figure><p>而更类似于:</p><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">int</span> __tmpNum = <span class="number">0</span>, *sampleNum = &__tmpNum;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 或者:</span></span><br><span class="line"><span class="built_in">shared_ptr</span><<span class="keyword">int</span>> sampleNum(<span class="keyword">new</span> <span class="keyword">int</span>(<span class="number">0</span>));</span><br></pre></td></tr></table></figure><h3 id="setitems__操作将隐式解指针">__setitems__操作将隐式解指针</h3><p>Python 与指针的另一个重要联系在于 Python 的<strong>隐式解指针行为。</strong></p><p>虽然 Python 不存在显式解指针操作,但(有且仅有)__setitems__操作将进行隐式解指针,通过此方法对变量进行修改等同于通过解指针操作修改变量原值。</p><p>此种性质意味着:</p><ol type="1"><li>任何不涉及__setitems__的操作都将成为指针重绑定。</li></ol><p>对于Python代码:</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><span class="line">numList = [<span class="keyword">None</span>] * <span class="number">10</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Rebinding</span></span><br><span class="line">numList = [<span class="keyword">None</span>] * <span class="number">5</span></span><br></pre></td></tr></table></figure><p>其相当于:</p><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">int</span> *numList = <span class="keyword">new</span> <span class="keyword">int</span>[<span class="number">10</span>];</span><br><span class="line"></span><br><span class="line"><span class="comment">// Rebinding</span></span><br><span class="line"><span class="keyword">delete</span>[] numList;</span><br><span class="line">numList = <span class="keyword">new</span> <span class="keyword">int</span>[<span class="number">5</span>];</span><br><span class="line"><span class="keyword">delete</span>[] numList;</span><br></pre></td></tr></table></figure><p>由此可见,对 numList 的非__setitems__操作,导致 numList 被绑定到了一个新指针上。</p><ol start="2" type="1"><li>任何涉及__setitems__的操作都将成为解指针操作。</li></ol><p>由于 Python 对哈希表的高度依赖,“涉及__setitems__的操作”在 Python 中实际上是一个非常广泛的行为,这主要包括:</p><ul><li>对数组的索引操作</li><li>对哈希表的查找操作</li><li>涉及__setattr__的操作(由于 Python 将 attribute 存储在哈希表中,所以__setattr__操作最终将是某种__setitems__操作)</li></ul><hr><p>于是,将<code>set()</code>改为这样:</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><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">set</span><span class="params">(self, L)</span>:</span></span><br><span class="line"> self.val = L[<span class="number">0</span>] <span class="comment"># self=ListNode(val=L[0])</span></span><br><span class="line"> self.next = <span class="keyword">None</span></span><br><span class="line"> now = self</span><br><span class="line"> <span class="keyword">for</span> x <span class="keyword">in</span> L[<span class="number">1</span>:]:</span><br><span class="line"> now.next = ListNode(val=x)</span><br><span class="line"> now = now.next</span><br></pre></td></tr></table></figure><p>就解决了问题</p><p><strong><code>self</code>是默认将实例本身传入的参数</strong>,根据上文,实际传入的是实例的指针,而<strong><code>self=ListNode(val=L[0])</code>将<code>self</code>重新绑定至一个新建的节点</strong>,那么后续进行的操作就与原实例无关了</p>]]></content>
<summary type="html">
<h2 id="section">3.25</h2>
<p>今天遇到了这样一个问题:</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</s
</summary>
<category term="学习笔记" scheme="http://oi.linkfqy.top/categories/%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"/>
<category term="Python" scheme="http://oi.linkfqy.top/tags/Python/"/>
</entry>
<entry>
<title>【最大权闭合子图】LOJ6045 「雅礼集训 2017 Day8」价</title>
<link href="http://oi.linkfqy.top/posts/LOJ6045/"/>
<id>http://oi.linkfqy.top/posts/LOJ6045/</id>
<published>2018-11-25T11:48:02.000Z</published>
<updated>2018-11-25T12:09:24.000Z</updated>
<content type="html"><![CDATA[<p><a href="https://loj.ac/problem/6045" target="_blank" rel="noopener">题面在这里</a></p><p></p><p>很明显是最大权闭合子图的模型</p><p></p><p>示例程序:</p><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><span class="line">54</span><br><span class="line">55</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><cstdio></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><cstring></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><algorithm></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> cl(x,y) memset(x,y,sizeof(x))</span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"><span class="keyword">typedef</span> <span class="keyword">long</span> <span class="keyword">long</span> ll;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> maxn=<span class="number">605</span>,maxe=<span class="number">200005</span>,inf=<span class="number">0x3f3f3f3f</span>,INF=<span class="number">0x7fffffff</span>;</span><br><span class="line"><span class="keyword">int</span> n,S,T;</span><br><span class="line"><span class="keyword">int</span> tot,son[maxe],nxt[maxe],lnk[maxn];ll flw[maxe],cap[maxe];</span><br><span class="line"><span class="function"><span class="keyword">inline</span> <span class="keyword">void</span> <span class="title">add</span><span class="params">(<span class="keyword">int</span> x,<span class="keyword">int</span> y,<span class="keyword">int</span> f)</span></span>{</span><br><span class="line">son[++tot]=y;nxt[tot]=lnk[x];lnk[x]=tot;flw[tot]=<span class="number">0</span>;cap[tot]=f;</span><br><span class="line">son[++tot]=x;nxt[tot]=lnk[y];lnk[y]=tot;flw[tot]=<span class="number">0</span>;cap[tot]=<span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"><span class="keyword">int</span> que[maxn],d[maxn],pos[maxn];</span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">bfs</span><span class="params">()</span></span>{</span><br><span class="line">cl(d,<span class="number">63</span>);</span><br><span class="line"><span class="keyword">int</span> hed=<span class="number">0</span>,til=<span class="number">1</span>;</span><br><span class="line">que[<span class="number">1</span>]=S;d[S]=<span class="number">0</span>;</span><br><span class="line"><span class="keyword">while</span> (hed!=til){</span><br><span class="line"><span class="keyword">int</span> x=que[++hed];</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> j=lnk[x];j;j=nxt[j])</span><br><span class="line"> <span class="keyword">if</span> (d[son[j]]==inf&&flw[j]<cap[j])</span><br><span class="line"> d[que[++til]=son[j]]=d[x]+<span class="number">1</span>;</span><br><span class="line">}</span><br><span class="line"><span class="keyword">return</span> d[T]!=inf;</span><br><span class="line">}</span><br><span class="line"><span class="function">ll <span class="title">dfs</span><span class="params">(<span class="keyword">int</span> x,ll flow)</span></span>{</span><br><span class="line"><span class="keyword">if</span> (x==T||flow==<span class="number">0</span>) <span class="keyword">return</span> flow;</span><br><span class="line">ll f=<span class="number">0</span>,res=<span class="number">0</span>;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> &j=pos[x];j;j=nxt[j])</span><br><span class="line"> <span class="keyword">if</span> (d[son[j]]==d[x]+<span class="number">1</span>&&(f=dfs(son[j],min(flow,cap[j]-flw[j])))><span class="number">0</span>){</span><br><span class="line"> flw[j]+=f;flw[j^<span class="number">1</span>]-=f;</span><br><span class="line"> res+=f,flow-=f;</span><br><span class="line"> <span class="keyword">if</span> (flow==<span class="number">0</span>) <span class="keyword">return</span> res;</span><br><span class="line"> }</span><br><span class="line"><span class="keyword">return</span> res;</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span>{</span><br><span class="line"><span class="built_in">scanf</span>(<span class="string">"%d"</span>,&n);</span><br><span class="line">S=<span class="number">2</span>*n+<span class="number">1</span>,T=S+<span class="number">1</span>;tot=<span class="number">1</span>;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">1</span>;i<=n;i++){</span><br><span class="line"><span class="keyword">int</span> t;<span class="built_in">scanf</span>(<span class="string">"%d"</span>,&t);</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> j=<span class="number">1</span>,x;j<=t;j++) <span class="built_in">scanf</span>(<span class="string">"%d"</span>,&x),add(i,x+n,INF);</span><br><span class="line">add(i+n,T,inf);</span><br><span class="line">}</span><br><span class="line">ll ans=<span class="number">0</span>;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">1</span>,pi;i<=n;i++) <span class="built_in">scanf</span>(<span class="string">"%d"</span>,&pi),add(S,i,-pi+inf),ans-=inf-pi;</span><br><span class="line"><span class="keyword">while</span> (bfs()){</span><br><span class="line"><span class="built_in">memcpy</span>(pos,lnk,<span class="keyword">sizeof</span>(lnk));</span><br><span class="line">ans+=dfs(S,INF);</span><br><span class="line">}</span><br><span class="line"><span class="built_in">printf</span>(<span class="string">"%lld"</span>,ans);</span><br><span class="line"><span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<p><a href="https://loj.ac/problem/6045" target="_blank" rel="noopener">题面在这里</a></p>
<p></p>
<p>很明显是最大权闭合子图的模型</p>
<p></p>
<p>示例程序:</
</summary>
<category term="题解" scheme="http://oi.linkfqy.top/categories/%E9%A2%98%E8%A7%A3/"/>
<category term="二分图" scheme="http://oi.linkfqy.top/tags/%E4%BA%8C%E5%88%86%E5%9B%BE/"/>
<category term="最大权闭合子图" scheme="http://oi.linkfqy.top/tags/%E6%9C%80%E5%A4%A7%E6%9D%83%E9%97%AD%E5%90%88%E5%AD%90%E5%9B%BE/"/>
<category term="LOJ" scheme="http://oi.linkfqy.top/tags/LOJ/"/>
</entry>
<entry>
<title>【莫队+bitset】BZOJ4810 [Ynoi2017]由乃的玉米田</title>
<link href="http://oi.linkfqy.top/posts/BZOJ4810/"/>
<id>http://oi.linkfqy.top/posts/BZOJ4810/</id>
<published>2018-11-22T22:52:00.000Z</published>
<updated>2018-11-22T23:03:06.000Z</updated>
<content type="html"><![CDATA[<p><a href="https://www.lydsy.com/JudgeOnline/problem.php?id=4810" target="_blank" rel="noopener">题面在这里</a></p><p></p><p>直接莫队……用bitset维护出现过哪些值 <span class="math display">\[a-b=x\Leftrightarrow a=b+x \\a+b=x\Leftrightarrow a=-(b-x)\]</span></p><p>对于操作1,bitset左移x位后对自己取并</p><p>对于操作2,需要同时维护一个所有值的相反数的bitset,同1</p><p>对于操作3,直接爆枚因子即可</p><p>时间复杂度<span class="math inline">\(O(n\sqrt n)\)</span></p><p></p><p>示例程序:</p><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><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></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><cstdio></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><bitset></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><cmath></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><algorithm></span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"><span class="function"><span class="keyword">inline</span> <span class="keyword">char</span> <span class="title">nc</span><span class="params">()</span></span>{</span><br><span class="line"><span class="keyword">static</span> <span class="keyword">char</span> buf[<span class="number">100000</span>],*l=buf,*r=buf;</span><br><span class="line"><span class="keyword">return</span> l==r&&(r=(l=buf)+fread(buf,<span class="number">1</span>,<span class="number">100000</span>,<span class="built_in">stdin</span>),l==r)?EOF:*l++;</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">inline</span> <span class="keyword">int</span> <span class="title">red</span><span class="params">()</span></span>{</span><br><span class="line"><span class="keyword">int</span> res=<span class="number">0</span>,f=<span class="number">1</span>;<span class="keyword">char</span> ch=nc();</span><br><span class="line"><span class="keyword">while</span> (ch<<span class="string">'0'</span>||<span class="string">'9'</span><ch) {<span class="keyword">if</span> (ch==<span class="string">'-'</span>) f=-f;ch=nc();}</span><br><span class="line"><span class="keyword">while</span> (<span class="string">'0'</span><=ch&&ch<=<span class="string">'9'</span>) res=res*<span class="number">10</span>+ch<span class="number">-48</span>,ch=nc();</span><br><span class="line"><span class="keyword">return</span> res*f;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> maxn=<span class="number">100005</span>;</span><br><span class="line"><span class="keyword">int</span> n,q,a[maxn],h[maxn];</span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">Query</span>{</span></span><br><span class="line"><span class="keyword">int</span> t,l,r,x,id;</span><br><span class="line"><span class="keyword">bool</span> <span class="keyword">operator</span><(<span class="keyword">const</span> Query&b)<span class="keyword">const</span>{</span><br><span class="line"><span class="keyword">if</span> (h[l]==h[b.l]) <span class="keyword">return</span> r<b.r;</span><br><span class="line"><span class="keyword">return</span> l<b.l;</span><br><span class="line">}</span><br><span class="line">}Q[maxn];</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">blocker</span><span class="params">()</span></span>{</span><br><span class="line"><span class="keyword">int</span> k=<span class="built_in">sqrt</span>(n);</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">1</span>;i<=n;i++) h[i]=i/k;</span><br><span class="line">}</span><br><span class="line"><span class="built_in">bitset</span><maxn*2> A,B;</span><br><span class="line"><span class="keyword">int</span> cnt[maxn*<span class="number">2</span>];</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">add</span><span class="params">(<span class="keyword">int</span> x)</span></span>{</span><br><span class="line"><span class="keyword">if</span> (!cnt[x]) A[x+<span class="number">100000</span>]=<span class="number">1</span>;</span><br><span class="line"><span class="keyword">if</span> (!cnt[x]) B[<span class="number">100000</span>-x]=<span class="number">1</span>;</span><br><span class="line">cnt[x]++;</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">dec</span><span class="params">(<span class="keyword">int</span> x)</span></span>{</span><br><span class="line">cnt[x]--;</span><br><span class="line"><span class="keyword">if</span> (!cnt[x]) A[x+<span class="number">100000</span>]=<span class="number">0</span>;</span><br><span class="line"><span class="keyword">if</span> (!cnt[x]) B[<span class="number">100000</span>-x]=<span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"><span class="keyword">bool</span> ans[maxn];</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span>{</span><br><span class="line">n=red(),q=red();</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">1</span>;i<=n;i++) a[i]=red();</span><br><span class="line">blocker();</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">1</span>;i<=q;i++) Q[i].t=red(),Q[i].l=red(),Q[i].r=red(),Q[i].x=red(),Q[i].id=i;</span><br><span class="line">sort(Q+<span class="number">1</span>,Q+<span class="number">1</span>+q);</span><br><span class="line"><span class="keyword">int</span> L=<span class="number">1</span>,R=<span class="number">1</span>; add(a[<span class="number">1</span>]);</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">1</span>;i<=q;i++){</span><br><span class="line"><span class="keyword">while</span> (Q[i].l<L) add(a[--L]);</span><br><span class="line"><span class="keyword">while</span> (R<Q[i].r) add(a[++R]);</span><br><span class="line"><span class="keyword">while</span> (L<Q[i].l) dec(a[L++]);</span><br><span class="line"><span class="keyword">while</span> (Q[i].r<R) dec(a[R--]);</span><br><span class="line"><span class="keyword">if</span> (Q[i].t==<span class="number">1</span>){</span><br><span class="line">ans[Q[i].id]=(A&(A<<Q[i].x)).any();</span><br><span class="line">}<span class="keyword">else</span></span><br><span class="line"><span class="keyword">if</span> (Q[i].t==<span class="number">2</span>){</span><br><span class="line">ans[Q[i].id]=(A&(B<<Q[i].x)).any();</span><br><span class="line">}<span class="keyword">else</span>{</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> d=<span class="number">1</span>,td=<span class="built_in">sqrt</span>(Q[i].x);d<=td;d++)</span><br><span class="line"> <span class="keyword">if</span> (Q[i].x%d==<span class="number">0</span>&&cnt[Q[i].x/d]&&cnt[d]) {ans[Q[i].id]=<span class="number">1</span>;<span class="keyword">break</span>;}</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">1</span>;i<=q;i++) <span class="built_in">puts</span>(ans[i]?<span class="string">"yuno"</span>:<span class="string">"yumi"</span>);</span><br><span class="line"><span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<p><a href="https://www.lydsy.com/JudgeOnline/problem.php?id=4810" target="_blank" rel="noopener">题面在这里</a></p>
<p></p>
<p>直接莫队……用bitset维
</summary>
<category term="题解" scheme="http://oi.linkfqy.top/categories/%E9%A2%98%E8%A7%A3/"/>
<category term="BZOJ" scheme="http://oi.linkfqy.top/tags/BZOJ/"/>
<category term="莫队" scheme="http://oi.linkfqy.top/tags/%E8%8E%AB%E9%98%9F/"/>
</entry>
<entry>
<title>【二分图博弈】LOJ6033 「雅礼集训 2017 Day2」棋盘游戏</title>
<link href="http://oi.linkfqy.top/posts/LOJ6033/"/>
<id>http://oi.linkfqy.top/posts/LOJ6033/</id>
<published>2018-11-22T09:37:58.000Z</published>
<updated>2018-11-22T10:01:44.000Z</updated>
<content type="html"><![CDATA[<p><a href="https://loj.ac/problem/6033" target="_blank" rel="noopener">题面在这里</a></p><p></p><p>显然可以把整个图黑白染色,得到一个二分图</p><p>考虑二分图最大匹配,如果初始点是未匹配点,则Bob只能走未匹配边到一个匹配点,而Alice一定可以沿匹配边走回左边的匹配点,由于不能往回走,此时的情形与初始状态一样,最终Bob输</p><p>如果初始点是匹配点,此时Bob走的是匹配边,Alice走未匹配边,如果最后能走回左边则Alice赢,否则Bob赢。其实他们走的是增广路,Alice能赢当且仅当初始点不一定是匹配点</p><p>所以答案是所有【不一定是匹配点】的点</p><p>具体做法是从左边未匹配点出发,沿增广路遍历到的所有左边点都是答案</p><p></p><p>示例程序:</p><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><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></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><cstdio></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><cstring></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> cl(x,y) memset(x,y,sizeof(x))</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> maxn=<span class="number">10005</span>,maxe=<span class="number">40005</span>,p[<span class="number">4</span>][<span class="number">2</span>]={{<span class="number">0</span>,<span class="number">1</span>},{<span class="number">1</span>,<span class="number">0</span>},{<span class="number">0</span>,<span class="number">-1</span>},{<span class="number">-1</span>,<span class="number">0</span>}};</span><br><span class="line"><span class="keyword">int</span> n,m,N,id[<span class="number">105</span>][<span class="number">105</span>];</span><br><span class="line"><span class="keyword">char</span> a[<span class="number">105</span>][<span class="number">105</span>];</span><br><span class="line"><span class="keyword">int</span> tot,son[maxe],lnk[maxn],nxt[maxe];</span><br><span class="line"><span class="function"><span class="keyword">inline</span> <span class="keyword">void</span> <span class="title">add</span><span class="params">(<span class="keyword">int</span> x,<span class="keyword">int</span> y)</span></span>{</span><br><span class="line">son[++tot]=y;nxt[tot]=lnk[x];lnk[x]=tot;</span><br><span class="line">}</span><br><span class="line"><span class="keyword">int</span> vis[maxn],times,con[maxn];</span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">fnd</span><span class="params">(<span class="keyword">int</span> x)</span></span>{</span><br><span class="line"><span class="keyword">if</span> (vis[x]==times) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">vis[x]=times;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> j=lnk[x];j;j=nxt[j]){</span><br><span class="line"><span class="keyword">int</span> k=con[son[j]];con[son[j]]=x;</span><br><span class="line"><span class="keyword">if</span> (!k||fnd(k)) <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">con[son[j]]=k;</span><br><span class="line">}</span><br><span class="line"><span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"><span class="keyword">bool</span> ans[maxn][maxn];</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">dfs</span><span class="params">(<span class="keyword">int</span> x)</span></span>{</span><br><span class="line">vis[x]=<span class="number">1</span>;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> j=lnk[x];j;j=nxt[j])</span><br><span class="line"> <span class="keyword">if</span> (!vis[con[son[j]]]) dfs(con[son[j]]);</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span>{</span><br><span class="line"><span class="built_in">scanf</span>(<span class="string">"%d%d"</span>,&n,&m);</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">1</span>;i<=n;i++) <span class="built_in">scanf</span>(<span class="string">"%s"</span>,a[i]+<span class="number">1</span>);</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">1</span>;i<=n;i++)</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> j=<span class="number">1</span>;j<=m;j++)</span><br><span class="line"> <span class="keyword">if</span> (a[i][j]==<span class="string">'.'</span>) id[i][j]=++N;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">1</span>;i<=n;i++)</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> j=<span class="number">1</span>;j<=m;j++) <span class="keyword">if</span> (a[i][j]==<span class="string">'.'</span>)</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> t=<span class="number">0</span>;t<<span class="number">4</span>;t++){</span><br><span class="line"> <span class="keyword">int</span> ii=i+p[t][<span class="number">0</span>],jj=j+p[t][<span class="number">1</span>];</span><br><span class="line"> <span class="keyword">if</span> (ii<<span class="number">1</span>||jj<<span class="number">1</span>||ii>n||jj>m||a[ii][jj]==<span class="string">'#'</span>) <span class="keyword">continue</span>;</span><br><span class="line"> add(id[i][j],id[ii][jj]);</span><br><span class="line"> }</span><br><span class="line"><span class="keyword">int</span> num=<span class="number">0</span>;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">1</span>;i<=n;i++)</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> j=<span class="number">1</span>;j<=m;j++)</span><br><span class="line"> <span class="keyword">if</span> (a[i][j]==<span class="string">'.'</span>&&((i+j)&<span class="number">1</span>)) times++,num+=fnd(id[i][j]);</span><br><span class="line"><span class="keyword">if</span> (num*<span class="number">2</span>==N) <span class="keyword">return</span> <span class="built_in">puts</span>(<span class="string">"0"</span>),<span class="number">0</span>;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">1</span>;i<=N;i++) con[con[i]]=i;</span><br><span class="line"></span><br><span class="line">cl(vis,<span class="number">0</span>);</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">1</span>;i<=n;i++)</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> j=<span class="number">1</span>;j<=m;j++)</span><br><span class="line"> <span class="keyword">if</span> (a[i][j]==<span class="string">'.'</span>&&!vis[id[i][j]])</span><br><span class="line"> <span class="keyword">if</span> (!con[id[i][j]]) dfs(id[i][j]);</span><br><span class="line"><span class="keyword">int</span> ANS=<span class="number">0</span>;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">1</span>;i<=n;i++)</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> j=<span class="number">1</span>;j<=m;j++)</span><br><span class="line"> <span class="keyword">if</span> (vis[id[i][j]]) ANS++,ans[i][j]=<span class="number">1</span>;</span><br><span class="line"></span><br><span class="line"><span class="built_in">printf</span>(<span class="string">"%d\n"</span>,ANS);</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">1</span>;i<=n;i++)</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> j=<span class="number">1</span>;j<=m;j++)</span><br><span class="line"> <span class="keyword">if</span> (ans[i][j]) <span class="built_in">printf</span>(<span class="string">"%d %d\n"</span>,i,j);</span><br><span class="line"><span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<p><a href="https://loj.ac/problem/6033" target="_blank" rel="noopener">题面在这里</a></p>
<p></p>
<p>显然可以把整个图黑白染色,得到一个二分图</p>
<p>考虑二分图最大匹配,如
</summary>
<category term="题解" scheme="http://oi.linkfqy.top/categories/%E9%A2%98%E8%A7%A3/"/>
<category term="二分图" scheme="http://oi.linkfqy.top/tags/%E4%BA%8C%E5%88%86%E5%9B%BE/"/>
<category term="博弈论" scheme="http://oi.linkfqy.top/tags/%E5%8D%9A%E5%BC%88%E8%AE%BA/"/>
<category term="LOJ" scheme="http://oi.linkfqy.top/tags/LOJ/"/>
</entry>
<entry>
<title>LOJ6030 「雅礼集训 2017 Day1」矩阵</title>
<link href="http://oi.linkfqy.top/posts/LOJ6030/"/>
<id>http://oi.linkfqy.top/posts/LOJ6030/</id>
<published>2018-11-16T12:47:02.000Z</published>
<updated>2018-11-16T12:48:42.000Z</updated>
<content type="html"><![CDATA[<p><a href="https://loj.ac/problem/6030" target="_blank" rel="noopener">题面在这里</a></p><p></p><p>直接乱搞即可</p><p></p><p>示例程序:</p><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></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><cstdio></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><algorithm></span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> maxn=<span class="number">1005</span>;</span><br><span class="line"><span class="keyword">int</span> n,x[maxn],y[maxn];</span><br><span class="line"><span class="keyword">char</span> s[maxn];</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span>{</span><br><span class="line"><span class="built_in">scanf</span>(<span class="string">"%d"</span>,&n);</span><br><span class="line"><span class="keyword">bool</span> suc=<span class="number">0</span>;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">1</span>;i<=n;i++){</span><br><span class="line"><span class="built_in">scanf</span>(<span class="string">"%s"</span>,s+<span class="number">1</span>);</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> j=<span class="number">1</span>;j<=n;j++)</span><br><span class="line"> <span class="keyword">if</span> (s[j]==<span class="string">'#'</span>) suc=<span class="number">1</span>,x[i]++,y[j]++;</span><br><span class="line">}</span><br><span class="line"><span class="keyword">if</span> (!suc) <span class="keyword">return</span> <span class="built_in">puts</span>(<span class="string">"-1"</span>),<span class="number">0</span>;</span><br><span class="line"><span class="keyword">int</span> ans=n*n;</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">1</span>;i<=n;i++) ans=min(ans,n-x[i]+!y[i]);</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">1</span>;i<=n;i++)</span><br><span class="line"> <span class="keyword">if</span> (y[i]!=n) ans++;</span><br><span class="line"><span class="built_in">printf</span>(<span class="string">"%d"</span>,ans);</span><br><span class="line"><span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<p><a href="https://loj.ac/problem/6030" target="_blank" rel="noopener">题面在这里</a></p>
<p></p>
<p>直接乱搞即可</p>
<p></p>
<p>示例程序:</p>
<fig
</summary>
<category term="题解" scheme="http://oi.linkfqy.top/categories/%E9%A2%98%E8%A7%A3/"/>
<category term="贪心" scheme="http://oi.linkfqy.top/tags/%E8%B4%AA%E5%BF%83/"/>
<category term="LOJ" scheme="http://oi.linkfqy.top/tags/LOJ/"/>
</entry>
<entry>
<title>【线段树+势能分析】LOJ6029 「雅礼集训 2017 Day1」市场</title>
<link href="http://oi.linkfqy.top/posts/LOJ6029/"/>
<id>http://oi.linkfqy.top/posts/LOJ6029/</id>
<published>2018-11-16T09:52:29.000Z</published>
<updated>2018-11-16T10:09:08.000Z</updated>
<content type="html"><![CDATA[<p><a href="https://loj.ac/problem/6029" target="_blank" rel="noopener">题面在这里</a></p><p></p><p>考虑一个区间除后变化量如果都相同,就转化为区间减了</p><p>维护最大值和最小值即可判断</p><p>复杂度证明:</p><p>考虑两个数<span class="math inline">\(a,b\)</span>,差是<span class="math inline">\(a-b\)</span>,除以<span class="math inline">\(d\)</span>后差是<span class="math inline">\(\frac{a-b}d\)</span></p><p>也就是说两个数被除<span class="math inline">\(\log\)</span>次就相等了</p><p>令一个线段树节点的势能为<span class="math inline">\(\log(Max-Min)\)</span></p><p>操作2就相当于把区间内所有势能不为1的节点势能-1,代价为势能减小总量</p><p>操作1会将<span class="math inline">\(\log\)</span>个节点的势能恢复为<span class="math inline">\(\log(Max-Min)\)</span></p><p>总时间复杂度为整个过程中产生的势能总量<span class="math inline">\(O((n+q\log n)\log a_i)\)</span></p><p></p><p>示例程序:</p><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><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></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><cstdio></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><cmath></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><algorithm></span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"><span class="keyword">typedef</span> <span class="keyword">long</span> <span class="keyword">long</span> ll;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> maxn=<span class="number">100005</span>,maxs=<span class="number">400005</span>;</span><br><span class="line"><span class="keyword">int</span> n,q,a[maxn];</span><br><span class="line">ll mx[maxs],mn[maxs],s[maxs],ad[maxs],len[maxs];</span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> ls x<<1</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> rs x<<1|1</span></span><br><span class="line"><span class="function"><span class="keyword">inline</span> <span class="keyword">void</span> <span class="title">pushup</span><span class="params">(<span class="keyword">int</span> x)</span> </span>{s[x]=s[ls]+s[rs];mx[x]=max(mx[ls],mx[rs]);mn[x]=min(mn[ls],mn[rs]);}</span><br><span class="line"><span class="function"><span class="keyword">inline</span> <span class="keyword">void</span> <span class="title">addad</span><span class="params">(<span class="keyword">int</span> x,<span class="keyword">int</span> w)</span> </span>{mx[x]+=w;mn[x]+=w;ad[x]+=w;s[x]+=len[x]*w;}</span><br><span class="line"><span class="function"><span class="keyword">inline</span> <span class="keyword">void</span> <span class="title">pushdown</span><span class="params">(<span class="keyword">int</span> x)</span></span>{</span><br><span class="line"><span class="keyword">if</span> (ad[x]) addad(ls,ad[x]),addad(rs,ad[x]),ad[x]=<span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">build</span><span class="params">(<span class="keyword">int</span> x,<span class="keyword">int</span> l,<span class="keyword">int</span> r)</span></span>{</span><br><span class="line">ad[x]=<span class="number">0</span>; len[x]=r-l+<span class="number">1</span>;</span><br><span class="line"><span class="keyword">if</span> (l==r) <span class="keyword">return</span> mx[x]=mn[x]=s[x]=a[l],<span class="keyword">void</span>();</span><br><span class="line"><span class="keyword">int</span> mid=l+r>><span class="number">1</span>;</span><br><span class="line">build(ls,l,mid);build(rs,mid+<span class="number">1</span>,r);</span><br><span class="line">pushup(x);</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">istad</span><span class="params">(<span class="keyword">int</span> x,<span class="keyword">int</span> l,<span class="keyword">int</span> r,<span class="keyword">int</span> ql,<span class="keyword">int</span> qr,<span class="keyword">int</span> w)</span></span>{</span><br><span class="line"><span class="keyword">if</span> (qr<l||r<ql) <span class="keyword">return</span>;</span><br><span class="line"><span class="keyword">if</span> (ql<=l&&r<=qr) <span class="keyword">return</span> addad(x,w);</span><br><span class="line"><span class="keyword">int</span> mid=l+r>><span class="number">1</span>; pushdown(x);</span><br><span class="line">istad(ls,l,mid,ql,qr,w);istad(rs,mid+<span class="number">1</span>,r,ql,qr,w);</span><br><span class="line">pushup(x);</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">istdv</span><span class="params">(<span class="keyword">int</span> x,<span class="keyword">int</span> l,<span class="keyword">int</span> r,<span class="keyword">int</span> ql,<span class="keyword">int</span> qr,<span class="keyword">int</span> d)</span></span>{</span><br><span class="line"><span class="keyword">if</span> (qr<l||r<ql) <span class="keyword">return</span>;</span><br><span class="line"><span class="keyword">if</span> (ql<=l&&r<=qr&&<span class="built_in">floor</span>(<span class="number">1.0</span>*mx[x]/d)-mx[x]==<span class="built_in">floor</span>(<span class="number">1.0</span>*mn[x]/d)-mn[x]) <span class="keyword">return</span> addad(x,<span class="built_in">floor</span>(<span class="number">1.0</span>*mn[x]/d)-mn[x]);</span><br><span class="line"><span class="keyword">int</span> mid=l+r>><span class="number">1</span>; pushdown(x);</span><br><span class="line">istdv(ls,l,mid,ql,qr,d);istdv(rs,mid+<span class="number">1</span>,r,ql,qr,d);</span><br><span class="line">pushup(x);</span><br><span class="line">}</span><br><span class="line"><span class="function">ll <span class="title">qrymn</span><span class="params">(<span class="keyword">int</span> x,<span class="keyword">int</span> l,<span class="keyword">int</span> r,<span class="keyword">int</span> ql,<span class="keyword">int</span> qr)</span></span>{</span><br><span class="line"><span class="keyword">if</span> (qr<l||r<ql) <span class="keyword">return</span> <span class="number">1e18</span>;</span><br><span class="line"><span class="keyword">if</span> (ql<=l&&r<=qr) <span class="keyword">return</span> mn[x];</span><br><span class="line"><span class="keyword">int</span> mid=l+r>><span class="number">1</span>; pushdown(x);</span><br><span class="line"><span class="keyword">return</span> min(qrymn(ls,l,mid,ql,qr),qrymn(rs,mid+<span class="number">1</span>,r,ql,qr));</span><br><span class="line">}</span><br><span class="line"><span class="function">ll <span class="title">qrys</span><span class="params">(<span class="keyword">int</span> x,<span class="keyword">int</span> l,<span class="keyword">int</span> r,<span class="keyword">int</span> ql,<span class="keyword">int</span> qr)</span></span>{</span><br><span class="line"><span class="keyword">if</span> (qr<l||r<ql) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line"><span class="keyword">if</span> (ql<=l&&r<=qr) <span class="keyword">return</span> s[x];</span><br><span class="line"><span class="keyword">int</span> mid=l+r>><span class="number">1</span>; pushdown(x);</span><br><span class="line"><span class="keyword">return</span> qrys(ls,l,mid,ql,qr)+qrys(rs,mid+<span class="number">1</span>,r,ql,qr);</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span>{</span><br><span class="line"><span class="built_in">scanf</span>(<span class="string">"%d%d"</span>,&n,&q);</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">1</span>;i<=n;i++) <span class="built_in">scanf</span>(<span class="string">"%d"</span>,&a[i]);</span><br><span class="line">build(<span class="number">1</span>,<span class="number">1</span>,n);</span><br><span class="line"><span class="keyword">while</span> (q--){</span><br><span class="line"><span class="keyword">int</span> c;<span class="built_in">scanf</span>(<span class="string">"%d"</span>,&c);</span><br><span class="line"><span class="keyword">if</span> (c==<span class="number">1</span>){</span><br><span class="line"><span class="keyword">int</span> l,r,w;<span class="built_in">scanf</span>(<span class="string">"%d%d%d"</span>,&l,&r,&w);l++,r++;</span><br><span class="line">istad(<span class="number">1</span>,<span class="number">1</span>,n,l,r,w);</span><br><span class="line">}<span class="keyword">else</span></span><br><span class="line"><span class="keyword">if</span> (c==<span class="number">2</span>){</span><br><span class="line"><span class="keyword">int</span> l,r,w;<span class="built_in">scanf</span>(<span class="string">"%d%d%d"</span>,&l,&r,&w);l++,r++;</span><br><span class="line">istdv(<span class="number">1</span>,<span class="number">1</span>,n,l,r,w);</span><br><span class="line">}<span class="keyword">else</span></span><br><span class="line"><span class="keyword">if</span> (c==<span class="number">3</span>){</span><br><span class="line"><span class="keyword">int</span> l,r;<span class="built_in">scanf</span>(<span class="string">"%d%d"</span>,&l,&r);l++,r++;</span><br><span class="line"><span class="built_in">printf</span>(<span class="string">"%lld\n"</span>,qrymn(<span class="number">1</span>,<span class="number">1</span>,n,l,r));</span><br><span class="line">}<span class="keyword">else</span>{</span><br><span class="line"><span class="keyword">int</span> l,r;<span class="built_in">scanf</span>(<span class="string">"%d%d"</span>,&l,&r);l++,r++;</span><br><span class="line"><span class="built_in">printf</span>(<span class="string">"%lld\n"</span>,qrys(<span class="number">1</span>,<span class="number">1</span>,n,l,r));</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"><span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<p><a href="https://loj.ac/problem/6029" target="_blank" rel="noopener">题面在这里</a></p>
<p></p>
<p>考虑一个区间除后变化量如果都相同,就转化为区间减了</p>
<p>维护最大值和
</summary>
<category term="题解" scheme="http://oi.linkfqy.top/categories/%E9%A2%98%E8%A7%A3/"/>
<category term="复杂度分析" scheme="http://oi.linkfqy.top/tags/%E5%A4%8D%E6%9D%82%E5%BA%A6%E5%88%86%E6%9E%90/"/>
<category term="线段树" scheme="http://oi.linkfqy.top/tags/%E7%BA%BF%E6%AE%B5%E6%A0%91/"/>
<category term="LOJ" scheme="http://oi.linkfqy.top/tags/LOJ/"/>
</entry>
</feed>