-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathatom.xml
404 lines (193 loc) · 402 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
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>MilkTeaAddicted</title>
<subtitle>欢迎来到晓沐的主页</subtitle>
<link href="http://sweetheart.nefu.site/atom.xml" rel="self"/>
<link href="http://sweetheart.nefu.site/"/>
<updated>2021-05-23T06:04:04.450Z</updated>
<id>http://sweetheart.nefu.site/</id>
<author>
<name>晓沐</name>
</author>
<generator uri="https://hexo.io/">Hexo</generator>
<entry>
<title>“Bert论文笔记</title>
<link href="http://sweetheart.nefu.site/2021/05/22/%E2%80%9CBert%E8%AE%BA%E6%96%87%E7%AC%94%E8%AE%B0/"/>
<id>http://sweetheart.nefu.site/2021/05/22/%E2%80%9CBert%E8%AE%BA%E6%96%87%E7%AC%94%E8%AE%B0/</id>
<published>2021-05-22T12:18:42.000Z</published>
<updated>2021-05-23T06:04:04.450Z</updated>
<content type="html"><![CDATA[<h1 id="Bert论文笔记"><a href="#Bert论文笔记" class="headerlink" title="Bert论文笔记"></a>Bert论文笔记</h1><p>首先放上论文的地址:</p><p><a href="https://arxiv.org/pdf/1810.04805.pdf">BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding</a></p><h2 id="背景介绍"><a href="#背景介绍" class="headerlink" title="背景介绍"></a>背景介绍</h2><p>NLP中有一个比较重要的任务就是如何将人类的句子和词翻译机器能够理解的表示,从而让机器进行处理。也就是说<strong>如何让机器理解人类语言</strong></p><p><img src="https://img-blog.csdnimg.cn/20190407192340124.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ppYW93b3Nob3V6aQ==,size_16,color_FFFFFF,t_70" alt="语言模型发展脉络简要梳理:"></p><ul><li><p>最简单最粗暴的表示方式是one-hot编码,即就像鸢尾花数据集中的one-hot表示,但是如果在词级别上用one-hot进行表示,那么表示词的向量将会非常大而且会过于稀疏,不利于机器处理,并且很难表示词的语义特征。</p><p><img src="https://img-blog.csdnimg.cn/20191128112529381.png" alt="img"></p></li><li><p>后来出现了Word Embedding ,这一方式解决了传统机器学习方法中的特征稀疏问题,它通过把一个词映射到一个低维稠密的语义空间,从而使得相似的词可以共享上下文的信息,从而提升泛化能力。而且通过无监督的训练(比如word2vec和glove方法),从而能够将这些语义知识迁移到数据较少的具体任务上。但是word embeding也有缺点,Word Embedding学到的是一个词的所有语义,比如bank可以是”银行”也可以是”水边。如果一定要用一个固定的向量来编码其语义,那么我们只能把这两个词的语义都编码进去,但是实际一个句子中只有一个语义是合理的,这显然是有问题的。也就是说word Embeding没有考虑到词在具体语境以及中的含义。</p><p><img src="https://img-blog.csdnimg.cn/20191024181316166.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3ZfSlVMWV92,size_16,color_FFFFFF,t_70" alt="img"></p></li><li><p>为了解决句子的在不同语境中的语义不同的问题,可以通过RNN来编码上下文的语义,但是最原始的RNN由于梯度消失和梯度爆炸等问题很难训练,后来引入了LSTM和GRU等模型来解决这个问题。最早的RNN只能用于分类、回归和序列标注等任务,通过引入两个RNN构成的Seq2Seq模型可以解决序列的变换问题。于是到了2017年,Google提出了Transformer模型,引入了Self-Attention。Self-Attention的初衷是为了用Attention替代LSTM,从而可以更好的并行(因为LSTM的时序依赖特效很难并行,而transformer一次可以处理多个词),从而可以处理更大规模的语料。</p><p><img src="https://img-blog.csdnimg.cn/20200818124139104.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTMwNjk1NTI=,size_16,color_FFFFFF,t_70" alt="img"></p></li><li><p>于是在transformer的基础上发展出了ELMo(<a href="https://arxiv.org/abs/1802.05365">Deep contextualized word representations</a>)与OpenAI GPT<a href="https://s3-us-west-2.amazonaws.com/openai-assets/research-covers/language-unsupervised/language_understanding_paper.pdf">(Improving Language Understanding by Generative Pre-Training)</a>这两预训练模型。ELMo会根据不同的任务,把上面得到的双向的LSTM的不同层的隐状态组合起来。使得输出的词表示与上下文相关的。可以用于下游(downstream)的特定任务。和ELMo不同,GPT得到的语言模型的参数不是固定的,它会根据特定的任务进行调整(通常是微调),这样得到的句子表示能更好的适配特定任务。它的思想其实也很简单,使用Transformer来学习一个语言模型,对句子进行无监督的Embedding,然后根据具体任务对Transformer的参数进行微调。从这一点来看,GPT的思想很接近本文要介绍的bert了。</p><p><img src="https://img-blog.csdnimg.cn/20190407193050891.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ppYW93b3Nob3V6aQ==,size_16,color_FFFFFF,t_70" alt="elmo"></p><p><img src="http://fancyerii.github.io/img/bert/gpt-2.png" alt="GPT在一些baseline的效果"></p></li><li><p><strong>一切过往, 皆为序章</strong>:尽管以及有能够考虑到上下文语义信息的模型,但是ELMo和GPT最大的问题就是其语言模型是单向的——我们是根据之前的历史来预测当前词。但是我们不能利用后面的信息。bert之所以state-of-the-art的一点就是其虽然也是基于transformer,但是BERT能够同时利用前后两个方向的信息。主要是源于其预训练的方法的创新。</p><blockquote><p>注意:即使ELMo训练了双向的两个RNN,但是一个RNN只能看一个方向,因此也是无法”同时”利用前后两个方向的信息的。</p></blockquote><p><img src="http://fancyerii.github.io/img/bert/bert-1.png"></p></li></ul><h2 id="摘要"><a href="#摘要" class="headerlink" title="摘要"></a>摘要</h2><blockquote><p>We introduce a new language representation model called BERT, which stands for Bidirectional Encoder Representations from Transformers. </p></blockquote><p>简介:bert首先是一个基于transform的双向编码表示。</p><blockquote><p>BERT is designed to pretrain deep bidirectional representations from unlabeled text by jointly conditioning on both left and right context in all layers. </p><p>As a result, the pre-trained BERT model can be finetuned with just one additional output layer to create state-of-the-art models for a wide range of tasks, such as question answering and language inference, without substantial taskspecific architecture modifications.</p></blockquote><p>其次摘要讲了下bert的上游和下游任务中的处理方式:</p><p>bert的预训练的策略是输入未标注的文本,bert的所有层中都要同时考虑未标记的文本的上下文,从而得到文本的深度编码表示(即机器能够理解并处理的语义表示)。</p><p>因此,预训练好的bert模型可以通过finetuned ,只用在后面接上一个输出层(应用于下游任务),就可以达到意料之外的效果,因此可以应用到广泛的学习任务中</p><blockquote><p>BERT is conceptually simple and empirically powerful. It obtains new state-of-the-art results on eleven natural language processing tasks, including pushing the GLUE score to 80.5% (7.7% point absolute improvement), MultiNLI accuracy to 86.7% (4.6% absolute improvement), SQuAD v1.1 question answering Test F1 to 93.2 (1.5 point absolute improvement) and SQuAD v2.0 Test F1 to 83.1 (5.1 point absolute improvement).</p></blockquote><p>摘要最后讲了下bert的效果:bert在概念上简单,在经验上有力。在11个NLP任务中取得了非常非常不错的成果(效果见下)</p><p><img src="https://images.cnblogs.com/cnblogs_com/zingp/1681929/o_200327035726bert_results.png"></p><p>以及具体这11个任务:</p><blockquote><p>MNLI:Multi-Genre Natural Language Inference,给定句子对,判断两个句子是蕴含、矛盾还是中立,三分类<br>QQP:Quora Question Pairs,给定句子对,判断语义是否相似,二分类<br>QNLI:Question Natural Language Inference,给定句子对,判断后者是否是前者的回答,二分类<br>SST-2:Standford Sentiment Treebank,给定单句,判断情感,二分类<br>CoLA:Corpus of Linguistic Acceptability,给定单句,判断是否是一句话?二分类<br>STS-B:Semantic Textual Similarity,给定句子对,判断相似度程度,五分类<br>MRPC:Microsoft Research Paraphrase Corpus,给定句子对,判断语义是否一致,二分类<br>RTE:Recognizing Texual Entailment,给定句子对,判断蕴含性,二分类<br>SQuAD1.1:Stanford Question Answering Dataset,经典阅读理解任务,给定(question,paragraph)对,预测answer在paragraph中的起止位置(span prediction)<br>CoNLL-2003 NER:命名实体识别任务,输入单句,为每个词进行标注<br>SWAG:Situations With Adversarial Generations,原任务是给定一句话,和4个选项,从选项里面找出它的下一句,这里转化为输入pair的分类问题,四分类</p></blockquote><h2 id="bert的介绍"><a href="#bert的介绍" class="headerlink" title="bert的介绍"></a>bert的介绍</h2><blockquote><p>We introduce BERT and its detailed implementation in this section. There are two steps in our framework: pre-training and fine-tuning. </p><p>During pre-training, the model is trained on unlabeled data over different pre-training tasks. For finetuning, the BERT model is first initialized with the pre-trained parameters, and all of the parameters are fine-tuned using labeled data from the downstream tasks. Each downstream task has separate fine-tuned models, even though they are initialized with the same pre-trained parameters. The question-answering example in Figure 1 will serve as a running example for this section.</p></blockquote><p>使用bert框架需要两步,即:上游的预训练以及下游的微调步骤</p><p>首先gooles对提供海量数据对bert进行了预训练(预训练时是基于未标注的数据),这样我们初始化bert模型的时候就不是随机初始化而是利用了gooles预先训练好的参数和权重,我们需要对bert模型进行微调,以应用到下游的NL任务中(此时我们微调时利用的数据是有标签的数据)</p><p>然后论文附了一张图来表示bert在预训练和微调时的区别:</p><p><img src="http://imageproxy.chaoxing.com/0x0,q15,jpeg,sWZd92CVrSN4lpFVYERT1CEXxTZp1_7FhIrWlEWu_U2U/http://p.ananas.chaoxing.com/star3/origin/af08075865a6245ea212e2f92d9016e7.png" alt="附图"></p><p>预训练时:输入的经过mask处理过后的连续的两句子用一个特殊符号[sep]来进行隔离,[cls]是在没有输入文本示例前加入的特殊符号,某种意义上相当于一个考虑了全文信息的特征表达。bert经过预训练完后能够得到一组权重参数。</p><p>微调:微调时的网路结构除了输出层要适应下游的文本的处理任务,其他结构和预训练的时的架构完全一致,微调期间所有参数都要进行微调</p><blockquote><p>A distinctive feature of BERT is its unified architecture across different tasks.</p></blockquote><p>Bert在应用到不同任务中时需要进行微调,但是应用到具体任务中时bert的架构都不改变,预训练和微调的方式只有细微的不同。</p><h2 id="当前背景介绍"><a href="#当前背景介绍" class="headerlink" title="当前背景介绍"></a>当前背景介绍</h2><blockquote><p>We argue that current techniques restrict the power of the pre-trained representations, especially for the fine-tuning approaches.</p><p>The major limitation is that standard language models are unidirectional, and this limits the choice of architectures that can be used during pre-training. For example, in OpenAI GPT, the authors use a left-toright architecture, where every token can only attend to previous tokens in the self-attention layers of the Transformer (Vaswani et al., 2017).</p></blockquote><p>作者总结了之前的一些模型的不足;</p><p>作者认为当前的处理技术限制了预训练的表示能力,特别是在预训练方式上;</p><p>以往的语义处理模型大多是单向的,只考虑上文或者只考虑下文。</p><p>比如在早期的GPT模型中,作者只考虑前文,这使得文章中每个taken都只参考Transformer的自注意层之前的token.也就是说以往的语义模型单向(即使是训练了双向RNN的ELMo,但是一个RNN只能关注文本的一个方向,无法像摘要中提到的那样,每一个层都利用文本前后的信息)</p><blockquote><p>In this paper, we improve the fine-tuning based approaches by proposing BERT: Bidirectional Encoder Representations from Transformers. </p><p>BERT alleviates the previously mentioned unidirectionality constraint by using a “masked language model” (MLM) pre-training objective, inspired by the Cloze task (Taylor, 1953). The masked language model randomly masks some of the tokens from the input, and the objective is to predict the original vocabulary id of the masked arXiv:1810.04805v2 [cs.CL] 24 May 2019 word based only on its context. Unlike left-toright language model pre-training, the MLM objective enables the representation to fuse the left and the right context, which allows us to pretrain a deep bidirectional Transformer. In addition to the masked language model, we also use a “next sentence prediction” task that jointly pretrains text-pair representations. The contributions of our paper are as follows:</p></blockquote><p>于是为了改进前人的语义模型,使得模型能够同时利用上下文的信息,Bert改进了预训练手段。比较创新的一点就是MLM的引入</p><h2 id="bert的预训练"><a href="#bert的预训练" class="headerlink" title="bert的预训练"></a>bert的预训练</h2><p>预训练的创新点在于如何让bert能够同时关注句子前后两个方向的信息</p><p>具体的实现方式可以如此描述:</p><p>bert 的模型根据完形填空这个任务的启发,通过使用一种叫MLM的的方式对文本进行预训练。</p><h3 id="预训练任务1-Masked-LM"><a href="#预训练任务1-Masked-LM" class="headerlink" title="预训练任务1 Masked LM"></a>预训练任务1 Masked LM</h3><p>(这里看论文没有理解,于是看了下源码的自述文件)</p><blockquote><p>在原始的预处理代码中,我们随机选择要屏蔽的单词级别的token(也就是像完形填空一样随机地盖住一些词)。例如:</p><pre><code>Input Text(原文本): the man jumped up , put his basket on phil ##am ##mon ' s head` `Original Masked Input(经过遮盖后的输出): [MASK] man [MASK] up , put his [MASK] on phil [MASK] ##mon ' s head</code></pre></blockquote><p>bert在预训练的时候会随机的Mask掉15%的词,然后让BERT来预测这些Mask的词,通过调整模型的参数使得模型预测正确的概率尽可能大,这等价于交叉熵的损失函数。这样的Transformer在编码一个词的时候会(必须)参考上下文的信息。</p><p>但是这有一个问题:在Mask 时会出现特殊的Token [MASK],但是在后面的fine-tuning时却不会出现,这会出现Mismatch的问题。</p><blockquote><p>(原文本): the man jumped up , put his basket on phil ##am ##mon ‘ s head</p><p>(经过遮盖后的输出): [MASK] man [MASK] up , put his [MASK] on phil [MASK] ##mon ‘ s head</p></blockquote><p>该如何理解这句话?还是以上述文本作为例子,(the)在这一轮预训练的时候以15%的概率被mask掉了,可能下一轮(the)这个词比较倒霉,还被mask掉,可能这个词一直运气都比较背,每轮都被mask,这样bert就只知道(the)位置上有个空缺,但是不知道这个词到底是什么,为了避免这种事情的发生,bert在mask词的时候采用了一种非常不错的机制:</p><p>如果某个Token在被选中的15%个Token里,则按照下面的方式随机的执行:</p><blockquote><ul><li>80%的概率替换成[MASK],比如my dog is hairy → my dog is [MASK](这样一个词真正被mask的可能降低到15%*80%,在这种概率下,实际情况中基本上不会出现某个词一直被mask无法被学习到的情况)</li><li>10%的概率替换成随机的一个词,比如my dog is hairy → my dog is apple(相当于加入噪音,提高泛化性)</li><li>10%的概率替换成它本身,比如my dog is hairy → my dog is hairy</li></ul></blockquote><p>这样做的好处是,BERT并不知道[MASK]替换的是哪一个词,而且任何一个词都有可能是被替换掉的,比如它看到的apple可能是被替换的词。这样强迫模型在编码当前时刻的时候不能太依赖于当前的词,而要考虑它的上下文,甚至更加上下文进行”纠错”。比如上面的例子模型在编码apple是根据上下文my dog is应该把apple(部分)编码成hairy的语义而不是apple的语义。</p><h3 id="预训练任务2-Next-Sentence-Prediction-NSP"><a href="#预训练任务2-Next-Sentence-Prediction-NSP" class="headerlink" title="预训练任务2 Next Sentence Prediction (NSP)"></a>预训练任务2 Next Sentence Prediction (NSP)</h3><p>许多重要的下游任务,如问答(QA)和自然语言推理(NLI)都是建立在理解两个句子之间关系的基础上的,而语言建模并不能直接捕捉到这一点。</p><p>也就是说为了适应某些下游任务的需要,因此BERT还增加了一个新的任务——预测两个句子是否有关联关系,这是一种Multi-Task Learing。</p><p>bert的预训练时选择一些句子对A与B,其中50%的数据B是A的下一条句子,剩余50%的数据B是语料库中随机选择的,学习其中的相关性,添加这样的预训练的目的是目前很多NLP的任务比如QA和NLI都需要理解两个句子之间的关系,从而能让预训练的模型更好的适应这样的任务。</p><blockquote><p>50%: [CLS] the man went to [MASK] store [SEP] he bought a gallon [MASK] milk [SEP]</p><p>另外50%:[CLS] the man [MASK] to the store [SEP] penguin [MASK] are flight ##less birds [SEP]</p></blockquote><h3 id="预训练流程"><a href="#预训练流程" class="headerlink" title="预训练流程"></a>预训练流程</h3><blockquote><p> The pre-training procedure largely follows the existing literature on language model pre-training. For the pre-training corpus we use the BooksCorpus (800M words) (Zhu et al., 2015) and English Wikipedia (2,500M words). For Wikipedia we extract only the text passages and ignore lists, tables, and headers. It is critical to use a document-level corpus rather than a shuffled sentence-level corpus such as the Billion Word Benchmark (Chelba et al., 2013) in order to extract long contiguous sequences.</p><p>使用BooksCorpus(800万字)(Zhu et al., 2015)和English Wikipedia(2500万字)。对于Wikipedia,我们只提取文本段落,而忽略列表、表格和标题。使用文档级语料库而不是打乱的句子级语料库(如Billion Word Benchmark (Chelba et al., 2013))来提取长连续序列是至关重要的。</p></blockquote><p>用BooksCorpus(800M词)+ 英文Wikipedia(2500M词)作为语料,作者强调使用document-level的语料比随机shuffle句子的语料(比如Billion Word Benchmark)要好,因为这样才能抽取出连续的长句子,才好用于BERT的数据构造。</p><p>bert模型是非常大的,所以train来非常消耗资源。</p><p>都是训练了4天,BASE版本的BERT,用16块TPU,LARGE版本的BERT,用64块TPU,只能说谷歌爸爸真的非常有钱。</p><p><img src="https://img-blog.csdnimg.cn/20190407194312495.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ppYW93b3Nob3V6aQ==,size_16,color_FFFFFF,t_70" alt="参数对比以及预训练时长以及配置"></p><h2 id="bert的微调"><a href="#bert的微调" class="headerlink" title="bert的微调"></a>bert的微调</h2><blockquote><p>For each task, we simply plug in the task specific inputs and outputs into BERT and fine tune all the parameters end-to-end. </p><p>对于每个任务,我们只需将特定于任务的输入和输出插入BERT,并端到端调整所有参数。</p></blockquote><p>普通人很难训练一个标准的bert模型,据说8个GPU一起训练需要训练一年左右。但是谷歌已经预训练好了bert模型并且提供了开源使用<a href="https://github.com/google-research/bert">(代码地址)</a>,所以如果我们要使用bert模型,只需对其进行微调,应用到具体任务中即可。</p><h3 id="论文中提及的应对四种不同任务的微调方式"><a href="#论文中提及的应对四种不同任务的微调方式" class="headerlink" title="论文中提及的应对四种不同任务的微调方式"></a>论文中提及的应对四种不同任务的微调方式</h3><p>论文中探讨了4用bert处理的任务,论述了bert的使用。</p><p><img src="http://fancyerii.github.io/img/bert/bert-3.png"></p><ul><li><p>对于普通的分类任务,输入是一个序列,如图中右上所示,所有的Token都是属于同一个Segment(Id=0),我们用第一个特殊Token [CLS]的最后一层输出接上softmax进行分类,用分类的数据来进行Fine-Tuning(<strong>即需要用[SEP]分隔两个句子输入到模型中,然后同样仅须将[CLS]的输出送到分类器进行分类</strong>)。</p></li><li><p>对于相似度计算等输入为两个序列的任务(句子对关系任务)),过程如图左上所示。<strong>两个序列的Token对应不同的Segment(Id=0/1)。我们也是用第一个特殊Token [CLS]的最后一层输出接上softmax进行分类,然后用分类数据进行Fine-Tuning</strong>。</p></li><li><p>对于序列标注( SQuAD v2.0),比如命名实体识别,输入是一个句子(Token序列),除了[CLS]和[SEP]的每个时刻都会有输出的Tag,比如B-PER表示人名的开始,本章的序列标注部分已经介绍过怎么把NER变成序列标注的问题了,这里不再赘述。然后用输出的Tag来进行Fine-Tuning,过程如图右下所示。<strong>即对每个位置的输出进行分类即可,如果将每个位置的输出作为特征输入到CRF将取得更好的效果。</strong>;</p></li><li><p>第四类是问答类问题,比如SQuAD v1.1数据集,输入是一个问题和一段很长的包含答案的文字(Paragraph),输出在这段文字里找到问题的答案。<strong>即将问题与答案拼接输入到BERT模型中,然后将答案位置的输出向量进行二分类并在句子方向上进行softmax(只需预测开始和结束位置即可)</strong></p></li></ul><h3 id="应用bert前应做的数据预处理"><a href="#应用bert前应做的数据预处理" class="headerlink" title="应用bert前应做的数据预处理"></a>应用bert前应做的数据预处理</h3><p>由于bert是基于transformer的编码器,所以数据预处理要符合tramformer的需求</p><p>这里引用了<a href="https://blog.csdn.net/weixin_37763870/article/details/104452213">自然语言处理——BERT情感分类实战(一)之预处理</a></p><p>其中预处理有如下六步</p><p><img src="https://img-blog.csdnimg.cn/20200222225157335.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zNzc2Mzg3MA==,size_16,color_FFFFFF,t_70" alt="文本数据喂入bert前因做的六部预处理工作"></p><ul><li><p>step1<strong>分词</strong>:将文本的词按照单词级别进行划分,注意这里分词的规则:<img src="https://img-blog.csdnimg.cn/20200223122520237.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zNzc2Mzg3MA==,size_16,color_FFFFFF,t_70" alt="示例"></p></li><li><p>step2<strong>对文本划分句子以及标注</strong>:为句首添加[CLS]标志,然后用[SEP]划分每个字句</p><p><img src="https://img-blog.csdnimg.cn/20200223122958594.png"></p></li><li><p>step3<strong>用[PAD]填充句子</strong>:因为输入的每个句子要保证序列长度要一致,所以如果我定义喂入bert的序列长度为20,则如果现在句子长度(加上cls和sep后的长度)没有20,则要用[pad]进行填充,保证输入进入的序列长度是20,这从引用者的代码便可以看出</p><pre><code class="python">padded_tokens = tokens + ['[PAD]' for _ in range(20 - len(tokens))]print(padded_tokens)#效果如下</code></pre><p><img src="https://img-blog.csdnimg.cn/20200223123621517.png" alt="填充效果"></p></li></ul><ul><li><p>step4<strong>注意力mask编码</strong>:即有单词的为1,用[PAD]填充的为0,让bert知道句子的什么地方有语义什么地方没有</p><p><img src="https://img-blog.csdnimg.cn/20200223124312192.png" alt="img"></p></li><li><p>step5<strong>分段segment编码</strong>:用于区分不同的句子,我们这里只有一个句子,故全设为0</p><p><img src="https://img-blog.csdnimg.cn/20200223124943164.png" alt="img"></p></li><li><p>step6<strong>把token转化为id</strong>:文本分词后创建一个包含对应字 id的字典,这一步则是要查到每个单词对应的序号,转化为id</p><p><img src="https://img-blog.csdnimg.cn/20200223125408549.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zNzc2Mzg3MA==,size_16,color_FFFFFF,t_70" alt="img"></p></li></ul><p>最后我们要把得到了mask编码、segment编码、taken_id一起喂入bert</p><p><img src="https://img-blog.csdnimg.cn/20200223125937384.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zNzc2Mzg3MA==,size_16,color_FFFFFF,t_70" alt="首先三者转化为tensor"></p><p><img src="https://img-blog.csdnimg.cn/20200223130559772.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zNzc2Mzg3MA==,size_16,color_FFFFFF,t_70" alt="然后把三者一起喂进bert里,bert会返回我们下游任务需要的cls和hindden_reps的tensor表示"></p><h2 id="模型架构"><a href="#模型架构" class="headerlink" title="模型架构"></a>模型架构</h2><blockquote><p>BERT’s model architecture is a multi-layer bidirectional Transformer encoder based on the original implementation described in Vaswani et al. (2017) and released in the tensor2tensor library.1 Because the use of Transformers has become common and our implementation is almost identical to the original, </p><p>we will omit an exhaustive background description of the model architecture and refer readers to Vaswani et al. (2017) as well as excellent guides such as “The Annotated Transformer.”</p></blockquote><p>bert的模型架构是参考了Vaswani et al. (2017)的多层双向的 Transformer 编码器,因为bert对此实现基本上和原参考一致,而且transformer在NLP任务中使用比较广泛,所以这篇文章就不再细讲Vaswani et al. (2017)中编码器的实现(bert中的’T’ 的实现)</p><blockquote><p>In this work, we denote the number of layers (i.e., Transformer blocks) as L, the hidden size as H, and the number of self-attention heads as A. 3 We primarily report results on two model sizes: BERTBASE (L=12, H=768, A=12, Total Parameters=110M) and BERTLARGE (L=24, H=1024, A=16, Total Parameters=340M).</p></blockquote><p>在介绍bert模型的架构时作者做出如下定义:</p><ul><li>作者直接定义一个Transformer blocks作为网络中的一层(L),(模型将将堆叠作者定义的L)。</li><li>隐藏层神经元规模用H表示(表示编码的维度)</li><li>A表示self-attention heads的数量;</li></ul><p>作者就L,H,A的不同进行了效果比对,发现参数越多规模越大效果越好</p><p><img src="http://fancyerii.github.io/img/bert/bert-8.png" alt="img"></p><h2 id="结果分析"><a href="#结果分析" class="headerlink" title="结果分析"></a>结果分析</h2><p>在GLUE评测平台上的结果如下图所示,我们可以发现BERT比之前最好的OpenAI GPT还提高了很多</p><p><img src="http://fancyerii.github.io/img/bert/bert-4.png" alt="img"></p><p>在SQuAD数据集上,BERT之前最好的结果F1=89.3%,而7个BERT的ensembling能达到93.2%的F1得分</p><p><img src="http://fancyerii.github.io/img/bert/bert-5.png" alt="img"></p><p>bert模型的创新点在于Mask LM和预测句子关系的Multi-Task Learning。为了知道每个改动的贡献,文章做了如下的对照(Ablation)实验。</p><p>如下图所示,这里测试用的是小参数的一个BERT参考模型;</p><ul><li><p>No NSP是没有预测句子关系(只有Mask LM)的BERT模型;</p></li><li><p>-LTR & No NSP基本等同于OpenAI GPT,它是基于Transoformer的从左到右的普通语言模型;</p></li><li><p>而最后一行+BiLSTM是指在Fine-Tuning OpenAI GPT的时候多加一个双向LSTM层(通常的Fine-Tuning都是只有一个线性层)。</p><p><img src="http://fancyerii.github.io/img/bert/bert-7.png" alt="img"></p></li></ul><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>bert的优点就不用说了11个NLP任务中屠榜</p><p>但是作者在论文中也提到了bert的缺点:</p><ul><li>[MASK]标记在实际预测中不会出现,训练时用过多[MASK]影响模型表现</li><li>每个batch只有15%的token被预测,所以BERT收敛得比left-to-right模型要慢(它们会预测每个token)(<strong>虽然预训练慢但是应用起来准确率高,对有钱有设备的谷歌来说都是小问题</strong>)</li><li>BERT的预训练任务MLM使得能够借助上下文对序列进行编码,但同时也使得其预训练过程与中的数据与微调的数据不匹配,难以适应生成式任务</li><li>BERT没有考虑预测[MASK]之间的相关性,是对语言模型联合概率的有偏估计</li><li>由于最大输入长度的限制(见上数据预处理),适合句子和段落级别的任务,不适用于文档级别的任务(如长文本分类)</li></ul><h2 id="参考资料"><a href="#参考资料" class="headerlink" title="参考资料"></a>参考资料</h2><p><a href="http://fancyerii.github.io/2019/03/09/bert-theory/">BERT模型详解- 李理的博客</a></p><p><a href="https://blog.csdn.net/Peter_Changyb/article/details/109162774">NLP中的经典BERT模型详解(最全面)</a></p><p><a href="https://blog.csdn.net/Magical_Bubble/article/details/89514057">BERT解读(论文 + TensorFlow源码)</a></p><p><a href="https://www.cnblogs.com/zingp/p/13849679.html">BERT模型详解- ZingpLiu - 博客园</a></p><p><a href="https://blog.csdn.net/weixin_37763870/article/details/104452213">自然语言处理——BERT情感分类实战(一)之预处理</a></p><p><a href="https://www.bilibili.com/video/BV1P4411F77q?t=2050">汉语自然语言处理-从零解读碾压循环神经网络的transformer模型(一)-注意力机制-位置编码-attention is all you need</a></p><p><a href="https://www.bilibili.com/video/BV1Mt411J734?p=2&t=1866">汉语自然语言处理-BERT的解读语言模型预训练-实践应用-transformer模型(二)-语料预处理-情感分析分类-数据增强-解决过拟合问题</a></p>]]></content>
<summary type="html"><h1 id="Bert论文笔记"><a href="#Bert论文笔记" class="headerlink" title="Bert论文笔记"></a>Bert论文笔记</h1><p>首先放上论文的地址:</p>
<p><a href="https://arxiv.org/p</summary>
<category term="NLP" scheme="http://sweetheart.nefu.site/categories/NLP/"/>
<category term="ML" scheme="http://sweetheart.nefu.site/tags/ML/"/>
<category term="NLP" scheme="http://sweetheart.nefu.site/tags/NLP/"/>
<category term="Bert" scheme="http://sweetheart.nefu.site/tags/Bert/"/>
</entry>
<entry>
<title>使用Python语言刷蓝桥杯历年真题</title>
<link href="http://sweetheart.nefu.site/2021/04/17/%E4%BD%BF%E7%94%A8Python%E8%AF%AD%E8%A8%80%E5%88%B7%E8%93%9D%E6%A1%A5%E6%9D%AF%E5%8E%86%E5%B9%B4%E7%9C%9F%E9%A2%98/"/>
<id>http://sweetheart.nefu.site/2021/04/17/%E4%BD%BF%E7%94%A8Python%E8%AF%AD%E8%A8%80%E5%88%B7%E8%93%9D%E6%A1%A5%E6%9D%AF%E5%8E%86%E5%B9%B4%E7%9C%9F%E9%A2%98/</id>
<published>2021-04-17T09:56:56.000Z</published>
<updated>2021-04-17T12:14:26.841Z</updated>
<content type="html"><![CDATA[<h1 id="用Python来刷蓝桥杯历年真题吧"><a href="#用Python来刷蓝桥杯历年真题吧" class="headerlink" title="用Python来刷蓝桥杯历年真题吧"></a>用Python来刷蓝桥杯历年真题吧</h1><p>其实看这发布时间就知道应该是就是<del>考前抱佛脚</del>考前演练</p><h2 id="11届蓝桥杯-Python组"><a href="#11届蓝桥杯-Python组" class="headerlink" title="11届蓝桥杯 Python组"></a>11届蓝桥杯 Python组</h2><p>11届是蓝桥杯第一次开Python赛道,之前刷题都是按照C/C艹组的难度来刷的题目</p><p>看看第一届Python组会有多难吧</p><h3 id="试题A-:门牌制作"><a href="#试题A-:门牌制作" class="headerlink" title="试题A :门牌制作"></a>试题A :门牌制作</h3><p>【问题描述】<br>小蓝要为一条街的住户制作门牌号。这条街一共有 2020 位住户,门牌号从 1 到 2020 编号。小蓝制作门牌的方法是先制作 0 到 9 这几个数字字符,最后根据需要将字符粘贴到门牌上,例如门牌 1017 需要依次粘贴字符 1、0、1、7,即需要 1 个字符 0,2 个字符 1,1 个字符 7。<br>请问要制作所有的 1 到 2020 号门牌,总共需要多少个字符 2?</p><pre><code class="python">count_n=0for i in range(1,2021): j=str(i) count_n+=j.count('2')print(count_n)#624</code></pre><h3 id="试题-B-寻找-2020"><a href="#试题-B-寻找-2020" class="headerlink" title="试题 B: 寻找 2020"></a>试题 B: 寻找 2020</h3><p>【问题描述】<br>小蓝有一个数字矩阵,里面只包含数字 0 和 2。小蓝很喜欢 2020,他想找<br>到这个数字矩阵中有多少个 2020 。<br>小蓝只关注三种构成 2020 的方式:<br>• 同一行里面连续四个字符从左到右构成 2020。<br>• 同一列里面连续四个字符从上到下构成 2020。<br>• 在一条从左上到右下的斜线上连续四个字符,从左上到右下构成 2020。<br>例如,对于下面的矩阵:<br>220000<br>000000<br>002202<br>000000<br>000022<br>002020<br>一共有 5 个 2020。其中 1 个是在同一行里的,1 个是在同一列里的,3 个<br>是斜线上的。<br>小蓝的矩阵比上面的矩阵要大,由于太大了,他只好将这个矩阵放在了一个文件里面,在试题目录下有一个文件 2020.txt,里面给出了小蓝的矩阵。<br>请帮助小蓝确定在他的矩阵中有多少个 2020。<br>文件2020.txt找不到了,所以大概的写了用例的解决代码。找到2020.txt其实只要改下for循环的长度就可以了。</p><pre><code class="python">count=0with open('2020.txt') as f: L=f.readlines() for i in L: count+=i.count("2020") len_col=len(L[0]) len_row=len(L) for j in range(len_row-3): for i in range(len_col): if L[j][i]=='2' and L[j][i+1]=='0' and L[j][i+2]=='2' and L[j][i+3]=='0' : count+=1 for i in range(len_col): for j in range(len_row-3): if L[j][i]=='2' and L[j+1][i]=='0' and L[j+2][i]=='2' and L[j+3][i]=='0' : count+=1 #最重点的一步来了, for i in range(len_col-3): for j in range(len_row-3): if L[j][i] == '2' and L[j + 1][i+1] == '0' and L[j + 2][i+2] == '2' and L[j + 3][i+3] == '0': count += 1 print(count)#20915#很奇怪,列用count来找和一个个匹配结果不一样</code></pre><h3 id="试题C:跑步锻炼"><a href="#试题C:跑步锻炼" class="headerlink" title="试题C:跑步锻炼"></a>试题C:跑步锻炼</h3><p><img src="https://img-blog.csdnimg.cn/20210313204033753.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0d5Z2VydA==,size_16,color_FFFFFF,t_70"></p><pre><code class="python">import datetimea=datetime.date(2000,1,1)b=datetime.date(2020,10,1)sub=datetime.timedelta(days=1)c=1while a<=b: if a.day==1 or a.weekday()==1: c+=2 else: c+=1 a+=subprint(c)</code></pre><p><a href="https://blog.csdn.net/u011250186/article/details/103972471?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522161865844116780264014572%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=161865844116780264014572&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-103972471.first_rank_v2_pc_rank_v29&utm_term=datetime">datatime的用法</a></p><h3 id="试题D-蛇形填数"><a href="#试题D-蛇形填数" class="headerlink" title="试题D:蛇形填数"></a>试题D:蛇形填数</h3><p><img src="https://img-blog.csdnimg.cn/20210316200806449.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0d5Z2VydA==,size_16,color_FFFFFF,t_70"></p><p>找规律的题,建议手写找出规律后用python计算</p><h3 id="试题F-成绩统计"><a href="#试题F-成绩统计" class="headerlink" title="试题F:成绩统计"></a>试题F:成绩统计</h3><p><img src="https://img-blog.csdnimg.cn/20210316202208452.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0d5Z2VydA==,size_16,color_FFFFFF,t_70"></p><p><img src="https://img-blog.csdnimg.cn/20210316202222162.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0d5Z2VydA==,size_16,color_FFFFFF,t_70"></p><p>送分题就不打了</p><h3 id="试题G-单词分析"><a href="#试题G-单词分析" class="headerlink" title="试题G:单词分析"></a>试题G:单词分析</h3><p><img src="https://img-blog.csdnimg.cn/20210316202338139.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0d5Z2VydA==,size_16,color_FFFFFF,t_70"></p><p>白给题又一道</p><pre><code class="python">L=input()c=0max=0for i in L: c=L.count(i) if c>max: max=c j=iprint(j)print(max)</code></pre><h3 id="试题H:数字三角形"><a href="#试题H:数字三角形" class="headerlink" title="试题H:数字三角形"></a>试题H:数字三角形</h3><p><img src="https://img-blog.csdnimg.cn/20210316201907139.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0d5Z2VydA==,size_16,color_FFFFFF,t_70"></p><p><img src="https://img-blog.csdnimg.cn/20210316201946889.png"></p><p>比上面两个有难度,但还是一道送分的题</p><pre><code class="python">n=int(input())m=[]for i in range(n): m.append(list(map(int,input().split())))print(m)for i in range(n): for j in range(i): m[i][j]+=max(m[i-1][j-1],m[i-1][j])if(n%2==0): print(max(m[n-1][n//2],m[n-1][n//2-1]))else: print(m[n-1][n//2])</code></pre><h3 id="试题I-平面切分"><a href="#试题I-平面切分" class="headerlink" title="试题I:平面切分"></a>试题I:平面切分</h3><p>平面切分,不会写,空了</p><p>抄来的思路:</p><p>每有一条平行线则平面+1,每条线每和其他线产生一个交点,则新增平面数=产生交点数+1<br>初版代码先放这(提供下思路,后面还会修改)</p><pre><code class="python">def px(a1,a2,b1,b2): if(a1==a2 and b1!=b2): return 1 else: return 0def xj(a1,a2): if(a1!=a2): return 1 else: return 0n=int(input())a=[0]*nb=[0]*nx=[0]*ny=[0]*ns=2point=0for i in range(n): a[i],b[i]=map(int,input().split())for i in range(n): if(i>0): for j in range(i): if(px(a[i],a[j],b[i],b[j])):#如果平行则平面+1 s+=1 elif(xj(a[i],a[j])): x[i]=(b[i]-b[j])/(a[j]-a[i]) y[i]=a[i]*x[i]+b[i] if(x[i]==x[j] and y[i]==y[j]): point+=1 s+=point+1print(s)</code></pre><p>emmmmm总结一下,第一次开的python组试题基本上大多为送分题,虽然不知道我将要参加的第二届蓝桥杯会是什么一种情况,要是真就这难度那就好了,辣鸡只想搞一个省二以上</p>]]></content>
<summary type="html"><h1 id="用Python来刷蓝桥杯历年真题吧"><a href="#用Python来刷蓝桥杯历年真题吧" class="headerlink" title="用Python来刷蓝桥杯历年真题吧"></a>用Python来刷蓝桥杯历年真题吧</h1><p>其实看这发布时间就知</summary>
<category term="蓝桥杯" scheme="http://sweetheart.nefu.site/categories/%E8%93%9D%E6%A1%A5%E6%9D%AF/"/>
<category term="Python" scheme="http://sweetheart.nefu.site/tags/Python/"/>
</entry>
<entry>
<title>蓝桥杯Python算法训练</title>
<link href="http://sweetheart.nefu.site/2021/03/18/%E8%93%9D%E6%A1%A5%E6%9D%AFPython%E7%AE%97%E6%B3%95%E8%AE%AD%E7%BB%83/"/>
<id>http://sweetheart.nefu.site/2021/03/18/%E8%93%9D%E6%A1%A5%E6%9D%AFPython%E7%AE%97%E6%B3%95%E8%AE%AD%E7%BB%83/</id>
<published>2021-03-18T12:15:41.000Z</published>
<updated>2021-04-16T13:41:14.440Z</updated>
<content type="html"><![CDATA[<h1 id="蓝桥杯Python组算法训练"><a href="#蓝桥杯Python组算法训练" class="headerlink" title="蓝桥杯Python组算法训练"></a>蓝桥杯Python组算法训练</h1><h2 id="1"><a href="#1" class="headerlink" title="1"></a>1</h2><blockquote><p>题目 1017: [编程入门]完数的判断</p><p>时间限制: 1Sec 内存限制: 128MB 提交: 23074 解决: 10991</p><p>题目描述</p><p>一个数如果恰好等于不包含它本身所有因子之和,这个数就称为”完数”。 例如,6的因子为1、2、3,而6=1+2+3,因此6是”完数”。 编程序找出N之内的所有完数,并按下面格式输出其因子</p><p>输入</p><p>N</p><p>输出</p><p>? its factors are ? ? ?</p><p>样例输入</p><pre><code>1000</code></pre><p>样例输出</p><pre><code>6 its factors are 1 2 3 28 its factors are 1 2 4 7 14 496 its factors are 1 2 4 8 16 31 62 124 248 </code></pre></blockquote><pre><code class="python">n=int(input())list=[]for i in range(1,n+1): sum=0 for j in range(1,i): if(i%j==0): sum+=j list.append(j) if sum==i: print(sum,end=' ') print('its factors are',end=' ') for k in list: print(k,end=' ') print() list=[]</code></pre><p>时间超限50%</p><p>以下是不超限的题解</p><pre><code class="python">a=int(input())for i in range(2,a): b=[1] sums=1 c=int(pow(i,0.5))+1 for j in range(2,c): if i%j==0: b.append(j) b.append(int(i/j)) sums+=j+int(i/j) if sums==i: b.sort() print(i,'its factors are ',end='') for j in range (len(b)): print(b[j],end=' ') print()</code></pre><h2 id="2"><a href="#2" class="headerlink" title="2"></a>2</h2><blockquote><p>题目 1021: [编程入门]迭代法求平方根</p><p>时间限制: 1Sec 内存限制: 128MB 提交: 14256 解决: 7563</p><p>题目描述</p><p>用迭代法求 平方根</p><p>公式:求a的平方根的迭代公式为: X[n+1]=(X[n]+a/X[n])/2 要求前后两次求出的差的绝对值少于0.00001。 输出保留3位小数</p><p>输入</p><p>X</p><p>输出</p><p>X的平方根</p><p>样例输入</p><pre><code>4</code></pre><p>样例输出</p><pre><code>2.000</code></pre></blockquote><pre><code class="python">from math import *a=int(input())b=a/2#从1开始迭代c=(b+a/b)/2while abs(c-b)>=0.00001: b=c c=(b+a/b)/2print("%.3f"%c)</code></pre><h2 id="3"><a href="#3" class="headerlink" title="3"></a>3</h2><blockquote><p>题目 1023: [编程入门]选择排序</p><p>时间限制: 1Sec 内存限制: 128MB 提交: 22695 解决: 10654</p><p>题目描述</p><p>用选择法对10个整数从小到大排序。</p><p>输入</p><p>输入10个无序的数字</p><p>输出</p><p>排序好的10个整数</p><p>样例输入</p><pre><code>4 85 3 234 45 345 345 122 30 12</code></pre></blockquote><pre><code class="python">m=list(map(int,input().split()))m.sort()for i in m: print(i)</code></pre><h2 id="4"><a href="#4" class="headerlink" title="4"></a>4</h2><blockquote><p>题目 1011: [编程入门]最大公约数与最小公倍数</p><p>时间限制: 1Sec 内存限制: 128MB 提交: 29761 解决: 16522</p><p>题目描述</p><p>输入两个正整数m和n,求其最大公约数和最小公倍数。</p><p>输入</p><p>两个整数</p><p>输出</p><p>最大公约数,最小公倍数</p><p>样例输入</p><pre><code>5 7</code></pre><p>样例输出</p><pre><code>1 35</code></pre></blockquote><pre><code class="python">def gcd(a, b): if a%b == 0: return b else: return gcd(b, a%b)a, b = map(int, input().split())if a<b: c=a a=b b=cs = gcd(a, b)print("&#123;&#125; &#123;:.0f&#125;".format(s, (a*b)/s))</code></pre><h2 id="5"><a href="#5" class="headerlink" title="5"></a>5</h2><blockquote><p>题目 1044: [编程入门]三个字符串的排序</p><p>时间限制: 1Sec 内存限制: 128MB 提交: 11726 解决: 5993</p><p>题目描述</p><p>输入三个字符串,按由小到大的顺序输出</p><p>输入</p><p>3行字符串</p><p>输出</p><p>按照从小到大输出成3行</p><p>样例输入</p><pre><code>cdeafgabc</code></pre><p>样例输出</p><pre><code>abcafgcde</code></pre></blockquote><pre><code class="python">a=input();b=input();c=input()x=[a,b,c]x.sort()for i in x: print(i)</code></pre><h2 id="6"><a href="#6" class="headerlink" title="6"></a>6</h2><blockquote><p>题目 1047: [编程入门]报数问题</p><p>时间限制: 1Sec 内存限制: 128MB 提交: 8494 解决: 4512</p><p>题目描述</p><p>有n人围成一圈,顺序排号。从第1个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来的第几号的那位。</p><p>输入</p><p>初始人数n</p><p>输出</p><p>最后一人的初始编号</p><p>样例输入</p><pre><code>3</code></pre><p>样例输出</p><pre><code>2</code></pre></blockquote><pre><code class="python">n = int(input())s = [i for i in range(1,n+1)]i = 1 # 当前报的数index = 0 # 当前的位置while len(s) != 1: # 当只剩一人的时候退出 if i == 3: del s[index] # 当前的人报数为3的时候删除,因为当前人的推出index不必+1即代表下一个人 i = 1 # 从新从1开始报数 else: index += 1 i += 1 if index == len(s): # 报到最后一位时,重新开始从第一个人开始报数 index = 0print(s[0])</code></pre><p>如果每次len(数组),会超时</p><h2 id="7"><a href="#7" class="headerlink" title="7"></a>7</h2><blockquote><p>题目 1084: 用筛法求之N内的素数。</p><p>时间限制: 1Sec 内存限制: 64MB 提交: 16162 解决: 9636</p><p>题目描述</p><p>用筛法求之N内的素数。</p><p>输入</p><p>N</p><p>输出</p><p>0~N的素数</p><p>样例输入</p><pre><code>100</code></pre><p>样例输出</p><pre><code>2357111317192329313741434753596167717379838997</code></pre></blockquote><pre><code class="python">a=int(input())l=[2]for i in range(2,a+1): if i<=2: continue for m in range(2,i): if i%m==0: break else: l.append(i)it = iter(l)for x in it: print (x, end="\n")</code></pre><p>以上有误</p><h2 id="8"><a href="#8" class="headerlink" title="8"></a>8</h2><blockquote><p>题目描述</p><p>有一头母牛,它每年年初生一头小母牛。每头小母牛从第四个年头开始,每年年初也生一头小母牛。请编程实现在第n年的时候,共有多少头母牛?</p><p>输入</p><p>输入数据由多个测试实例组成,每个测试实例占一行,包括一个整数n(0<n<55),n的含义如题目中描述。<br>n=0表示输入数据的结束,不做处理。</p><p>输出</p><p>对于每个测试实例,输出在第n年的时候母牛的数量。<br>每个输出占一行。</p><p>样例输入</p><pre><code>2450</code></pre><p>样例输出</p><pre><code>246</code></pre></blockquote><pre><code class="python">#递归表达式写出来是n=n-1+n-3n=int(input())while n: n1, n2, n3 = 4, 3, 2 k=0 if n<5: print(n) else: n=n-4 while n: k=n1 +n3 n3=n2 n2=n1 n1=k n=n-1 print(k) n=int(input())</code></pre><h2 id="9"><a href="#9" class="headerlink" title="9"></a>9</h2><blockquote><p>题目 1093: 字符逆序</p><p>时间限制: 1Sec 内存限制: 64MB 提交: 20847 解决: 10636</p><p>题目描述</p><p>将一个字符串str的内容颠倒过来,并输出。str的长度不超过100个字符。</p><p>输入</p><p>输入包括一行。 第一行输入的字符串。</p><p>输出</p><p>输出转换好的逆序字符串。</p><p>样例输入</p><pre><code>I am a student</code></pre><p>样例输出</p><pre><code>tneduts a ma I</code></pre></blockquote><pre><code class="python">m=input().split()m.reverse()for i in m: print(i,end=" ")#这是按单词逆序</code></pre><pre><code class="python">x=input("")x=x[::-1] #列表切片,逆序输出print(x)#按字母输出</code></pre><h2 id="10"><a href="#10" class="headerlink" title="10"></a>10</h2><blockquote><p>题目 1094: 字符串的输入输出处理</p><p>时间限制: 1Sec 内存限制: 64MB 提交: 19709 解决: 7115</p><p>题目描述</p><p>字符串的输入输出处理。</p><p>输入</p><p>第一行是一个正整数N,最大为100。之后是多行字符串(行数大于N), 每一行字符串可能含有空格,字符数不超过1000。</p><p>输出</p><p>先将输入中的前N行字符串(可能含有空格)原样输出,再将余下的字符串(不含有空格)以空格或回车分割依次按行输出。每行输出之间输出一个空行。</p><p>样例输入</p><pre><code>2www.dotcpp.com DOTCPPA C MD O T CPP</code></pre><p>样例输出</p><pre><code>www.dotcpp.com DOTCPPA C MDOTCPP</code></pre></blockquote><pre><code class="python">n=int(input())for i in range(n): str=input() print(str) print()while True:#注意这里,保持后续的输入 str=input().split(' ') for i in str : print(i) print()</code></pre><h2 id="11"><a href="#11" class="headerlink" title="11"></a>11</h2><blockquote><p>题目 1097: 蛇行矩阵</p><p>时间限制: 1Sec 内存限制: 64MB 提交: 10033 解决: 6737</p><p>题目描述</p><p>蛇形矩阵是由1开始的自然数依次排列成的一个矩阵上三角形。</p><p>输入</p><p>本题有多组数据,每组数据由一个正整数N组成。(N不大于100)</p><p>输出</p><p>对于每一组数据,输出一个N行的蛇形矩阵。两组输出之间不要额外的空行。矩阵三角中同一行的数字用一个空格分开。行尾不要多余的空格。</p><p>样例输入</p><pre><code>5</code></pre><p>样例输出</p><pre><code>1 3 6 10 152 5 9 144 8 137 1211</code></pre></blockquote><pre><code class="python">n=int(input())list1=[ ]list1.append(1)for j in range(2,n+1): list1.append(list1[-1]+j)for i in list1: print(i,end=' ')n=n-1print()j=1while n: for i in range(n): list1[i] = list1[i] + j + i#对这个链表进行更新,保证从上一列取输出 print(list1[i],end=' ') print() n=n-1 j=j+1</code></pre><h2 id="12"><a href="#12" class="headerlink" title="12"></a>12</h2><blockquote><p>题目 1110: 2^k进制数</p><p>时间限制: 1Sec 内存限制: 128MB 提交: 1953 解决: 966</p><p>题目描述</p><p>设r是个2^k 进制数,并满足以下条件:<br>(1)r至少是个2位的2^k 进制数。<br>(2)作为2^k 进制数,除最后一位外,r的每一位严格小于它右边相邻的那一位。<br>(3)将r转换为2进制数q后,则q的总位数不超过w。<br>在这里,正整数k(1≤k≤9)和w(k〈w≤30000)是事先给定的。</p><p>问:满足上述条件的不同的r共有多少个?<br>我们再从另一角度作些解释:设S是长度为w 的01字符串(即字符串S由w个“0”或“1”组成),S对应于上述条件(3)中的q。将S从右起划分为若干个长度为k 的段,每段对应一位2^k进制的数,如果S至少可分成2段,则S所对应的二进制数又可以转换为上述的2^k 进制数r。<br>例:设k=3,w=7。则r是个八进制数(2^3=8)。由于w=7,长度为7的01字符串按3位一段分,可分为3段(即1,3,3,左边第一段只有一个二进制位),则满足条件的八进制数有:<br>2位数:高位为1:6个(即12,13,14,15,16,17),高位为2:5个,…,高位为6:1个(即67)。共6+5+…+1=21个。<br>3位数:高位只能是1,第2位为2:5个(即123,124,125,126,127),第2位为3:4个,…,第2位为6:1个(即167)。共5+4+…+1=15个。<br>所以,满足要求的r共有36个。</p><p>输入</p><p>只有1行,为两个正整数,用一个空格隔开:<br>k w</p><p>输出</p><p>1行,是一个正整数,为所求的计算结果,即满足条件的不同的r的个数(用十进制数表示),要求最高位不得为0,各数字之间不得插入数字以外的其他字符(例如空格、换行符、逗号等)。<br>(提示:作为结果的正整数可能很大,但不会超过200位)</p><p>样例输入</p><pre><code>3 7</code></pre><p>样例输出</p><pre><code>36</code></pre></blockquote><pre><code class="python">#一开始我想用dfs写,但是看了下题解好像有更简单的方法,把过程类比成二项式求解n, m = map(int, input().split())shang, yu = divmod(m, n)def zuheshu(j, i): # 求组合数用 if i > j: return 0 if j < 0: return 0 sum = 1 for t in range(i): sum = sum * (j - t) //(t + 1) return sums0 = sum([zuheshu(2 ** n-1, i) for i in range(2, shang + 1)]) # 当没有达到高位,只用非高位求组合数,结果同排序后的结果s1 = sum([zuheshu(2 ** n - 1 - x0, shang) for x0 in range(1, 2 ** yu)]) # 在全范围内减去高位范围的组合数print(s1 + s0)</code></pre><blockquote><p>原题链接:<a href="https://www.dotcpp.com/oj/problem1110.html">2^k进制数</a></p><p>解题思路:</p><p>因为只要保证每个位置上的数不相同,自然可以把它们从小到大排列</p><p>所以只需从第二个数(从右往左)一直计算当前位置的排列数最后加起来就行</p><p>因为除最高位以外,别的位置的范围都是从 1 到 进制数减去当前位置<br>所以先计算除最高位以外的排列数,再计算最高位的排列数</p><p>注意事项:</p><p>最高位的排列数应该用减法思维,即拿k=3,w=8来说,最高位只能取1-3,实际计算的时候应该拿最高位可以取1-7的情况减去最高位可以取4-7的情况,因为假设最高位取了2,后面只能比前面大,所以此时要排除后面取1和2的情况,计算量大。如果计算4-7,则最高位和后面都只能取4-7,不存在最高位能取后面不能取的情况,即最高位和后面都只能取4-7等于从4张牌里挑3张,共4种,最高位可以取1-7即7张牌里挑3张,共35种,35减4=31</p><p>当然加法也可以做,即最高位取1加最高位取2加最高位取3,即最高位取1,后面6张挑2张,等于15,最高位取2,后面取不了1了,5张挑2张,等于10,最高位取3,后面取不了1和2了,4张挑2张,等于6,15+10+6=31</p><p>最终答案用最高位排列数加上最高位以外的排列数即 31+21=52 </p></blockquote><h2 id="13"><a href="#13" class="headerlink" title="13"></a>13</h2><blockquote><p>题目 1115: DNA</p><p>时间限制: 1Sec 内存限制: 128MB 提交: 9689 解决: 3342</p><p>题目描述</p><p>小强从小就喜欢生命科学,他总是好奇花草鸟兽从哪里来的。终于, 小强上中学了,接触到了神圣的名词–DNA.它有一个双螺旋的结构。这让一根筋的小强抓破头皮,“要是能画出来就好了” 小强喊道。现在就请你帮助他吧</p><p>输入</p><p>输入包含多组测试数据。第一个整数N(N<=15),N表示组数,每组数据包含两个整数a,b。a表示一个单位的DNA串的行数,a为奇数且 3<=a<=39。b表示重复度(1<=b<=20)。</p><p>输出</p><p>输出DNA的形状,每组输出间有一空行。</p><p>样例输入</p><pre><code>23 15 4</code></pre><p>样例输出</p><pre><code>X X XX XX X X X X X XX X X X X X XX X X X X X XX X X X X X XX X</code></pre></blockquote><pre><code class="python">n=int(input())for i in range(n): col,num=map(int ,input().split()) list_=[[' ' for i in range(col)] for i in range(col)]#创建一个二维矩阵 for j in range(col): for k in range(col): if j==k or (j+k)==col-1: list_[k][j]='X' for j in range(1,num+1): if j%2: for l in range(col): for t in range(col): print(list_[l][t], end='') print() else: for l in range(1,col-1): for t in range(col): print(list_[l][t],end='') print() if j==num: for l in range(1): for t in range(col): print(list_[l][t], end='') print() print()</code></pre><h2 id="14"><a href="#14" class="headerlink" title="14"></a>14</h2><blockquote><p>题目 1116: IP判断</p><p>时间限制: 1Sec 内存限制: 128MB 提交: 8310 解决: 3380</p><p>题目描述</p><p>在基于Internet的程序中,我们常常需要判断一个IP字符串的合法性。<br>合法的IP是这样的形式:<br>A.B.C.D<br>其中A、B、C、D均为位于[0, 255]中的整数。为了简单起见,我们规定这四个整数中不允许有前导零存在,如001这种情况。<br>现在,请你来完成这个判断程序吧^_^</p><p>输入</p><p>输入由多行组成,每行是一个字符串,输入由“End of file”结束。<br>字符串长度最大为30,且不含空格和不可见字符</p><p>输出</p><p>对于每一个输入,单独输出一行<br>如果该字符串是合法的IP,输出Y,否则,输出N</p><p>样例输入</p><pre><code>1.2.3.4a.b.c.d267.43.64.1212.34.56.bb210.43.64.129-123.4.5.6</code></pre><p>样例输出</p><pre><code>YNNNYN</code></pre></blockquote><pre><code class="python">#这个题C做绝对没有python舒服</code></pre><h2 id="15"><a href="#15" class="headerlink" title="15"></a>15</h2><blockquote><p>题目 1117: K-进制数</p><p>时间限制: 1Sec 内存限制: 128MB 提交: 3161 解决: 1247</p><p>题目描述</p><p>考虑包含N位数字的K-进制数. 定义一个数有效, 如果其K-进制表示不包含两连续的0.</p><p>考虑包含N位数字的K-进制数. 定义一个数有效, 如果其K-进制表示不包含两连续的0.</p><p>例:<br>1010230 是有效的7位数<br>1000198 无效<br>0001235 不是7位数, 而是4位数.</p><p>给定两个数N和K, 要求计算包含N位数字的有效K-进制数的总数.</p><p>假设2 <= K <= 10; 2 <= N; 4 <= N+K <= 18.</p><p>输入</p><p>两个十进制整数N和K</p><p>输出</p><p>十进制表示的结果</p><p>样例输入</p><pre><code>210</code></pre><p>样例输出</p><pre><code>90</code></pre></blockquote><pre><code class="python"># 写下思路:# (1)dp# 这题是可以看成是一道dp题# 首先首位必须是除了0以外的数# 首位的可能性是确定为K-1:如果是十进制那么只有9个数在首位# 然后后面的每一列可以取0 或非0# 那么对于10进制dp表达式是:# dp[i]=10*dp[i-1](如果前面串是非0那么此处10种取法)+9*dp[i-2](如果前面是0,那么有9种取法)# dfs同理n=int(input())k=int(input())re=0def loop(c,m): global n,k,re#全局变量应用 if c==1:#对于每个分支到尽头了 if m==0: re+=k-1#这一分支最后有k-1种选择 else: re+=k#这一分支最后有 elif c==n: for i in range(1,k):#直接开启k-1个分支 loop(c-1,i) else: if m==0:#如果前面是0,那么开启k-1分支 for i in range(1,k): loop(c-1,i) else:#如果前面 for i in range(0,k):#如果前面不是0,那么开启k分支 loop(c-1,i)loop(n,1)print(re)</code></pre><h2 id="16"><a href="#16" class="headerlink" title="16"></a>16</h2><blockquote><p>题目 1118: Tom数</p><p>时间限制: 1Sec 内存限制: 128MB 提交: 10594 解决: 4180</p><p>题目描述</p><p>正整数的各位数字之和被Tom称为Tom数。求输入数(<2^32)的Tom数!</p><p>输入</p><p>每行一个整数(<2^32).</p><p>输出</p><p>每行一个输出,对应该数的各位数之和.</p><p>样例输入</p><pre><code>123455612382</code></pre><p>样例输出</p><pre><code>151710</code></pre></blockquote><pre><code class="python">x=input()while x: print(sum([int(i) for i in x])) x=input() #python就是这么优雅</code></pre><h2 id="17"><a href="#17" class="headerlink" title="17"></a>17</h2><blockquote><p>题目 1255: [蓝桥杯][算法提高]能量项链</p><p>时间限制: 1Sec 内存限制: 128MB 提交: 3366 解决: 1094</p><p>题目描述</p><p>在Mars星球上,每个Mars人都随身佩带着一串能量项链。在项链上有 N颗能量珠。能量珠是一颗有头标记与尾标记的珠子,这些标记对应着某个正整数。并且,对于相邻的两颗珠子,前一颗珠子的尾标记一定等于后一颗珠子的头标 记。因为只有这样,通过吸盘(吸盘是Mars人吸收能量的一种器官)的作用,这两颗珠子才能聚合成一颗珠子,同时释放出可以被吸盘吸收的能量。如果前一颗 能量珠的头标记为m,尾标记为r,后一颗能量珠的头标记为r,尾标记为n,则聚合后释放的能量为m<em>r</em>n(Mars单位),新产生的珠子的头标记为m, 尾标记为n。<br>需要时,Mars人就用吸盘夹住相邻的两颗珠子,通过聚合得到能量,直到项链上只剩下一颗珠子为止。显然,不同的聚合顺序得到的总能量是不同的,请你设计一个聚合顺序,使一串项链释放出的总能量最大。<br>例如:设N=4,4颗珠子的头标记与尾标记依次为(2,3) (3,5) (5,10) (10,2)。我们用记号◎表示两颗珠子的聚合操作,(j◎k)表示第j,k两颗珠子聚合后所释放的能量。则第4、1两颗珠子聚合后释放的能量为:<br>(4◎1)=10<em>2</em>3=60。<br>这一串项链可以得到最优值的一个聚合顺序所释放的总能量为<br>((4◎1)◎2)◎3)=10<em>2</em>3+10<em>3</em>5+10<em>5</em>10=710。</p><p>输入</p><p>第一行是一个正整数N(4≤N≤100),表示项链上珠子的个数。第二行 是N个用空格隔开的正整数,所有的数均不超过1000。第i个数为第i颗珠子的头标记(1≤i≤N),当i〈N时,第i颗珠子的尾标记应该等于第i+1颗 珠子的头标记。第N颗珠子的尾标记应该等于第1颗珠子的头标记。<br>至于珠子的顺序,你可以这样确定:将项链放到桌面上,不要出现交叉,随意指定第一颗珠子,然后按顺时针方向确定其他珠子的顺序。</p><p>输出</p><p>只有一行,是一个正整数E(E≤2.1*10^9),为一个最优聚合顺序所释放的总能量</p><p>样例输入</p><pre><code>42 3 5 10</code></pre><p>样例输出</p><pre><code>710</code></pre></blockquote><pre><code class="python"># 看了c++的题解,可以每次消掉最小的那一个进行排序#自己写的n = int(input())l = list(map(int, input().split()))l1 = l[:]# 作为副本l.sort()sum = 0def caculate(l): global sum if len(l) == 1: pass else: i = l.pop(0) # 每次弹出最小的 index_i = l1.index(i) index_i_=(index_i + len(l1) + 1) % len(l1) index_i__=(index_i + len(l1) - 1) % len(l1) sum += i * l1[index_i_] * l1[index_i__] l1.pop(index_i) caculate(l)caculate(l)print(sum)</code></pre><p>看过的一种简洁的题解</p><pre><code class="python">num = int(input())lst = list(map(int,input().strip().split()))rst = 0for i in range(num-1): a=lst.index(min(lst)) rst+=lst[a]*lst[a-1]*lst[(a+1)%(num-i)] del lst[a]print(rst)</code></pre><h2 id="18"><a href="#18" class="headerlink" title="18"></a>18</h2><blockquote><p>如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着。与空格子相邻的格子中的卡片可以移动到空格中。经过若干次移动,可以形成第二个图所示的局面。</p><p><img src="https://www.dotcpp.com/oj/upload/image/20170306/20170306084421_13973.png" alt="img"></p><p>我们把第一个图的局面记为:12345678.<br>把第二个图的局面记为:123.46758<br>显然是按从上到下,从左到右的顺序记录数字,空格记为句点。<br>本题目的任务是已知九宫的初态和终态,求最少经过多少步的移动可以到达。如果无论多少步都无法到达,则输出-1。</p><p>输入</p><p>输入第一行包含九宫的初态,第二行包含九宫的终态。 </p><p>输出</p><p>输出最少的步数,如果不存在方案,则输出-1。</p><p>样例输入</p><pre><code>12345678. 123.46758 </code></pre><p>样例输出</p><pre><code>3</code></pre></blockquote><pre><code class="python"></code></pre><p>这道题主要考察双向BFs</p><h2 id="19"><a href="#19" class="headerlink" title="19"></a>19</h2><blockquote><p>题目 1427: [蓝桥杯][2013年第四届真题]买不到的数目</p><p>时间限制: 1Sec 内存限制: 128MB 提交: 5850 解决: 2963</p><p>题目描述</p><p>小明开了一家糖果店。他别出心裁:把水果糖包成4颗一包和7颗一包的两种。糖果不能拆包卖。<br>小朋友来买糖的时候,他就用这两种包装来组合。当然有些糖果数目是无法组合出来的,比如要买 10 颗糖。<br>你可以用计算机测试一下,在这种包装情况下,最大不能买到的数量是17。大于17的任何数字都可以用4和7组合出来。<br>本题的要求就是在已知两个包装的数量时,求最大不能组合出的数字。</p><p>输入</p><p>两个正整数,表示每种包装中糖的颗数(都不多于1000) </p><p>输出</p><p>一个正整数,表示最大不能买到的糖数 </p><p>样例输入</p><pre><code>4 7 </code></pre><p>样例输出</p><pre><code>17</code></pre></blockquote><pre><code class="python">L=[int(i) for i in input().split()]re=(min(L)-1)*(max(L))-min(L)if min(L)==1: print(0)else: print(re)</code></pre><p>自己写了下感觉 没有这个题解好</p><p><a href="https://blog.dotcpp.com/a/64446">[蓝桥杯][2013年第四届真题]买不到的数目-题解(Python代码) 一个公式而已</a></p><h2 id="20"><a href="#20" class="headerlink" title="20"></a>20</h2><blockquote><p>题目 1429: [蓝桥杯][2014年第五届真题]兰顿蚂蚁</p><p>时间限制: 1Sec 内存限制: 128MB 提交: 3930 解决: 1772</p><p>题目描述</p><p><img src="https://www.dotcpp.com/oj/upload/image/20170306/20170306151514_74936.png" alt="img"></p><p>兰顿蚂蚁,是于1986年,由克里斯·兰顿提出来的,属于细胞自动机的一种。</p><p>平面上的正方形格子被填上黑色或白色。在其中一格正方形内有一只“蚂蚁”。<br>蚂蚁的头部朝向为:上下左右其中一方。</p><p>蚂蚁的移动规则十分简单:<br>若蚂蚁在黑格,右转90度,将该格改为白格,并向前移一格;<br>若蚂蚁在白格,左转90度,将该格改为黑格,并向前移一格。</p><p>规则虽然简单,蚂蚁的行为却十分复杂。刚刚开始时留下的路线都会有接近对称,像是会重复,但不论起始状态如何,蚂蚁经过漫长的混乱活动后,会开辟出一条规则的“高速公路”。</p><p>蚂蚁的路线是很难事先预测的。</p><p>你的任务是根据初始状态,用计算机模拟兰顿蚂蚁在第n步行走后所处的位置。</p><p>输入</p><p>输入数据的第一行是 m n 两个整数(3 < m, n < 100),表示正方形格子的行数和列数。<br>接下来是 m 行数据。<br>每行数据为 n 个被空格分开的数字。0 表示白格,1 表示黑格。 </p><p>接下来是一行数据:x y s k, 其中x y为整数,表示蚂蚁所在行号和列号(行号从上到下增长,列号从左到右增长,都是从0开始编号)。s 是一个大写字母,表示蚂蚁头的朝向,我们约定:上下左右分别用:UDLR表示。k 表示蚂蚁走的步数。 </p><p>输出</p><p>输出数据为一个空格分开的整数 p q, 分别表示蚂蚁在k步后,所处格子的行号和列号。</p><p>样例输入</p><pre><code>5 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 3 L 5</code></pre><p>样例输出</p><pre><code>1 3</code></pre></blockquote><pre><code class="python">m,n=map(int,input().split())#m行数和n列数Gra=[]dir="URDL"#右手方向xx=[0,-1,0,1]yy=[-1,0,1,0]for i in range(m): gra=list(map(int,input().split())) Gra.append(gra)x,y,d,num=input().split()x,y,num=map(lambda i:int(i),[x,y,num])x,y=x-1,y-1def move_ant(x,y,d,n): d=dir.index(d) for i in range(n): if(Gra[x][y]):#如果是黑色的格子 d=((d+4)+1)%4 x+=xx[d] y+=yy[d] else: d=d=((d+4)-1)%4 x += xx[d] y += yy[d] return x,yx,y=move_ant(x,y,d,num)print(x,y)</code></pre><h2 id="21"><a href="#21" class="headerlink" title="21"></a>21</h2><blockquote><h4 id="题目-1432-蓝桥杯-2013年第四届真题-剪格子"><a href="#题目-1432-蓝桥杯-2013年第四届真题-剪格子" class="headerlink" title="题目 1432: [蓝桥杯][2013年第四届真题]剪格子"></a>题目 1432: [蓝桥杯][2013年第四届真题]剪格子</h4><p>时间限制: 1Sec 内存限制: 128MB 提交: 3361 解决: 1161</p><p>题目描述</p><p>历届试题 剪格子<br>时间限制:1.0s 内存限制:256.0MB</p><p>问题描述<br>如下图所示,3 x 3 的格子中填写了一些整数。<br>+–<em>–+–+<br>|10</em> 1|52|<br>+–<strong><strong>–+<br>|20|30* 1|<br>***</strong></strong>–+<br>| 1| 2| 3|<br>+–+–+–+<br>我们沿着图中的星号线剪开,得到两个部分,每个部分的数字和都是60。<br>本题的要求就是请你编程判定:对给定的m x n 的格子中的整数,是否可以分割为两个部分,使得这两个区域的数字和相等。<br>如果存在多种解答,请输出包含左上角格子的那个区域包含的格子的最小数目。<br>如果无法分割,则输出 0。</p><p>输入</p><p>程序先读入两个整数 m n 用空格分割 (m,n< 10)。<br>表示表格的宽度和高度。<br>接下来是n行,每行m个正整数,用空格分开。每个整数不大于10000。 </p><p>输出</p><p>输出一个整数,表示在所有解中,包含左上角的分割区可能包含的最小的格子数目。 </p><p>样例输入</p><pre><code>3 310 1 5220 30 11 2 3</code></pre><p>样例输出</p><pre><code>3</code></pre></blockquote><pre><code class="python">def dfs(x,y,ant,cur): global sum_,count,vis,n,m xx = [0, 1, 0, -1] yy = [1, 0, -1, 0] if cur==sum_ and ant<count: count=ant#当达到结尾的时候 else: #四个方向寻找 for j in range(4): x+=xx[j] y+=yy[j] if(x>=0 and x<m and y>=0 and y<n and vis[x][y]):#注意取反 #如果没有没出界而且没有访问 vis[x][y]=False dfs(x,y,ant+1,cur+Gra[x][y]) vis[x][y]=True else: continueGra=[]sum_=0count=1000n,m=map(int,input().split())#m列n行for i in range(n): list_=list(map(int,input().split())) sum_=sum_+sum(list_) Gra.append(list_)vis=[[True for i in range(m)] for j in range(n)]vis[0][0]=Falseif sum_%2:#如果是基数那么结束 print(0) exit()else: sum_//=2dfs(0,0,1,Gra[0][0])if (count==1000): print(0)else: print(count)</code></pre><h2 id="22"><a href="#22" class="headerlink" title="22"></a>22</h2><blockquote><h4 id="题目-1433-蓝桥杯-2013年第四届真题-危险系数"><a href="#题目-1433-蓝桥杯-2013年第四届真题-危险系数" class="headerlink" title="题目 1433: [蓝桥杯][2013年第四届真题]危险系数"></a>题目 1433: [蓝桥杯][2013年第四届真题]危险系数</h4><p>时间限制: 1Sec 内存限制: 128MB 提交: 2897 解决: 1075</p><p>题目描述</p><p>问题描述<br>抗日战争时期,冀中平原的地道战曾发挥重要作用。<br>地道的多个站点间有通道连接,形成了庞大的网络。但也有隐患,当敌人发现了某个站点后,其它站点间可能因此会失去联系。<br>我们来定义一个危险系数DF(x,y):<br>对于两个站点x和y (x != y), 如果能找到一个站点z,当z被敌人破坏后,x和y不连通,那么我们称z为关于x,y的关键点。相应的,对于任意一对站点x和y,危险系数DF(x,y)就表示为这两点之间的关键点个数。<br>本题的任务是:已知网络结构,求两站点之间的危险系数。</p><p>输入</p><p>输入数据第一行包含2个整数n(2 < = n < = 1000), m(0 < = m < = 2000),分别代表站点数,通道数;<br>接下来m行,每行两个整数 u,v (1 < = u, v < = n; u != v)代表一条通道;<br>最后1行,两个数u,v,代表询问两点之间的危险系数DF(u, v)。 </p><p>输出</p><p>一个整数,如果询问的两点不连通则输出-1. </p><p>样例输入</p><pre><code>7 61 32 33 43 54 55 61 6</code></pre><p>样例输出</p><pre><code>2</code></pre></blockquote><pre><code class="python">n,m=map(int,input().split())#n个点m个通道Gra=[[False for i in range(n+1)] for i in range(n+1)]Vis=[True for i in range(n+1)]path=[0 for i in range(n+1)]for i in range(m): x,y=map(int,input().split()) Gra[x][y]=True Gra[y][x]=Truestart,end=map(int,input().split())def dfs(s,e): global Gra,Vis,path if(s==e): for i in range(n): if not Vis[i]: path[i]+=1#注意在最后数数和访问就数数不一样 return else: for i in range(1,n+1): if Gra[s][i] and Vis[i]: Vis[i]=False dfs(i,e) Vis[i]=Truedfs(start,end)print(path.count(path[end])-1)#没有全对</code></pre><h2 id="23"><a href="#23" class="headerlink" title="23"></a>23</h2><blockquote><h4 id="题目-1434-蓝桥杯-历届试题-回文数字"><a href="#题目-1434-蓝桥杯-历届试题-回文数字" class="headerlink" title="题目 1434: [蓝桥杯][历届试题]回文数字"></a>题目 1434: [蓝桥杯][历届试题]回文数字</h4><p>时间限制: 1Sec 内存限制: 128MB 提交: 10531 解决: 4347</p><p>题目描述</p><p>观察数字:12321,123321 都有一个共同的特征,无论从左到右读还是从右向左读,都是相同的。这样的数字叫做:回文数字。</p><p>本题要求你找到一些5位或6位的十进制数字。满足如下要求:<br>该数字的各个数位之和等于输入的整数。</p><p>输入</p><p>一个正整数 n (10< n< 100), 表示要求满足的数位和。</p><p>输出</p><p>若干行,每行包含一个满足要求的5位或6位整数。<br>数字按从小到大的顺序排列。<br>如果没有满足条件的,输出:-1 </p><p>样例输入</p><pre><code>44 </code></pre><p>样例输出</p><pre><code>99899499994589985598895679976688886697796769967778877787787796697859958868868877778886688895598949949958859967769976679985589994499</code></pre></blockquote><pre><code class="python">count=0goal=int(input())flag=Truefor i in range(100,1000): j=str(i) j=[int(i) for i in j] if(sum(j[:-1])*2+j[-1]==goal): j=str(i) print(j[:-1]+j[::-1]) flag=Falsefor i in range(100,1000): j=str(i) j=[int(i) for i in j] if(sum(j)*2==goal): j=str(i) print(j+j[::-1]) flag = Falseif flag: print(-1)</code></pre><h2 id="24"><a href="#24" class="headerlink" title="24"></a>24</h2><blockquote><h4 id="题目-1435-蓝桥杯-历届试题-国王的烦恼"><a href="#题目-1435-蓝桥杯-历届试题-国王的烦恼" class="headerlink" title="题目 1435: [蓝桥杯][历届试题]国王的烦恼"></a>题目 1435: [蓝桥杯][历届试题]国王的烦恼</h4><p>时间限制: 1Sec 内存限制: 128MB 提交: 1607 解决: 459</p><p>题目描述</p><p>C国由n个小岛组成,为了方便小岛之间联络,C国在小岛间建立了m座大桥,每座大桥连接两座小岛。两个小岛间可能存在多座桥连接。然而,由于海水冲刷,有一些大桥面临着不能使用的危险。</p><p>如果两个小岛间的所有大桥都不能使用,则这两座小岛就不能直接到达了。然而,只要这两座小岛的居民能通过其他的桥或者其他的小岛互相到达,他们就会安然无事。但是,如果前一天两个小岛之间还有方法可以到达,后一天却不能到达了,居民们就会一起抗议。</p><p>现在C国的国王已经知道了每座桥能使用的天数,超过这个天数就不能使用了。现在他想知道居民们会有多少天进行抗议。</p><p>下文中的样例说明<br>第一天后2和3之间的桥不能使用,不影响。<br>第二天后1和2之间,以及1和3之间的桥不能使用,居民们会抗议。<br>第三天后3和4之间的桥不能使用,居民们会抗议。<br>数据规模和约定<br>对于100%的数据,1< =n< =10000,1< =m< =100000,1< =a, b< =n, 1< =t< =100000。</p><p>输入</p><p>输入的第一行包含两个整数n, m,分别表示小岛的个数和桥的数量。<br>接下来m行,每行三个整数a, b, t,分别表示该座桥连接a号和b号两个小岛,能使用t天。小岛的编号从1开始递增。</p><p>输出</p><p>输出一个整数,表示居民们会抗议的天数。</p><p>样例输入</p><pre><code>4 41 2 21 3 22 3 13 4 3</code></pre><p>样例输出</p><pre><code>2</code></pre></blockquote><p>并查集</p><p>思路:天数从大到小排序,如果有一个桥生成,那么居民抗议一天</p><pre><code class="python">n,m=map(int,input().split())#n点个数m,桥个数Gra=[]fa=[0 for i in range(1000)]for i in range(m): L=list(map(int ,input().split())) Gra.append(L)def init(): global fa for i in range(1,n+1): fa[i]=idef find_(x): if( x==fa[x]): return x else: fa[x]=find_(fa[x]) return fa[x]def kruskal(): global fa ,n init();#初始化并查集 Gra.sort(key=lambda x:x[2]) res=0;Time=-1 for i in range(m): p1=find_(Gra[i][0]) p2=find_(Gra[i][1]) if (p1!=p2):#如果不是一个集合 fa[p2]=p1#连上,表示同一集合 if(Gra[i][2]!=Time):#开始断桥 res+=1 Time=Gra[i][2] n-=1 if n ==1: break return resprint(kruskal()-1)</code></pre><h2 id="25"><a href="#25" class="headerlink" title="25"></a>25</h2><blockquote><h4 id="题目-1436-蓝桥杯-2014年第五届真题-地宫取宝"><a href="#题目-1436-蓝桥杯-2014年第五届真题-地宫取宝" class="headerlink" title="题目 1436: [蓝桥杯][2014年第五届真题]地宫取宝"></a>题目 1436: [蓝桥杯][2014年第五届真题]地宫取宝</h4><p>时间限制: 1Sec 内存限制: 128MB 提交: 3733 解决: 1060</p><p>题目描述</p><p>X 国王有一个地宫宝库。是 n x m 个格子的矩阵。每个格子放一件宝贝。每个宝贝贴着价值标签。</p><p>地宫的入口在左上角,出口在右下角。</p><p>小明被带到地宫的入口,国王要求他只能向右或向下行走。</p><p>走过某个格子时,如果那个格子中的宝贝价值比小明手中任意宝贝价值都大,小明就可以拿起它(当然,也可以不拿)。</p><p>当小明走到出口时,如果他手中的宝贝恰好是k件,则这些宝贝就可以送给小明。</p><p>请你帮小明算一算,在给定的局面下,他有多少种不同的行动方案能获得这k件宝贝。</p><p>输入</p><p>输入一行3个整数,用空格分开:n m k (1< =n,m< =50, 1< =k< =12) </p><p>接下来有 n 行数据,每行有 m 个整数 Ci (0< =Ci< =12)代表这个格子上的宝物的价值 </p><p>输出</p><p>要求输出一个整数,表示正好取k个宝贝的行动方案数。该数字可能很大,输出它对 1000000007 取模的结果。</p><p>样例输入</p><pre><code>2 3 21 2 32 1 5</code></pre><p>样例输出</p><pre><code>14</code></pre></blockquote><pre><code class="python">n,m,k=map(int,input().split())# 记录迷宫的宝贝价值table=[]for _ in range(n): table.append(list(map(int,input().split())))# 状态列表dp[1][2][3][4]=5 表示坐标(1,2)这个点物品数量为3最大价值为4的方案有5种dp=[[[[-1]*15 for _ in range(15)] for _ in range(51)]for _ in range(51)]#深度遍历def dfs(x,y,sum,max): #因为如果这个方案先前采用了,就会有一个值而不是初始值-1 if dp[x][y][sum][max+1]!=-1: #直接将记录过的状态返回 return dp[x][y][sum][max+1] #方案数 t=0 #到达终点 if x==n-1 and y==m-1: #最后一个格子能选 if table[x][y]>max: #可选可不选,若选那么只能再选最后一个(先前有k-1个) if sum==k or sum==k-1: t+=1 elif k==sum: #不能选也算一种方案 t+=1 dp[x][y][sum][max+1]=t #返回终点的方案数 return dp[x][y][sum][max+1] #向下走 if x+1<n: #可选 if table[x][y]>max: t+=dfs(x+1,y,sum+1,table[x][y]) t%=1000000007 #不选 t+=dfs(x+1,y,sum,max) t%=1000000007 #向右走 if y+1<m: #可选 if table[x][y]>max: t+=dfs(x,y+1,sum+1,table[x][y]) t%=1000000007 #不选 t+=dfs(x,y+1,sum,max) t%=1000000007 dp[x][y][sum][max+1]=t return dp[x][y][sum][max+1]dp[0][0][0][0]=dfs(0,0,0,-1)print(dp[0][0][0][0])</code></pre><h2 id="26"><a href="#26" class="headerlink" title="26"></a>26</h2><blockquote><h4 id="目-1439-蓝桥杯-历届试题-小朋友排队"><a href="#目-1439-蓝桥杯-历届试题-小朋友排队" class="headerlink" title="目 1439: [蓝桥杯][历届试题]小朋友排队"></a>目 1439: [蓝桥杯][历届试题]小朋友排队</h4><p>时间限制: 1Sec 内存限制: 128MB 提交: 2447 解决: 434</p><p>题目描述</p><p>n 个小朋友站成一排。现在要把他们按身高从低到高的顺序排列,但是每次只能交换位置相邻的两个小朋友。</p><p>每个小朋友都有一个不高兴的程度。开始的时候,所有小朋友的不高兴程度都是0。</p><p>如果某个小朋友第一次被要求交换,则他的不高兴程度增加1,如果第二次要求他交换,则他的不高兴程度增加2(即不高兴程度为3),依次类推。当要求某个小朋友第k次交换时,他的不高兴程度增加k。</p><p>请问,要让所有小朋友按从低到高排队,他们的不高兴程度之和最小是多少。</p><p>如果有两个小朋友身高一样,则他们谁站在谁前面是没有关系的。</p><p>样例说明<br>首先交换身高为3和2的小朋友,再交换身高为3和1的小朋友,再交换身高为2和1的小朋友,每个小朋友的不高兴程度都是3,总和为9。<br>数据规模和约定<br>对于100%的数据,1< =n< =100000,0< =Hi< =1000000。</p><p>输入</p><p>输入的第一行包含一个整数n,表示小朋友的个数。<br>第二行包含 n 个整数 H1 H2 … Hn,分别表示每个小朋友的身高。</p><p>输出</p><p>输出一行,包含一个整数,表示小朋友的不高兴程度和的最小值。</p><p>样例输入</p><pre><code>33 2 1</code></pre><p>样例输出</p><pre><code>9</code></pre></blockquote><h2 id="27"><a href="#27" class="headerlink" title="27"></a>27</h2><blockquote><h4 id="题目-1440-蓝桥杯-2013年第四届真题-带分数"><a href="#题目-1440-蓝桥杯-2013年第四届真题-带分数" class="headerlink" title="题目 1440: [蓝桥杯][2013年第四届真题]带分数"></a>题目 1440: [蓝桥杯][2013年第四届真题]带分数</h4><p>时间限制: 1Sec 内存限制: 128MB 提交: 1390 解决: 796</p><p>题目描述</p><p>100 可以表示为带分数的形式:100 = 3 + 69258 / 714。<br>还可以表示为:100 = 82 + 3546 / 197。<br>注意特征:带分数中,数字1~9分别出现且只出现一次(不包含0)。<br>类似这样的带分数,100 有 11 种表示法。</p><p>输入</p><p>从标准输入读入一个正整数N (N< 1000*1000) </p><p>输出</p><p>程序输出该数字用数码1~9不重复不遗漏地组成带分数表示的全部种数。<br>注意:不要求输出每个表示,只统计有多少表示法! </p><p>样例输入</p><pre><code>100 </code></pre><p>样例输出</p><pre><code>11</code></pre></blockquote><h2 id="28"><a href="#28" class="headerlink" title="28"></a>28</h2><blockquote><h4 id="题目-1441-蓝桥杯-2013年第四届真题-幸运数"><a href="#题目-1441-蓝桥杯-2013年第四届真题-幸运数" class="headerlink" title="题目 1441: [蓝桥杯][2013年第四届真题]幸运数"></a>题目 1441: [蓝桥杯][2013年第四届真题]幸运数</h4><p>时间限制: 1Sec 内存限制: 128MB 提交: 1479 解决: 642</p><p>题目描述</p><p>幸运数是波兰数学家乌拉姆命名的。它采用与生成素数类似的“筛法”生成<br>。<br>首先从1开始写出自然数1,2,3,4,5,6,….<br>1 就是第一个幸运数。<br>我们从2这个数开始。把所有序号能被2整除的项删除,变为:<br>1 _ 3 _ 5 _ 7 _ 9 ….<br>把它们缩紧,重新记序,为:<br>1 3 5 7 9 …. 。这时,3为第2个幸运数,然后把所有能被3整除的序号位置的数删去。注意,是序号位置,不是那个数本身能否被3整除!! 删除的应该是5,11, 17, …<br>此时7为第3个幸运数,然后再删去序号位置能被7整除的(19,39,…)<br>最后剩下的序列类似:<br>1, 3, 7, 9, 13, 15, 21, 25, 31, 33, 37, 43, 49, 51, 63, 67, 69, 73, 75, 79, …</p><p>输入</p><p>输入两个正整数m n, 用空格分开 (m < n < 1000*1000) </p><p>输出</p><p>程序输出 位于m和n之间的幸运数的个数(不包含m和n)。 </p><p>样例输入</p><pre><code>30 69 </code></pre><p>样例输出</p><pre><code>8</code></pre></blockquote><pre><code class="python">s=[int(i) for i in input().split()]m=s[0]n=s[1]L=[i for i in range(n)]def check(i): global L k=L[i] for j in range(len(L)-1,i-1,-1): if j%L[i]==0: L[j]=-1 while -1 in L: L.remove(-1) for j in L: if j>k: if int((len(L)-1)/j)==0: break check(L.index(j)) breakcheck(2)re=0for i in L: if m<i: re+=1print(re)</code></pre><h2 id="29"><a href="#29" class="headerlink" title="29"></a>29</h2><blockquote><h4 id="题目-1442-蓝桥杯-2013年第四届真题-打印十字图"><a href="#题目-1442-蓝桥杯-2013年第四届真题-打印十字图" class="headerlink" title="题目 1442: [蓝桥杯][2013年第四届真题]打印十字图"></a>题目 1442: [蓝桥杯][2013年第四届真题]打印十字图</h4><p>时间限制: 1Sec 内存限制: 128MB 提交: 1056 解决: 739</p><p>题目描述</p><p>历届试题 打印十字图<br>时间限制:1.0s 内存限制:256.0MB</p><p>问题描述<br>小明为某机构设计了一个十字型的徽标(并非红十字会啊),如下所示:</p><pre><code class="cpp">..$$$$$$$$$$$$$....$...........$..$$$.$$$$$$$$$.$$$$...$.......$...$$.$$$.$$$$$.$$$.$$.$...$...$...$.$$.$.$$$.$.$$$.$.$$.$.$...$...$.$.$$.$.$.$$$$$.$.$.$$.$.$...$...$.$.$$.$.$$$.$.$$$.$.$$.$...$...$...$.$$.$$$.$$$$$.$$$.$$...$.......$...$$$$.$$$$$$$$$.$$$..$...........$....$$$$$$$$$$$$$..</code></pre><p>对方同时也需要在电脑dos窗口中以字符的形式输出该标志,并能任意控制层数。</p><p>提示<br>请仔细观察样例,尤其要注意句点的数量和输出位置。 </p><p>输入</p><p>一个正整数 n (n< 30) 表示要求打印图形的层数。 </p><p>输出</p><p>对应包围层数的该标志。</p><p>样例输入</p><pre><code>3 </code></pre></blockquote><h2 id="30"><a href="#30" class="headerlink" title="30"></a>30</h2><blockquote><h4 id="题目-1443-蓝桥杯-历届试题-数字游戏"><a href="#题目-1443-蓝桥杯-历届试题-数字游戏" class="headerlink" title="题目 1443: [蓝桥杯][历届试题]数字游戏"></a>题目 1443: [蓝桥杯][历届试题]数字游戏</h4><p>时间限制: 1Sec 内存限制: 128MB 提交: 9976 解决: 1656</p><p>题目描述</p><p>栋栋正在和同学们玩一个数字游戏。</p><p>游戏的规则是这样的:栋栋和同学们一共n个人围坐在一圈。栋栋首先说出数字1。接下来,坐在栋栋左手边的同学要说下一个数字2。再下面的一个同学要从上一个同学说的数字往下数两个数说出来,也就是说4。下一个同学要往下数三个数,说7。依次类推。</p><p>为了使数字不至于太大,栋栋和同学们约定,当在心中数到 k-1 时,下一个数字从0开始数。例如,当k=13时,栋栋和同学们报出的前几个数依次为:<br>1, 2, 4, 7, 11, 3, 9, 3, 11, 7。</p><p>游戏进行了一会儿,栋栋想知道,到目前为止,他所有说出的数字的总和是多少。</p><p>样例说明<br>栋栋说出的数依次为1, 7, 9,和为17。<br>数据规模和约定<br>1 < n,k,T < 1,000,000;</p><p>输入</p><p>输入的第一行包含三个整数 n,k,T,其中 n 和 k 的意义如上面所述,T 表示到目前为止栋栋一共说出的数字个数。 </p><p>输出</p><p>输出一行,包含一个整数,表示栋栋说出所有数的和。 </p><p>样例输入</p><pre><code>3 13 3</code></pre><p>样例输出</p><pre><code>17</code></pre></blockquote><pre><code class="python">#自己写的错误的n,k,T=map(int,input().split())L=[[] for i in range(n)]#存储数组的数组count=0i=0sum_=1while len(L[0])<T: L[i].append(sum_) count+=1 sum_=(sum_+count)%k i=(i+1)%3print(sum(L[0]))</code></pre><pre><code class="python">#别人写的,找规律n,k,T=map(int,input().split())s=0p=1sum=0for i in range(T): sum=sum+p s=s+n p=(p+s*n-(n-1)*n//2)%kprint(sum)</code></pre><h2 id="31"><a href="#31" class="headerlink" title="31"></a>31</h2><blockquote><h4 id="题目-1462-蓝桥杯-基础练习VIP-Huffuman树"><a href="#题目-1462-蓝桥杯-基础练习VIP-Huffuman树" class="headerlink" title="题目 1462: [蓝桥杯][基础练习VIP]Huffuman树"></a>题目 1462: [蓝桥杯][基础练习VIP]Huffuman树</h4><p>时间限制: 1Sec 内存限制: 128MB 提交: 2005 解决: 1326</p><p>题目描述</p><p>Huffman树在编码中有着广泛的应用。在这里,我们只关心Huffman树的构造过程。</p><p>给出一列数{pi}={p0, p1, …, pn-1},用这列数构造Huffman树的过程如下:</p><p>\1. 找到{pi}中最小的两个数,设为pa和pb,将pa和pb从{pi}中删除掉,然后将它们的和加入到{pi}中。这个过程的费用记为pa + pb。</p><p>\2. 重复步骤1,直到{pi}中只剩下一个数。</p><p>在上面的操作过程中,把所有的费用相加,就得到了构造Huffman树的总费用。</p><p>本题任务:对于给定的一个数列,现在请你求出用该数列构造Huffman树的总费用。</p><p>例如,对于数列{pi}={5, 3, 8, 2, 9},Huffman树的构造过程如下:</p><p>\1. 找到{5, 3, 8, 2, 9}中最小的两个数,分别是2和3,从{pi}中删除它们并将和5加入,得到{5, 8, 9, 5},费用为5。</p><p>\2. 找到{5, 8, 9, 5}中最小的两个数,分别是5和5,从{pi}中删除它们并将和10加入,得到{8, 9, 10},费用为10。</p><p>\3. 找到{8, 9, 10}中最小的两个数,分别是8和9,从{pi}中删除它们并将和17加入,得到{10, 17},费用为17。</p><p>\4. 找到{10, 17}中最小的两个数,分别是10和17,从{pi}中删除它们并将和27加入,得到{27},费用为27。</p><p>\5. 现在,数列中只剩下一个数27,构造过程结束,总费用为5+10+17+27=59。</p><p>输入</p><p>输入的第一行包含一个正整数n(n< =100)。 </p><p>接下来是n个正整数,表示p0, p1, …, pn-1,每个数不超过1000。 </p><p>输出</p><p>输出用这些数构造Huffman树的总费用。 </p><p>样例输入</p><pre><code>5 5 3 8 2 9</code></pre><p>样例输出</p><pre><code>59</code></pre></blockquote><pre><code class="python">n=int(input())L=list(map(int,input().split()))sum=0while len(L)!=1: a1=min(L) L.remove(a1) a2=min(L) sum+=(a1+a2) L[L.index(a2)]=a1+a2print(sum)</code></pre><h2 id="32"><a href="#32" class="headerlink" title="32"></a>32</h2><blockquote><h4 id="题目-1463-蓝桥杯-基础练习VIP-Sine之舞"><a href="#题目-1463-蓝桥杯-基础练习VIP-Sine之舞" class="headerlink" title="题目 1463: [蓝桥杯][基础练习VIP]Sine之舞"></a>题目 1463: [蓝桥杯][基础练习VIP]Sine之舞</h4><p>时间限制: 1Sec 内存限制: 128MB 提交: 2261 解决: 1374</p><p>题目描述</p><p>最近FJ为他的奶牛们开设了数学分析课,FJ知道若要学好这门课,必须有一个好的三角函数基本功。所以他准备和奶牛们做一个“Sine之舞”的游戏,寓教于乐,提高奶牛们的计算能力。<br>不妨设<br>An=sin(1–sin(2+sin(3–sin(4+…sin(n))…)<br>Sn=(…(A1+n)A2+n-1)A3+…+2)An+1<br>FJ想让奶牛们计算Sn的值,请你帮助FJ打印出Sn的完整表达式,以方便奶牛们做题。</p><p>输入</p><p>仅有一个数:N<201。</p><p>输出</p><p>请输出相应的表达式Sn,以一个换行符结束。输出中不得含有多余的空格或换行、回车符。</p><p>样例输入</p><pre><code>3</code></pre><p>样例输出</p><pre><code>((sin(1)+3)sin(1-sin(2))+2)sin(1-sin(2+sin(3)))+1</code></pre></blockquote><pre><code class="python">n=int(input())def an(n): for i in range(1,n+1): print('sin',end='') print('(',end='') print(i,end='') if i !=n:#注意这里 if i%2: print('-',end='') else: print('+',end='') for i in range(n): print(')',end='') return ''def sn(n): for i in range(n-1): print('(',end='') for i in range(1,n+1): print(an(i),end='') print('+',end='') print(n-i+1,end='') if i!=n: print(')',end='')sn(n)</code></pre><h2 id="33"><a href="#33" class="headerlink" title="33"></a>33</h2><blockquote><h4 id="题目-1464-蓝桥杯-基础练习VIP-分解质因数"><a href="#题目-1464-蓝桥杯-基础练习VIP-分解质因数" class="headerlink" title="题目 1464: [蓝桥杯][基础练习VIP]分解质因数"></a>题目 1464: [蓝桥杯][基础练习VIP]分解质因数</h4><p>时间限制: 1Sec 内存限制: 128MB 提交: 3039 解决: 1819</p><p>题目描述</p><p>求出区间[a,b]中所有整数的质因数分解。</p><p>提示</p><p>先筛出所有素数,然后再分解。</p><p>数据规模和约定</p><p>输入</p><p>输入两个整数a,b。 </p><p>2< =a< =b< =10000</p><p>输出</p><p>每行输出一个数的分解,形如k=a1<em>a2</em>a3…(a1< =a2< =a3…,k也是从小到大的)(具体可看样例) </p><p>样例输入</p><pre><code>3 10</code></pre><p>样例输出</p><pre><code>3=34=2*25=56=2*37=78=2*2*29=3*310=2*5</code></pre></blockquote><pre><code class="python">def fun2(i): l1=[] while True: for j in range(2,i+1): flag=True if i%j==0: l1.append(str(j)) i=i//j break if i==1: break s='*'.join(l1)#注意这种用法 return sdef fun(i): if i in l: return i else: return fun2(i)n,m=map(int,input().split())l=[]for i in range(n ,m+1): flag=True for j in range(2,i): if i%j!=0: flag=False break if flag: l.append(i)for i in range(n,m+1): print("&#123;&#125;=&#123;&#125;".format(i,fun(i)))</code></pre><p>注意join的使用</p><p>注意先排除之间的指数</p><p>注意数的变化</p><h2 id="34"><a href="#34" class="headerlink" title="34"></a>34</h2><blockquote><h4 id="题目-1465-蓝桥杯-基础练习VIP-回形取数"><a href="#题目-1465-蓝桥杯-基础练习VIP-回形取数" class="headerlink" title="题目 1465: [蓝桥杯][基础练习VIP]回形取数"></a>题目 1465: [蓝桥杯][基础练习VIP]回形取数</h4><p>时间限制: 1Sec 内存限制: 128MB 提交: 2916 解决: 939</p><p>题目描述</p><p>回形取数就是沿矩阵的边取数,若当前方向上无数可取或已经取过,则左转90度。一开始位于矩阵左上角,方向向下。</p><p>输入</p><p>输入第一行是两个不超过200的正整数m, n,表示矩阵的行和列。接下来m行每行n个整数,表示这个矩阵。</p><p>输出</p><p>输出只有一行,共mn个数,为输入矩阵回形取数得到的结果。数之间用一个空格分隔,行末不要有多余的空格。</p><p>样例输入</p><pre><code>3 31 2 34 5 67 8 9</code></pre><p>样例输出</p><pre><code>1 4 7 8 9 6 3 2 5</code></pre></blockquote><pre><code class="python">#这时间超限了n,m=map(int,input().split())#m行,n列L=[]for i in range(m): l=list(map(int ,input().split())) L.append(l)count=0x=0while count!=n*m: for i in range(x,m-x): if L[i][x]: print(L[i][x],end=' ') L[i][x]=0 count+=1 else: break for j in range(x+1,n-x): if L[m-x-1][j]: print(L[m-x-1][j],end=' ') L[m-x-1][j]=0 count+=1 else: break for k in range(m-x-2,x-1,-1): if L[k][n-x-1]: print(L[k][n-x-1],end=' ') L[k][n - x - 1]=0 count+=1 else: break for t in range(n-x-2,x,-1): if L[x][t]: print(L[x][t],end=' ') L[x][t]=0 count+=1 else: break x+=1</code></pre><p>以下是完美的题解</p><pre><code class="python">m,n = map(int,input().split())mapL = [list(map(int,input().split())) for _ in range(m)]i,j = 0,0 #i表示行,j表示列flag = "D" #从向下走开始result = [] #存结果while True: if i<0 or j<0 or i>=m or j>=n or mapL[i][j] == -1: #“i<0 or j<0 or i>=m or j>=n”这一段要加,不然一些单行,单列(n=1 or m=1)的用例通不过 break result.append(mapL[i][j]) mapL[i][j] = -1 if flag == "D": i += 1 elif flag == "R": j += 1 elif flag == "U": i -= 1 elif flag == "L": j -= 1 if flag == "D" and (i>=m or mapL[i][j]==-1): flag = "R" i -= 1 j += 1 elif flag == "R" and (j>=n or mapL[i][j]==-1): flag = "U" j -= 1 i -= 1 elif flag == "U" and (i<0 or mapL[i][j] == -1): flag = "L" i += 1 j -= 1 elif flag == "L" and (j<0 or mapL[i][j] == -1): flag = "D" j += 1 i += 1for i in range(len(result)): if i == len(result) -1: print(result[i]) else: print(result[i],end=" ")</code></pre><h2 id="35"><a href="#35" class="headerlink" title="35"></a>35</h2><blockquote><h4 id="题目-1466-蓝桥杯-基础练习VIP-字符串对比"><a href="#题目-1466-蓝桥杯-基础练习VIP-字符串对比" class="headerlink" title="题目 1466: [蓝桥杯][基础练习VIP]字符串对比"></a>题目 1466: [蓝桥杯][基础练习VIP]字符串对比</h4><p>时间限制: 1Sec 内存限制: 512MB 提交: 5542 解决: 3212</p><p>题目描述</p><p>给定两个仅由大写字母或小写字母组成的字符串(长度介于1到10之间),它们之间的关系是以下4中情况之一:</p><p>1:两个字符串长度不等。比如 Beijing 和 Hebei</p><p>2:两个字符串不仅长度相等,而且相应位置上的字符完全一致(区分大小写),比如 Beijing 和 Beijing</p><p>3:两个字符串长度相等,相应位置上的字符仅在不区分大小写的前提下才能达到完全一致(也就是说,它并不满足情况2)。比如 beijing 和 BEIjing</p><p>4:两个字符串长度相等,但是即使是不区分大小写也不能使这两个字符串一致。比如 Beijing 和 Nanjing</p><p>编程判断输入的两个字符串之间的关系属于这四类中的哪一类,给出所属的类的编号。</p><p>输入</p><p>包括两行,每行都是一个字符串 </p><p>输出</p><p>仅有一个数字,表明这两个字符串的关系编号 </p><p>样例输入</p><pre><code>BEIjingbeiJing</code></pre><p>样例输出</p><pre><code>3</code></pre></blockquote><pre><code class="python">s1=input()s2=input()if len(s1)!=len(s2): print(1)elif s1!=s2: if s1.lower()==s2.lower(): print(3) else: print(4)elif s1==s2: print(2)</code></pre><h2 id="36"><a href="#36" class="headerlink" title="36"></a>36</h2><blockquote><h4 id="题目-1467-蓝桥杯-基础练习VIP-完美的代价"><a href="#题目-1467-蓝桥杯-基础练习VIP-完美的代价" class="headerlink" title="题目 1467: [蓝桥杯][基础练习VIP]完美的代价"></a>题目 1467: [蓝桥杯][基础练习VIP]完美的代价</h4><p>时间限制: 1Sec 内存限制: 128MB 提交: 2465 解决: 748</p><p>题目描述</p><p>回文串,是一种特殊的字符串,它从左往右读和从右往左读是一样的。小龙龙认为回文串才是完美的。现在给你一个串,它不一定是回文的,请你计算最少的交换次数使得该串变成一个完美的回文串。</p><p>交换的定义是:交换两个相邻的字符</p><p>例如mamad</p><p>第一次交换 ad : mamda</p><p>第二次交换 md : madma</p><p>第三次交换 ma : madam (回文!完美!)</p><p>输入</p><p>第一行是一个整数N,表示接下来的字符串的长度(N < = 8000) </p><p>第二行是一个字符串,长度为N.只包含小写字母 </p><p>输出</p><p>如果可能,输出最少的交换次数。 </p><p>否则输出Impossible </p><p>样例输入</p><pre><code>5 mamad </code></pre><p>样例输出</p><pre><code>3</code></pre></blockquote><pre><code class="python">n=int(input())s=input()L=len(s)s=list(s)alpha=[0 for i in range(26)]#判断是否能成为回文for i in range(5): alpha[ord(s[i])-ord('a')]+=1#转换ascii马count=0for i in alpha: if i%2: count+=1if count>1: print("Impossible")else: number=0 for i in range(L//2): for j in range(L-(i+1),i,-1): if(s[i]==s[j]): for j2 in range (j,L-(i+1)): character=s[j2] s[j2]=s[j2+1] s[j2+1]=character number+=L-(i+1)-j if(s[L-(i+1)]==s[L-(j+1)]): for j2 in range(L-(j+1),i,-1): a=s[j2] s[j2]=s[j2-1] s[j2-1]=a number+=L-(j+1)-i print(number) #自己写的有问题的</code></pre><h2 id="37"><a href="#37" class="headerlink" title="37"></a>37</h2><blockquote><h4 id="题目-1468-蓝桥杯-基础练习VIP-报时助手"><a href="#题目-1468-蓝桥杯-基础练习VIP-报时助手" class="headerlink" title="题目 1468: [蓝桥杯][基础练习VIP]报时助手"></a>题目 1468: [蓝桥杯][基础练习VIP]报时助手</h4><p>时间限制: 1Sec 内存限制: 128MB 提交: 3230 解决: 1229</p><p>题目描述</p><p>给定当前的时间,请用英文的读法将它读出来。</p><p>时间用时h和分m表示,在英文的读法中,读一个时间的方法是:</p><p>如果m为0,则将时读出来,然后加上“o’clock”,如3:00读作“three o’clock”。</p><p>如果m不为0,则将时读出来,然后将分读出来,如5:30读作“five thirty”。</p><p>时和分的读法使用的是英文数字的读法,其中0~20读作:</p><p>0:zero, 1: one, 2:two, 3:three, 4:four, 5:five, 6:six, 7:seven, 8:eight, 9:nine, 10:ten, 11:eleven, 12:twelve, 13:thirteen, 14:fourteen, 15:fifteen, 16:sixteen, 17:seventeen, 18:eighteen, 19:nineteen, 20:twenty。</p><p>30读作thirty,40读作forty,50读作fifty。</p><p>对于大于20小于60的数字,首先读整十的数,然后再加上个位数。如31首先读30再加1的读法,读作“thirty one”。</p><p>按上面的规则21:54读作“twenty one fifty four”,9:07读作“nine seven”,0:15读作“zero fifteen”。</p><p>输入</p><p>输入包含两个非负整数h和m,表示时间的时和分。非零的数字前没有前导0。h小于24,m小于60。 </p><p>输出</p><p>输出时间时刻的英文。 </p><p>样例输入</p><pre><code>0 15 </code></pre><p>样例输出</p><pre><code>zero fifteen</code></pre></blockquote><h2 id="38"><a href="#38" class="headerlink" title="38"></a>38</h2><blockquote><h4 id="题目-1471-蓝桥杯-基础练习VIP-矩形面积交"><a href="#题目-1471-蓝桥杯-基础练习VIP-矩形面积交" class="headerlink" title="题目 1471: [蓝桥杯][基础练习VIP]矩形面积交"></a>题目 1471: [蓝桥杯][基础练习VIP]矩形面积交</h4><p>时间限制: 1Sec 内存限制: 128MB 提交: 5912 解决: 1717</p><p>题目描述</p><p>平面上有两个矩形,它们的边平行于直角坐标系的X轴或Y轴。对于每个矩形,我们给出它的一对相对顶点的坐标,请你编程算出两个矩形的交的面积。</p><p>输入</p><p>输入仅包含两行,每行描述一个矩形。 </p><p>在每行中,给出矩形的一对相对顶点的坐标,每个点的坐标都用两个绝对值不超过10^7的实数表示。</p><p>输出</p><p>输出仅包含一个实数,为交的面积,保留到小数后两位。 </p><p>样例输入</p><pre><code>1 1 3 3 2 2 4 4 </code></pre><p>样例输出</p><pre><code>1.00</code></pre></blockquote><pre><code class="python">#38的错误答案L1=list(map(float,input().split()))L2=list(map(float,input().split()))x1,y1=(L1[0]+L1[2])/2,(L1[1]+L1[3])/2x2,y2=(L2[0]+L2[2])/2,(L2[1]+L2[3])/2w1,h1=x1-L1[0],y1-L1[1]w2,h2=x2-L2[0],y2-L2[1]if w1+w2>abs(x1-x2) and h1+h2>abs(y1-y2): w=(w1+w2)-abs(x1-x2) h=(h1+h2)-abs(y1-y2) print("%.2f"%(w*h))else:print(0)</code></pre><pre><code class="python">xy1 = list(map(float,input().split()))xy2 = list(map(float,input().split()))rx = min(max(xy1[0],xy1[2]),max(xy2[0],xy2[2]))lx = max(min(xy1[0],xy1[2]),min(xy2[0],xy2[2]))uy = min(max(xy1[1],xy1[3]),max(xy2[1],xy2[3]))dy = max(min(xy1[1],xy1[3]),min(xy2[1],xy2[3]))w,h = rx-lx,uy-dyif w<=0.0 or h<=0.00: print("0.00")else: #print((str(w*h)+"00").split(".")[0]+"."+(str(w*h)+"00").split(".")[1][:2:]) 不进位输出小数点后两位 print("%.2f"%(w*h))</code></pre><h2 id="39"><a href="#39" class="headerlink" title="39"></a>39</h2><blockquote><h4 id="题目-1472-蓝桥杯-基础练习VIP-矩阵乘法"><a href="#题目-1472-蓝桥杯-基础练习VIP-矩阵乘法" class="headerlink" title="题目 1472: [蓝桥杯][基础练习VIP]矩阵乘法"></a>题目 1472: [蓝桥杯][基础练习VIP]矩阵乘法</h4><p>时间限制: 1Sec 内存限制: 128MB 提交: 2655 解决: 791</p><p>题目描述</p><p>给定一个N阶矩阵A,输出A的M次幂(M是非负整数)</p><p>例如:</p><p>A =</p><p>1 2</p><p>3 4</p><p>A的2次幂</p><p>7 10</p><p>15 22</p><p>输入</p><p>第一行是一个正整数N、M(1< =N< =30, 0< =M< =5),表示矩阵A的阶数和要求的幂数 </p><p>接下来N行,每行N个绝对值不超过10的非负整数,描述矩阵A的值 </p><p>输出</p><p>输出共N行,每行N个整数,表示A的M次幂所对应的矩阵。相邻的数之间用一个空格隔开 </p><p>样例输入</p><pre><code>2 2 1 2 3 4 </code></pre><p>样例输出</p><pre><code>7 1015 22</code></pre></blockquote><pre><code class="python">#输入方阵的大小(n*n) 和幂mn,m=map(int,input().split())# 输入数据生成矩阵matrix=[]for _ in range(n): matrix.append(list(map(int,input().split())))#矩阵matrix_a和矩阵matrix_b相乘得到matrix_resultdef multi(matrix_a,matrix_b): #对于a*b和b*c的矩阵,得到的规模是a*c matrix_result=[[0 for _ in range(len(matrix_b[0]))] for _ in range(len(matrix_a))] for i in range(len(matrix_a)): for j in range(len(matrix_b[0])): #这里len(matrix_b)也可以换成len(matrix_a[0]) for k in range(len(matrix_b)): matrix_result[i][j]+=matrix_a[i][k]*matrix_b[k][j] return matrix_result# 求和matrix规模相同的单位矩阵Edef unit_1(n): #print('unit进来了') #初始化为0 E=[[0 for _ in range(n)]for _ in range(n)] #对角线为1 for i in range(n): E[i][i]=1 #print(E) return E#矩阵快速幂def quick_multi(matrix,m): #print('quick进来') res=unit_1(len(matrix)) while m: if m&1: res=multi(res,matrix) matrix=multi(matrix,matrix) m=m>>1 #print('quick结束') return res#输出for r in quick_multi(matrix,m): print(' '.join([str(i) for i in r]))</code></pre><p><a href="https://blog.dotcpp.com/a/77575">抄的题解的出处</a></p><h2 id="40"><a href="#40" class="headerlink" title="40"></a>40</h2><blockquote><h4 id="题目-1447-蓝桥杯-2013年第四届真题-格子刷油漆"><a href="#题目-1447-蓝桥杯-2013年第四届真题-格子刷油漆" class="headerlink" title="题目 1447: [蓝桥杯][2013年第四届真题]格子刷油漆"></a>题目 1447: [蓝桥杯][2013年第四届真题]格子刷油漆</h4><p>时间限制: 1Sec 内存限制: 128MB 提交: 684 解决: 174</p><p>题目描述</p><p>X国的一段古城墙的顶端可以看成 2*N个格子组成的矩形(如下图所示),现需要把这些格子刷上保护漆。</p><p><img src="https://www.dotcpp.com/oj/upload/image/20180421/20180421182053_36275.jpg" alt="img"><br>你可以从任意一个格子刷起,刷完一格,可以移动到和它相邻的格子(对角相邻也算数),但不能移动到较远的格子(因为油漆未干不能踩!)<br>比如:a d b c e f 就是合格的刷漆顺序。<br>c e f d a b 是另一种合适的方案。<br>当已知 N 时,求总的方案数。当N较大时,结果会迅速增大,请把结果对 1000000007 (十亿零七) 取模。</p><p>输入</p><p>输入数据为一个正整数(不大于1000) </p><p>输出</p><p>输出数据为一个正整数。</p><p>样例输入</p><pre><code>3 </code></pre><p>样例输出</p><pre><code>96</code></pre></blockquote><h2 id="41"><a href="#41" class="headerlink" title="41"></a>41</h2><blockquote><p>观察这个数列:<br>1 3 0 2 -1 1 -2 …</p><p>这个数列中后一项总是比前一项增加2或者减少3。</p><p>栋栋对这种数列很好奇,他想知道长度为 n 和为 s 而且后一项总是比前一项增加a或者减少b的整数数列可能有多少种呢?</p><p>样例说明<br>这两个数列分别是2 4 1 3和7 4 1 -2。</p><p>输入</p><p>输入的第一行包含四个整数 n s a b,含义如前面说述。 </p><p>数据规模和约定<br>对于100%的数据,1< =n< =1000,-1,000,000,000< =s< =1,000,000,000,1< =a, b< =1,000,000。</p><p>输出</p><p>输出一行,包含一个整数,表示满足条件的方案数。由于这个数很大,请输出方案数除以100000007的余数。 </p><p>样例输入</p><pre><code>4 10 2 3</code></pre><p>样例输出</p><pre><code>2</code></pre></blockquote><h2 id="42"><a href="#42" class="headerlink" title="42"></a>42</h2><blockquote><h4 id="题目-1452-蓝桥杯-历届试题-网络寻路"><a href="#题目-1452-蓝桥杯-历届试题-网络寻路" class="headerlink" title="题目 1452: [蓝桥杯][历届试题]网络寻路"></a>题目 1452: [蓝桥杯][历届试题]网络寻路</h4><p>时间限制: 1Sec 内存限制: 128MB 提交: 610 解决: 248</p><p>题目描述</p><p>X 国的一个网络使用若干条线路连接若干个节点。节点间的通信是双向的。某重要数据包,为了安全起见,必须恰好被转发两次到达目的地。该包可能在任意一个节点产生,我们需要知道该网络中一共有多少种不同的转发路径。<br>源地址和目标地址可以相同,但中间节点必须不同。<br>如下图所示的网络。</p><p>1 -> 2 -> 3 -> 1 是允许的<br>1 -> 2 -> 1 -> 2 或者 1 -> 2 -> 3 -> 2 都是非法的。</p><p>输入</p><p>输入数据的第一行为两个整数N M,分别表示节点个数和连接线路的条数(1< =N< =10000; 0< =M< =100000)。<br>接下去有M行,每行为两个整数 u 和 v,表示节点u 和 v 联通(1< =u,v< =N , u!=v)。<br>输入数据保证任意两点最多只有一条边连接,并且没有自己连自己的边,即不存在重边和自环。 </p><p>输出</p><p>输出一个整数,表示满足要求的路径条数。</p><p>样例输入</p><pre><code>4 41 22 33 11 4</code></pre><p>样例输出</p><pre><code>10</code></pre></blockquote><h2 id="43"><a href="#43" class="headerlink" title="43"></a>43</h2><blockquote><h4 id="题目-1450-蓝桥杯-2014年第五届真题-矩阵翻硬币"><a href="#题目-1450-蓝桥杯-2014年第五届真题-矩阵翻硬币" class="headerlink" title="题目 1450: [蓝桥杯][2014年第五届真题]矩阵翻硬币"></a>题目 1450: [蓝桥杯][2014年第五届真题]矩阵翻硬币</h4><p>时间限制: 1Sec 内存限制: 128MB 提交: 328 解决: 74</p><p>题目描述</p><p>小明先把硬币摆成了一个 n 行 m 列的矩阵。</p><p>随后,小明对每一个硬币分别进行一次 Q 操作。</p><p>对第x行第y列的硬币进行 Q 操作的定义:将所有第 i<em>x 行,第 j</em>y 列的硬币进行翻转。</p><p>其中i和j为任意使操作可行的正整数,行号和列号都是从1开始。</p><p>当小明对所有硬币都进行了一次 Q 操作后,他发现了一个奇迹——所有硬币均为正面朝上。</p><p>小明想知道最开始有多少枚硬币是反面朝上的。于是,他向他的好朋友小M寻求帮助。</p><p>聪明的小M告诉小明,只需要对所有硬币再进行一次Q操作,即可恢复到最开始的状态。然而小明很懒,不愿意照做。于是小明希望你给出他更好的方法。帮他计算出答案。</p><p>输入</p><p>输入数据包含一行,两个正整数 n m,含义见题目描述。 </p><p>数据规模和约定<br>对于100%的数据,n、m < = 10^1000(10的1000次方)。</p><p>输出</p><p>输出一个正整数,表示最开始有多少枚硬币是反面朝上的。 </p><p>样例输入</p><pre><code>2 3</code></pre><p>样例输出</p><pre><code>1</code></pre></blockquote><h2 id="44"><a href="#44" class="headerlink" title="44"></a>44</h2><blockquote><h4 id="题目-1453-蓝桥杯-历届试题-翻硬币"><a href="#题目-1453-蓝桥杯-历届试题-翻硬币" class="headerlink" title="题目 1453: [蓝桥杯][历届试题]翻硬币"></a>题目 1453: [蓝桥杯][历届试题]翻硬币</h4><p>时间限制: 1Sec 内存限制: 128MB 提交: 2301 解决: 1242</p><p>题目描述</p><p>小明正在玩一个“翻硬币”的游戏。</p><p>桌上放着排成一排的若干硬币。我们用 * 表示正面,用 o 表示反面(是小写字母,不是零)。</p><p>比如,可能情形是:*<em>oo**</em>oooo</p><p>如果同时翻转左边的两个硬币,则变为:oooo***oooo</p><p>现在小明的问题是:如果已知了初始状态和要达到的目标状态,每次只能同时翻转相邻的两个硬币,那么对特定的局面,最少要翻动多少次呢?</p><p>我们约定:把翻动相邻的两个硬币叫做一步操作。</p><p>输入</p><p>两行等长的字符串,分别表示初始状态和要达到的目标状态。每行的长度< 1000 </p><p>输出</p><p>一个整数,表示最小操作步数。 </p><p>样例输入</p><pre><code>*o**o***o*** *o***o**o*** </code></pre><p>样例输出</p><pre><code>1</code></pre></blockquote><h2 id="45"><a href="#45" class="headerlink" title="45"></a>45</h2><blockquote><h4 id="题目-1454-蓝桥杯-历届试题-蚂蚁感冒"><a href="#题目-1454-蓝桥杯-历届试题-蚂蚁感冒" class="headerlink" title="题目 1454: [蓝桥杯][历届试题]蚂蚁感冒"></a>题目 1454: [蓝桥杯][历届试题]蚂蚁感冒</h4><p>时间限制: 1Sec 内存限制: 128MB 提交: 3449 解决: 1539</p><p>题目描述</p><p>长100厘米的细长直杆子上有n只蚂蚁。它们的头有的朝左,有的朝右。</p><p>每只蚂蚁都只能沿着杆子向前爬,速度是1厘米/秒。</p><p>当两只蚂蚁碰面时,它们会同时掉头往相反的方向爬行。</p><p>这些蚂蚁中,有1只蚂蚁感冒了。并且在和其它蚂蚁碰面时,会把感冒传染给碰到的蚂蚁。</p><p>请你计算,当所有蚂蚁都爬离杆子时,有多少只蚂蚁患上了感冒。</p><p>输入</p><p>第一行输入一个整数n (1 < n < 50), 表示蚂蚁的总数。 </p><p>接着的一行是n个用空格分开的整数 Xi (-100 < Xi < 100), Xi的绝对值,表示蚂蚁离开杆子左边端点的距离。正值表示头朝右,负值表示头朝左,数据中不会出现0值,也不会出现两只蚂蚁占用同一位置。其中,第一个数 据代表的蚂蚁感冒了。</p><p>输出</p><p>要求输出1个整数,表示最后感冒蚂蚁的数目。 </p><p>样例输入</p><pre><code>5-10 8 -20 12 25</code></pre><p>样例输出</p><pre><code>3</code></pre></blockquote><h2 id="46"><a href="#46" class="headerlink" title="46"></a>46</h2><blockquote><h4 id="题目-1456-蓝桥杯-历届试题-连号区间数"><a href="#题目-1456-蓝桥杯-历届试题-连号区间数" class="headerlink" title="题目 1456: [蓝桥杯][历届试题]连号区间数"></a>题目 1456: [蓝桥杯][历届试题]连号区间数</h4><p>时间限制: 1Sec 内存限制: 128MB 提交: 1001 解决: 515</p><p>题目描述</p><p>小明这些天一直在思考这样一个奇怪而有趣的问题:<br>在1~N的某个全排列中有多少个连号区间呢?这里所说的连号区间的定义是:<br>如果区间[L, R] 里的所有元素(即此排列的第L个到第R个元素)递增排序后能得到一个长度为R-L+1的“连续”数列,则称这个区间连号区间。<br>当N很小的时候,小明可以很快地算出答案,但是当N变大的时候,问题就不是那么简单了,现在小明需要你的帮助。</p><p>输入</p><p>第一行是一个正整数N (1 < = N < = 50000), 表示全排列的规模。<br>第二行是N个不同的数字Pi(1 < = Pi < = N), 表示这N个数字的某一全排列。</p><p>输出</p><p>输出一个整数,表示不同连号区间的数目。</p><p>样例输入</p><pre><code>53 4 2 5 1</code></pre><p>样例输出</p><pre><code>9</code></pre></blockquote><h2 id="46-1"><a href="#46-1" class="headerlink" title="46"></a>46</h2><blockquote><h4 id="题目-1457-蓝桥杯-历届试题-邮局"><a href="#题目-1457-蓝桥杯-历届试题-邮局" class="headerlink" title="题目 1457: [蓝桥杯][历届试题]邮局"></a>题目 1457: [蓝桥杯][历届试题]邮局</h4><p>时间限制: 1Sec 内存限制: 128MB 提交: 461 解决: 98</p><p>题目描述</p><p>C村住着n户村民,由于交通闭塞,C村的村民只能通过信件与外界交流。为了方便村民们发信,C村打算在C村建设k个邮局,这样每户村民可以去离自己家最近的邮局发信。</p><p>现在给出了m个备选的邮局,请从中选出k个来,使得村民到自己家最近的邮局的距离和最小。其中两点之间的距离定义为两点之间的直线距离。</p><p>输入</p><p>输入的第一行包含三个整数n, m, k,分别表示村民的户数、备选的邮局数和要建的邮局数。<br>接下来n行,每行两个整数x, y,依次表示每户村民家的坐标。<br>接下来m行,每行包含两个整数x, y,依次表示每个备选邮局的坐标。 </p><p>在输入中,村民和村民、村民和邮局、邮局和邮局的坐标可能相同,但你应把它们看成不同的村民或邮局。</p><p>数据规模和约定<br>对于100%的数据,1< =n< =50,1< =m< =25,1< =k< =10。</p><p>输出</p><p>输出一行,包含k个整数,从小到大依次表示你选择的备选邮局编号。(备选邮局按输入顺序由1到m编号)</p><p>样例输入</p><pre><code>5 4 20 02 03 13 31 10 11 02 13 2</code></pre><p>样例输出</p><pre><code>2 4</code></pre></blockquote><h2 id="47"><a href="#47" class="headerlink" title="47"></a>47</h2><blockquote><h4 id="题目-1458-蓝桥杯-2013年第四届真题-错误票据"><a href="#题目-1458-蓝桥杯-2013年第四届真题-错误票据" class="headerlink" title="题目 1458: [蓝桥杯][2013年第四届真题]错误票据"></a>题目 1458: [蓝桥杯][2013年第四届真题]错误票据</h4><p>时间限制: 1Sec 内存限制: 128MB 提交: 5332 解决: 1840</p><p>题目描述</p><p>某涉密单位下发了某种票据,并要在年终全部收回。<br>每张票据有唯一的ID号。全年所有票据的ID号是连续的,但ID的开始数码是随机选定的。<br>因为工作人员疏忽,在录入ID号的时候发生了一处错误,造成了某个ID断号,另外一个ID重号。<br>你的任务是通过编程,找出断号的ID和重号的ID。<br>假设断号不可能发生在最大和最小号。</p><p>输入</p><p>要求程序首先输入一个整数N(N< 100)表示后面数据行数。<br>接着读入N行数据。<br>每行数据长度不等,是用空格分开的若干个(不大于100个)正整数(不大于100000),请注意行内和行末可能有多余的空格,你的程序需要能处理这些空格。<br>每个整数代表一个ID号。 </p><p>输出</p><p>要求程序输出1行,含两个整数m n,用空格分隔。<br>其中,m表示断号ID,n表示重号ID </p><p>样例输入</p><pre><code>25 6 8 11 910 12 9</code></pre><p>样例输出</p><pre><code>7 9</code></pre></blockquote><h2 id="48"><a href="#48" class="headerlink" title="48"></a>48</h2><blockquote><h4 id="题目-1459-蓝桥杯-2013年第四届真题-高僧斗法"><a href="#题目-1459-蓝桥杯-2013年第四届真题-高僧斗法" class="headerlink" title="题目 1459: [蓝桥杯][2013年第四届真题]高僧斗法"></a>题目 1459: [蓝桥杯][2013年第四届真题]高僧斗法</h4><p>时间限制: 1Sec 内存限制: 128MB 提交: 446 解决: 104</p><p>题目描述</p><p>古时丧葬活动中经常请高僧做法事。仪式结束后,有时会有“高僧斗法”的趣味节目,以舒缓压抑的气氛。<br>节目大略步骤为:先用粮食(一般是稻米)在地上“画”出若干级台阶(表示N级浮屠)。又有若干小和尚随机地“站”在某个台阶上。最高一级台阶必须站人,其它任意。(如图1所示)<br>两位参加游戏的法师分别指挥某个小和尚向上走任意多级的台阶,但会被站在高级台阶上的小和尚阻挡,不能越过。两个小和尚也不能站在同一台阶,也不能向低级台阶移动。<br>两法师轮流发出指令,最后所有小和尚必然会都挤在高段台阶,再也不能向上移动。轮到哪个法师指挥时无法继续移动,则游戏结束,该法师认输。<br>对于已知的台阶数和小和尚的分布位置,请你计算先发指令的法师该如何决策才能保证胜出。</p><p>输入</p><p>输入数据为一行用空格分开的N个整数,表示小和尚的位置。台阶序号从1算起,所以最后一个小和尚的位置即是台阶的总数。(N< 100, 台阶总数< 1000)</p><p>输出</p><p>输出为一行用空格分开的两个整数: A B, 表示把A位置的小和尚移动到B位置。若有多个解,输出A值较小的解,若无解则输出-1。 </p><p>样例输入</p><pre><code>1 5 9</code></pre><p>样例输出</p><pre><code>1 4</code></pre></blockquote><h2 id="49"><a href="#49" class="headerlink" title="49"></a>49</h2><blockquote><h4 id="题目-1460-蓝桥杯-基础练习VIP-2n皇后问题"><a href="#题目-1460-蓝桥杯-基础练习VIP-2n皇后问题" class="headerlink" title="题目 1460: [蓝桥杯][基础练习VIP]2n皇后问题"></a>题目 1460: [蓝桥杯][基础练习VIP]2n皇后问题</h4><p>时间限制: 1Sec 内存限制: 128MB 提交: 1667 解决: 841</p><p>题目描述</p><p>给定一个n*n的棋盘,棋盘中有一些位置不能放皇后。现在要向棋盘中放入n个黑皇后和n个白皇后,使任意的两个黑皇后都不在同一行、同一列或同一条对角线上,任意的两个白皇后都不在同一行、同一列或同一条对角线上。问总共有多少种放法?n小于等于8。</p><p>输入</p><p>输入的第一行为一个整数n,表示棋盘的大小。 n小于等于8</p><p>接下来n行,每行n个0或1的整数,如果一个整数为1,表示对应的位置可以放皇后,如果一个整数为0,表示对应的位置不可以放皇后。 </p><p>输出</p><p>输出一个整数,表示总共有多少种放法。 </p><p>样例输入</p><pre><code>41 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 </code></pre><p>样例输出</p><pre><code>2</code></pre></blockquote><h2 id="50"><a href="#50" class="headerlink" title="50"></a>50</h2><blockquote><h4 id="题目-1461-蓝桥杯-基础练习VIP-FJ的字符串"><a href="#题目-1461-蓝桥杯-基础练习VIP-FJ的字符串" class="headerlink" title="题目 1461: [蓝桥杯][基础练习VIP]FJ的字符串"></a>题目 1461: [蓝桥杯][基础练习VIP]FJ的字符串</h4><p>时间限制: 1Sec 内存限制: 128MB 提交: 3710 解决: 2470</p><p>题目描述</p><p>FJ在沙盘上写了这样一些字符串:</p><p>A1 = “A”</p><p>A2 = “ABA”</p><p>A3 = “ABACABA”</p><p>A4 = “ABACABADABACABA”</p><p>… …</p><p>你能找出其中的规律并写所有的数列AN吗?</p><p>输入</p><p>仅有一个数:N ≤ 26。</p><p>输出</p><p>请输出相应的字符串AN,以一个换行符结束。输出中不得含有多余的空格或换行、回车符。 </p><p>样例输入</p><pre><code>3 </code></pre><p>样例输出</p><pre><code>ABACABA</code></pre></blockquote><p>[基础练习VIP]: </p><h2 id="51"><a href="#51" class="headerlink" title="51"></a>51</h2><blockquote><p> 最长滑雪道<br>问题描述<br> 小袁非常喜欢滑雪, 因为滑雪很刺激。为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你。 小袁想知道在某个区域中最长的一个滑坡。区域由一个二维数组给出。数组的每个数字代表点的高度。如下:<br> <br>一个人可以从某个点滑向上下左右相邻四个点之一,当且仅当高度减小。在上面的例子中,一条可滑行的滑坡为24-17-16-1。当然25-24-23-…-3-2-1更长。事实上,这是最长的一条。<br> 你的任务就是找到最长的一条滑坡,并且将滑坡的长度输出。 滑坡的长度定义为经过点的个数,例如滑坡24-17-16-1的长度是4。<br>输入格式<br> 输入的第一行表示区域的行数R和列数C(1<=R, C<=10)。下面是R行,每行有C个整数,依次是每个点的高度h(0<= h <=10000)。<br>输出格式<br> 只有一行,为一个整数,即最长区域的长度。<br>样例输入<br>5 5<br>1 2 3 4 5<br>16 17 18 19 6<br>15 24 25 20 7<br>14 23 22 21 8<br>13 12 11 10 9<br>样例输出<br>25</p></blockquote><pre><code class="python">def dfs(x, y): """ 深度递归搜索 :param x: 横坐标 :param y: 纵坐标 :return: 最大距离 """ max_height = 1 # 初始距离为1 if dp[x][y] > 0: # 如果已经有了当前位置出发的最大距离,则直接返回 return dp[x][y] for k in range(4): # 判断该位置的上下左右四个位置 tx = x + next_[k][0] ty = y + next_[k][1] if tx < 0 or tx >= row or ty < 0 or ty >= col: # 越界情况 continue if arr[tx][ty] >= arr[x][y]: # 不符合高到低的情况 continue max_height = max(max_height, dfs(tx, ty) + 1) # 符合,递归搜索下一个位置且距离加1 dp[x][y] = max_height # 最终距离放在此矩阵中保存 return dp[x][y] # 返回该位置下的最大距离row, col = map(int, input().split())dp = [[0 for _ in range(col)] for _ in range(row)] # 记录从每个位置(x, y)开始,它的最大长度arr = [list(map(int, input().split())) for _ in range(row)] # 这里发明了二位数组python输入方法的一种全新方式,偶然发现的next_ = [[0, 1], [1, 0], [0, -1], [-1, 0]] # 用来表示(x, y)的上下左右四个位置ans = 0for i in range(row): for j in range(col): ans = max(ans, dfs(i, j))print(ans)</code></pre><pre><code class="python">#自己写的失败的代码def dfs(x,y): if DP[x][y]>0: return DP[x][y] maxLength=1 for i in range(4): tx=x+Direct[i][0] ty=y+Direct[i][1] if tx>=R or tx<0 or ty>=C or ty<0: continue if G[ty][tx]>G[x][y]: continue else: maxLength=max(maxLength,dfs(tx,ty)+1) DP[x][y]=maxLength return DP[x][y]R,C=map(int,input().split())G=[]for i in range(R): L=list(map(int ,input().split())) G.append(L)DP=[[0 for j in range(C)] for i in range(R)]ans=0Direct=[[0,1],[1,0],[-1,0],[0,-1]]for i in range(R): for j in range(C): ans=max(ans,dfs(i,j))print(ans)</code></pre><h2 id="52"><a href="#52" class="headerlink" title="52"></a>52</h2><p>龟兔赛跑</p><pre><code class="python">R,T=0,0count=0flag=0while R<l and T<l: count+=1 R+=v1 T+=v2 if R>=l: flag=1 break if T>=l: flag=2 break if R-T>=t: count1=count while count>=count1+s: count+=1 T+=v1 if T >=l: flag=3 break if flag==3: breakif R>T: print("R") print(count)if T>R: print("T") print(count)if T==R: print("R T") print(count)</code></pre>]]></content>
<summary type="html"><h1 id="蓝桥杯Python组算法训练"><a href="#蓝桥杯Python组算法训练" class="headerlink" title="蓝桥杯Python组算法训练"></a>蓝桥杯Python组算法训练</h1><h2 id="1"><a href="#1" c</summary>
</entry>
<entry>
<title>Python 爬虫学习笔记</title>
<link href="http://sweetheart.nefu.site/2021/01/24/Python-%E7%88%AC%E8%99%AB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"/>
<id>http://sweetheart.nefu.site/2021/01/24/Python-%E7%88%AC%E8%99%AB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/</id>
<published>2021-01-24T01:18:36.000Z</published>
<updated>2021-01-28T09:24:27.358Z</updated>
<content type="html"><![CDATA[<h1 id="Python-爬虫笔记"><a href="#Python-爬虫笔记" class="headerlink" title="Python 爬虫笔记"></a>Python 爬虫笔记</h1><p>为了学习机器学习时方便获取数据以及日后的web开发</p><p>这个寒假又开始捡起爬虫(其实之前只会基本请求,网页源码全扒下来的那种~~)</p><h2 id="准备工作"><a href="#准备工作" class="headerlink" title="准备工作"></a>准备工作</h2><p>准备爬取豆瓣top250的信息</p><p>规律:每页都是以25为间隔</p><p>利用Chrome开发者工具辅助</p><p>需要引入的库:</p><pre><code class="python">import bs4 #网页解析获取数据import re #正则表达式,文字匹配import urllib.request,urllib.error #制定url,获取网页数据import xlwt # 进行excel操作import sqlite3 #进行sqlite数据库操作</code></pre><p>代码架构如下:</p><pre><code class="python">def main(): baseUrl="https://movie.douban.com/top250" #基本网址 # 爬取网页 savePath=r".\豆瓣电影Top250.xls" # 逐一解析数据 # 保存数据 # 爬取网页 def getData(): datalist=[] # 逐一解析数据 return datalist def SaveData(savePath): print() if __name__=="__main__": main() </code></pre><h2 id="urlib用法"><a href="#urlib用法" class="headerlink" title="urlib用法"></a>urlib用法</h2><pre><code class="python">import urllib.request#获取一个get方式response=urllib.request.urlopen("https://www.baidu.com")#将网页打开并返回网页数据,就是获得了网页源代码print(response.read().decode('utf-8'))#打印信息,并且保证中文显示</code></pre><pre><code class="python">import urllib.requestimport urllib.parse#解析器#获取一个post请求data=bytes(urllib.parse.urlencode(&#123;"hellow":"world"&#125;),encoding="utf-8")#转化二进制,解析键值对response=urllib.request.urlopen(r"https://httpbin.org/post",data=data)print(response.read().decode("utf-8"))# 返回如下:# &#123;# "args": &#123;&#125;,# "data": "",# "files": &#123;&#125;,# "form": &#123;# "hellow": "world"这里是我们请求的数据# &#125;,# "headers": &#123;# "Accept-Encoding": "identity",# "Content-Length": "12",# "Content-Type": "application/x-www-form-urlencoded",# "Host": "httpbin.org",# "User-Agent": "Python-urllib/3.7",# "X-Amzn-Trace-Id": "Root=1-60102159-645571fd5c4c09b93338b8d5"# &#125;,# "json": null,# "origin": "117.65.146.144",# "url": "https://httpbin.org/post"# &#125;</code></pre><pre><code class="python">import urllib.requestimport urllib.parse#解析器#超时try: response=urllib.request.urlopen(r"https://httpbin.org",timeout=0.01) print(response.read())except urllib.error.URLError as e: print("超时了")</code></pre><pre><code class="python">import urllib.requestimport urllib.parse#解析器response=urllib.request.urlopen(r"https://douban.com")print(response.status)#urllib.error.HTTPError: HTTP Error 418: #表示发现你是一个爬虫了print(response.getheaders())#获取响应头,print(response.getheader('Set-Cookie'))#获取具体的头部数据</code></pre><p>如何让网页不知道我们是爬虫从而避免418:</p><pre><code class="python">import urllib.requestimport urllib.parse#解析器url="https://douban.com"headers=&#123;"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36"&#125;#网页检查network中从header中复制粘贴来的,req=urllib.request.Request(url=url,headers=headers)response=urllib.request.urlopen(req)print(response.read().decode("utf-8"))#成功返回了</code></pre><p>编写函数来访问:</p><pre><code class="python">import bs4 #网页解析获取数据import re #正则表达式,文字匹配import urllib.request,urllib.error #制定url,获取网页数据import xlwt # 进行excel操作import sqlite3 #进行sqlite数据库操作def main(): baseUrl = "https://movie.douban.com/top250" # 基本网址 AskUrl(baseUrl)#得到指定URL的内容def AskUrl(url): head = &#123;#模拟浏览器头部信息 "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36" &#125;#用户代理,告诉豆瓣我们可以接受什么类型的文件内容,这里一定要用豆瓣网页的 request=urllib.request.Request(url,headers=head) html="" try: response=urllib.request.urlopen(request) html=response.read().decode("utf-8") print(html) except urllib.error.URLError as e: if hasattr(e,"code"): print(e.code) if hasattr(e,"reason"): print(e.reason)if __name__ == '__main__': main()</code></pre><p>这里逐页获取:</p><pre><code class="python">def main(): baseUrl = "https://movie.douban.com/top250?start=" # 基本网址 # 爬取网页 savePath = r".\豆瓣电影Top250.xls" # 逐一解析数据 # 保存数据 getData()# 爬取网页def getData(): datalist = [] for i in range(0,10): url=baseurl+str(i*25) html=AskUrl(url) #保存获取到的源码 # 逐一解析数据 return datalist#得到指定URL的内容def AskUrl(url): head = &#123;#模拟浏览器头部信息 "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36" &#125;#用户代理,告诉豆瓣我们可以接受什么类型的文件内容,这里一定要用豆瓣网页的 request=urllib.request.Request(url,headers=head) html="" try: response=urllib.request.urlopen(request) html=response.read().decode("utf-8") print(html) except urllib.error.URLError as e: if hasattr(e,"code"): print(e.code) if hasattr(e,"reason"): print(e.reason) return htmlif __name__ == "__main__": main() </code></pre><h2 id="BeautifulSoup用法"><a href="#BeautifulSoup用法" class="headerlink" title="BeautifulSoup用法"></a>BeautifulSoup用法</h2><p>BS4可以将文档归档四种类型:</p><ul><li>tag</li><li>navigaableString</li><li>beautifulsoup</li><li>comment</li></ul><p><a href="https://blog.csdn.net/m0_37623485/article/details/88324296?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522161176637016780299025194%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=161176637016780299025194&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_click~default-1-88324296.pc_search_result_before_js&utm_term=beautifulsoup&spm=1018.2226.3001.4187">具体用法</a></p><pre><code class="python">from bs4 import BeautifulSoupbs=BeautifulSoup(html,"html.parser")#解析文件树print(bs.a)print(bs.title)print(bs.header)#这种方式访问标签内容,默认只拿到第一个内容#1.tag及其内容print(bs.title.string)#只知道标签内容,#2.navigableString标签里面的内容print(bs.a.atters)#拿到标签内部超链接以及标签内部的样式名称#获得整个文档内容print(bs)#整个文档print(bs.name)#documentprint(bs.attrs)#&#123;&#125;#3BeautifulSoupprint(ba.a.string)#这里拿到源码的注释的内容。没有注释的符号#文档的遍历#采用下标访问print(bs.head.contents[1])#文档的搜索#字符串过滤t_list=bs.find_all("a")#查找所有a标签print(bs.t_list)#正则表达式搜索import ret_list=bs.find_all(re.compile("a"))#包含a字母的标签#传入一个函数,根据一个函数搜索def name_is_exists(tag): return tag.has_atter("name")#包含name的标签,作为了解t_list=bs.find_all((name_is_exists))#kwargs参数搜索t_list=bs.find_all(id="head")#含有id=header的标签中所有内容t_list=bs.find_all(class_=True)#含有clas的标签以及子内容t_list=bs.find_all(href="http://baidu.com")#含有此链接的标签t_list=bs.find_all(text=["百度","贴吧"])#3文本参数搜索,将会搜索出文本t_list=bs.find_all(text=re.compile("\d"))#用正则表达式搜索特点文本内容(标签内字符串)#limit参数t_list=bs.find_all("a",limit=3)#限定搜索三个#css选择器t_list=bs.select("title")#通过标签查找t_list=bs.select(".class")#类名查找t_list=bs.select("#id")#id查找t_list=bs.select("head>title")#查找子标签t_list=bs.select("。mnav~.bri")#查找兄弟标签print(t_list[0].get_text())#找到标签包含的文本内容</code></pre><h2 id="开始爬取"><a href="#开始爬取" class="headerlink" title="开始爬取"></a>开始爬取</h2><pre><code class="python">import refrom bs4 import BeautifulSoupimport urllib.requestimport xlwtfindLink=re.compile(r'<a href="(.*?)">')findImg=re.compile(r'<img.*src="(.*?)"',re.S)#忽略换行符findTitle=re.compile(r'<span class="title">(.*)</span>')findRating=re.compile(r'<span class="rating_num" property="v:average">(.*)</span>')findJudge=re.compile(r'<span>(\d*)人评价</span>')findInq=re.compile(r'<span class="inq">(.*)</span>')findBd=re.compile(r'<p class="">(.*?)</p>',re.S)def main(): baseUrl = "https://movie.douban.com/top250?start=" # 基本网址 # 爬取网页 savePath = r".\豆瓣电影Top250.xls" # 逐一解析数据 # 保存数据 datalist=getData(baseUrl)# 爬取网页def getData(baseUrl): datalist = [] for i in range(0,10): url=baseUrl+str(i*25) html=AskUrl(url) #保存获取到的源码 # 逐一解析数据 soup=BeautifulSoup(html,"html.parser") for i in soup.find_all('div',class_="item"):#查找目标内容 # print(i) 测试查看全部信息 data=[] i=str(i) link=re.findall(findLink,i)[0] data.append(link) ImgSrc=re.findall(findImg,i) data.append(ImgSrc) titles=re.findall(findTitle,i) if (len(titles))==2: ctitle=titles[0] data.append(ctitle)#添加中文 otitle=titles[1].replace("/",'')#去掉无关的符号 data.append(otitle)#添加外文 else: data.append(titles[0]) data.append('暂无外文名')#注释无外文名 rating=re.findall(findRating,i)[0]#评分 data.append(rating) judgeNumber=re.findall(findJudge,i)[0] data.append(judgeNumber)#评价人数 inq=re.findall(findInq,i) if len(inq)!=0: inq=inq[0].replace("。",'')#去掉句号 else: inq="暂无简介" data.append(inq)#但是不是每一部都有概述 bd=re.findall(findBd,i)[0] bd=re.sub('<br(\s+)?>(\s+)?'," ",bd)#去掉br bd=re.sub('/',"—",bd) data.append(bd.strip())#去掉前后空格 datalist.append(data)#处理好的信息放入列表 print(datalist) return datalist#得到指定URL的内容def AskUrl(url): head = &#123;#模拟浏览器头部信息 "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36" &#125;#用户代理,告诉豆瓣我们可以接受什么类型的文件内容,这里一定要用豆瓣网页的 request=urllib.request.Request(url,headers=head) html="" try: response=urllib.request.urlopen(request) html=response.read().decode("utf-8") # print(html) except urllib.error.URLError as e: if hasattr(e,"code"): print(e.code) if hasattr(e,"reason"): print(e.reason) return htmlif __name__ == "__main__": main()</code></pre><h2 id="保存数据"><a href="#保存数据" class="headerlink" title="保存数据"></a>保存数据</h2><h3 id="xlwt用法"><a href="#xlwt用法" class="headerlink" title="xlwt用法"></a>xlwt用法</h3><pre><code class="python">import xlwtworkbook=xlwt.Workbook(encoding="utf-8")#创建workbook对象worksheet=workbook.add_sheet('sheet1')#创建工作表worksheet.write(0,0,"hellow")#向第一个元素写入hellow第一个是行,第二个个是列workbook.save("表格.xls")</code></pre><p><a href="https://blog.csdn.net/wangkai_123456/article/details/50457284?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522161182435616780261935226%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=161182435616780261935226&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~baidu_landing_v2~default-2-50457284.pc_search_result_before_js&utm_term=xlwt+%E4%BD%BF%E7%94%A8&spm=1018.2226.3001.4187">参考1</a></p><p><a href="https://my.oschina.net/kalnkaya/blog/3020078">参考2</a></p><p>案例:写入九九乘法表</p><pre><code class="python">import xlwtworkbook=xlwt.Workbook(encoding="utf-8")#创建workbook对象worksheet=workbook.add_sheet('sheet1')#创建工作表for i in range(9): for j in range(i+1): worksheet.write(i,j,"%d * %d = %d"%(i+1,j+1,(i+1)*(j+1)))workbook.save("表格.xls")</code></pre><h3 id="爬取数据写入"><a href="#爬取数据写入" class="headerlink" title="爬取数据写入"></a>爬取数据写入</h3><pre><code class="python">import refrom bs4 import BeautifulSoupimport urllib.requestimport xlwtfindLink=re.compile(r'<a href="(.*?)">')findImg=re.compile(r'<img.*src="(.*?)"',re.S)#忽略换行符findTitle=re.compile(r'<span class="title">(.*)</span>')findRating=re.compile(r'<span class="rating_num" property="v:average">(.*)</span>')findJudge=re.compile(r'<span>(\d*)人评价</span>')findInq=re.compile(r'<span class="inq">(.*)</span>')findBd=re.compile(r'<p class="">(.*?)</p>',re.S)def main(): baseUrl = "https://movie.douban.com/top250?start=" # 基本网址 # 爬取网页 savePath = r"豆瓣电影Top250.xls" # 逐一解析数据 # 保存数据 datalist=getData(baseUrl) SaveData(datalist,savePath)# 爬取网页def getData(baseUrl): datalist = [] for i in range(0,10): url=baseUrl+str(i*25) html=AskUrl(url) #保存获取到的源码 # 逐一解析数据 soup=BeautifulSoup(html,"html.parser") for i in soup.find_all('div',class_="item"):#查找目标内容 # print(i) 测试查看全部信息 data=[] i=str(i) link=re.findall(findLink,i)[0] data.append(link) ImgSrc=re.findall(findImg,i) data.append(ImgSrc) titles=re.findall(findTitle,i) if (len(titles))==2: ctitle=titles[0] data.append(ctitle)#添加中文 otitle=titles[1].replace("/",'')#去掉无关的符号 data.append(otitle)#添加外文 else: data.append(titles[0]) data.append('暂无外文名')#注释无外文名 rating=re.findall(findRating,i)[0]#评分 data.append(rating) judgeNumber=re.findall(findJudge,i)[0] data.append(judgeNumber)#评价人数 inq=re.findall(findInq,i) if len(inq)!=0: inq=inq[0].replace("。",'')#去掉句号 else: inq="暂无简介" data.append(inq)#但是不是每一部都有概述 bd=re.findall(findBd,i)[0] bd=re.sub('<br(\s+)?>(\s+)?'," ",bd)#去掉br bd=re.sub('/',"—",bd) data.append(bd.strip())#去掉前后空格 datalist.append(data)#处理好的信息放入列表 print(datalist) return datalist#得到指定URL的内容def AskUrl(url): head = &#123;#模拟浏览器头部信息 "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36" &#125;#用户代理,告诉豆瓣我们可以接受什么类型的文件内容,这里一定要用豆瓣网页的 request=urllib.request.Request(url,headers=head) html="" try: response=urllib.request.urlopen(request) html=response.read().decode("utf-8") # print(html) except urllib.error.URLError as e: if hasattr(e,"code"): print(e.code) if hasattr(e,"reason"): print(e.reason) return htmldef SaveData(datalist,savePath): film = xlwt.Workbook(encoding="utf-8",style_compression=0) # 创建workbook对象 filmSheet = film.add_sheet('豆瓣电影250',cell_overwrite_ok=True) # 创建工作表 覆盖以前内容 col=("电影详情链接","图片链接","影片中文名","影片外国名","评分","评价数","概况","相关信息") for i in range(8): filmSheet.write(0,i,col[i])#写入第一行 for i in range(250): print("第%d条"%i) data=datalist[i] for j in range(8): filmSheet.write(i+1,j,data[j]) film.save(savePath) #保存if __name__ == "__main__": main()</code></pre><p>效果如下:</p><p><img src="http://pan-yz.chaoxing.com/preview/showpreview_561600886733012992.html?v=1611825690000" alt="最终效果图"></p><p><strong>至此基本的网页爬取技巧结束了</strong>,关于爬虫更加深入的引用后面会补充</p>]]></content>
<summary type="html"><h1 id="Python-爬虫笔记"><a href="#Python-爬虫笔记" class="headerlink" title="Python 爬虫笔记"></a>Python 爬虫笔记</h1><p>为了学习机器学习时方便获取数据以及日后的web开发</p>
<p>这</summary>
<category term="web" scheme="http://sweetheart.nefu.site/categories/web/"/>
<category term="Python" scheme="http://sweetheart.nefu.site/categories/web/Python/"/>
<category term="爬虫" scheme="http://sweetheart.nefu.site/categories/web/Python/%E7%88%AC%E8%99%AB/"/>
<category term="Python" scheme="http://sweetheart.nefu.site/tags/Python/"/>
<category term="爬虫" scheme="http://sweetheart.nefu.site/tags/%E7%88%AC%E8%99%AB/"/>
</entry>
<entry>
<title>神经网络与深度学习练习</title>
<link href="http://sweetheart.nefu.site/2021/01/19/Python%E5%9F%BA%E7%A1%80%E6%81%A2%E5%A4%8D/"/>
<id>http://sweetheart.nefu.site/2021/01/19/Python%E5%9F%BA%E7%A1%80%E6%81%A2%E5%A4%8D/</id>
<published>2021-01-19T07:29:51.000Z</published>
<updated>2021-02-27T03:50:02.060Z</updated>
<content type="html"><![CDATA[<h1 id="神经网络与深度学习作业"><a href="#神经网络与深度学习作业" class="headerlink" title="神经网络与深度学习作业"></a>神经网络与深度学习作业</h1><p>大垃圾一年没写python辣(其实去年也学的稀烂),今年要机器学习不得不捡起py开始学</p><p>为了逐步把自己的算法水平移植到py上,于是决定开始Py恢复训练(<strong>其实就是重新学</strong>)</p><p>然后这个笔记主要是存放西安科技大学的神经网络与深度学习的作业代码</p><p>然后也会放一些自己在kaggle或者其他网站数据分析的练习</p><h2 id="练习1:"><a href="#练习1:" class="headerlink" title="练习1:"></a>练习1:</h2><blockquote><p>( 20分 )</p><p>作业题1</p><p>要求用户输入一个1-100之间的整数。在屏幕上输出1-1000中所有可以被这个输入数字整除的整数,并把它们写入文本文件中。</p><p><strong>1.基本要求:</strong></p><p>(1) 接收用户输入,并判断是否为1-100之间的整数。如果输入符合要求,则继续执行第(2)步,否则结束程序。</p><p>(2) 根据用户输入,在屏幕上输出1-1000中,所有可以被这个数字整除的数字,并打印序号。序号从1开始,依次加1.</p><p>例如,用户输入20,的情况:</p><p> 请输入一个1-100之间的整数:20</p><p>1 20</p><p>2 40</p><p>3 60</p><p>4 80</p><p>5 100</p><p>……</p><p>46 920</p><p>47 940</p><p>48 960</p><p>49 980</p><p>50 1000</p><p>(3)将第(2)步的输出结果,写入C盘根目录下的文本文件中,文件名为“x的倍数.txt”,例如,输入20,则文件名为:“20的倍数.txt”。</p><p>(4) 添加必要的注释,说明程序设计思路。</p><p><strong>2.提高要求:</strong></p><p>(1) 如果输入不符合要求,则要求用户重新输入,并给出提示信息。具体要求参见第4讲单元作业1。</p><p>(2) 将基本要求中的(1)和(2),通过函数实现。</p><p>(3) 在程序中需要的地方,捕捉异常,或使用with语句管理资源。</p><p>说明:提交一份程序代码即可。根据实现功能综合得分。</p><p>满足基本要求最高14分,满足提高要求最高20分。</p></blockquote><p>代码:</p><pre><code class="python">print("请输入1-100之间的整数")while True: str=input() if not str.isdigit(): print("输入有误,不是整数,请继续") continue elif int(str)>100: print("输入有误,不在范围内,请继续") continue elif int(str)<1: print("输入有误,不在范围内,请继续") continue else: print("输入正确,继续程序") with open("记录用文件.txt","w") as f: count=1; for i in range(1,10001): if i%int(str)==0: f.write('%d: %s \n'%(count,i)) count+=1 with open("记录用文件.txt","r") as f: content=f.readlines() for i in content: print(i)</code></pre><h2 id="练习2:"><a href="#练习2:" class="headerlink" title="练习2:"></a>练习2:</h2><blockquote><p>( 10分 )</p><p>生成一个[0,1)之间均匀分布的随机数数组,包含1000个元素, 随机种子为612。接收用户输入一个1-100之间的数字。打印随机数组中所有索引值可以被输入整数整除的数字,并打印序号和索引值。序号从1开始,依次加1. 例如,用户输入50,则打印数组中索引值为0,50,100…1000的随机数。</p><p><strong>程序运行示例:</strong></p><p>请输入一个1-100之间的整数:50</p><p>序号 索引值 随机数</p><p>1 50 0.685693777029538</p><p>2 100 0.8447931162144151</p><p>3 150 0.7043694996423318</p><p>……</p><p>19 950 0.5979676151428348</p><p>20 1000 0.5714978209525051</p><p>提示:输出时可以使用制表符”\t”,对齐各列。</p></blockquote><p>代码:</p><pre><code class="python">import numpy as npnum=int(input("请输入一个整数,我将会打印打印随机数组中所有索引值可以被输入整数整除的数字:"))np.random.seed(612)a=np.random.rand(1000)count=0for i in range(1,1002): if i%num ==0: count += 1 print("%d\t%d\t%f\n"%(count,i,a[i]))</code></pre><h2 id="练习3:"><a href="#练习3:" class="headerlink" title="练习3:"></a>练习3:</h2><blockquote><p>已知:</p><p>x=[ 64.3,99.6,145.45,63.75,135.46,92.85,86.97,144.76,59.3,116.03]</p><p>y=[ 62.55,82.42,132.62,73.31,131.05,86.57,85.49,127.44,55.25,104.84]</p></blockquote><p>利用最小二乘法求x与y的回归曲线,代码如下:</p><pre><code class="python">import numpy as npx1=[ 64.3,99.6,145.45,63.75,135.46,92.85,86.97,144.76,59.3,116.03]y1=[ 62.55,82.42,132.62,73.31,131.05,86.57,85.49,127.44,55.25,104.84]x=np.array(x1)y=np.array(y1)_x=np.sum(x,axis=0)/np.size(x)_y=np.sum(y,axis=0)/np.size(y)x=x-_xy=y-_yCovXY=np.sum(x*y,axis=0)DX=np.sum(x*x,axis=0)w=CovXY/DXb=_y-w*_xprint("y=%.3f*x+%.3f"%(w,b))</code></pre><h2 id="练习4:"><a href="#练习4:" class="headerlink" title="练习4:"></a>练习4:</h2><blockquote><p>己知:</p><p>x0是一个包含长度为10、元素值全部为1的一维数组</p><p>x1=[ 64.3,99.6,145.45,63.75,135.46,92.85,86.97,144.76,59.3,116.03]</p><p>x2=[2,3,4,2,3,4,2,4,1,3]</p><p>y=[ 62.55,82.42,132.62,73.31,131.05,86.57,85.49,127.44,55.25,104.84]</p><p>要求:</p><p>(1)将x0、x1、x2堆叠为一个10x3的二维数组X,其中 x0、x1、x2依次是第1列,第2列和第3列;</p><p> 将y变换为10x1的二维数组Y。</p><p>(2)计算: w=(XTx)1xTY,并回答: w 的shape 属性结果是什么?</p><p>(3)分别输出X,Y和W。</p></blockquote><p>(1)</p><pre><code class="python">import numpy as npx0=np.ones(10)x1=np.array([ 64.3,99.6,145.45,63.75,135.46,92.85,86.97,144.76,59.3,116.03])x2=np.array([2,3,4,2,3,4,2,4,1,3])y=np.array([ 62.55,82.42,132.62,73.31,131.05,86.57,85.49,127.44,55.25,104.84])X=np.stack((x0,x1,x2),axis=1)Y=y.reshape(10,1)print(X)print("\n")print(Y)</code></pre><p>(2)</p><pre><code class="python">import numpy as npx0=np.ones(10)x1=np.array([ 64.3,99.6,145.45,63.75,135.46,92.85,86.97,144.76,59.3,116.03])x2=np.array([2,3,4,2,3,4,2,4,1,3])y=np.array([ 62.55,82.42,132.62,73.31,131.05,86.57,85.49,127.44,55.25,104.84])X=np.stack((x0,x1,x2),axis=1)Y=y.reshape(10,1)X=np.mat(X)Y=np.mat(Y)W=(X.T*X).I*X.T*Yprint(W.shape)#输出(3,1)</code></pre><p>(3)</p><pre><code class="python">import numpy as npx0=np.ones(10)x1=np.array([ 64.3,99.6,145.45,63.75,135.46,92.85,86.97,144.76,59.3,116.03])x2=np.array([2,3,4,2,3,4,2,4,1,3])y=np.array([ 62.55,82.42,132.62,73.31,131.05,86.57,85.49,127.44,55.25,104.84])X=np.stack((x0,x1,x2),axis=1)Y=y.reshape(10,1)X=np.mat(X)Y=np.mat(Y)W=(X.T*X).I*X.T*Yprint(W.shape)print(X,'\n',Y,'\n',W)</code></pre><h2 id="练习5:"><a href="#练习5:" class="headerlink" title="练习5:"></a>练习5:</h2><blockquote><p>( 20分 )</p><p>按下列要求完成程序。</p><p>(1) 下载波士顿数据集,读取全部506条数据,放在NumPy数组x、y中(x:属性,y:标记)。(5分)</p><p>(2) 使用全部506条数据,实现波士顿房价数据集可视化,如图1所示。(10分)</p><p>(3) 要求用户选择属性,如图2所示,根据用户的选择,输出对应属性的散点图,如图3所示。(5分)</p></blockquote><p><img src="https://edu-image.nosdn.127.net/8BC5482320FC3D941D619B74F6B882EE.png?imageView&thumbnail=890x0&quality=100" alt="图1"></p><p><img src="https://edu-image.nosdn.127.net/6DCA15B83A8137CAB44E778A8B31DEC9.png?imageView&thumbnail=890x0&quality=100" alt="图2"></p><p><img src="https://edu-image.nosdn.127.net/B351B147036FFA401C16F27AC536B8B8.png?imageView&thumbnail=890x0&quality=100" alt="图3"></p><p>代码:</p><pre><code class="python">import tensorflow as tfimport matplotlib.pyplot as pltboston_housing=tf.keras.datasets.boston_housing(x_train,y_tain),(x_test,y_test)=boston_housing.load_data(test_split=0)plt.rcParams['font.sans-serif']=['SimHei']plt.rcParams['axes.unicode_minus']=Falsetitles = ["CRIM","ZN","INDUS","CHAS","NOX","RM","AGE","DIs","RAD","TAX","PTRATIO","B-1000","LSTAT","MEDV"]plt.figure(figsize=(12,15))for i in range(13): plt.subplot(4,4,(i+1)) plt.scatter(x_train[:,i],y_tain) plt.xlabel(titles[i]) plt.ylabel("Price") plt.title(str(i+1)+'.'+titles[i]+'-Price')plt.tight_layout()plt.suptitle("各个属性与房价的关系",x=0.5,y=1.02, fontsize=20)plt.show() </code></pre><p>实现用户交互功能:</p><pre><code class="python">import tensorflow as tfimport matplotlib.pyplot as pltboston_housing=tf.keras.datasets.boston_housing(x_train,y_tain),(x_test,y_test)=boston_housing.load_data(test_split=0)plt.rcParams['font.sans-serif']=['SimHei']plt.rcParams['axes.unicode_minus']=Falsetitles = ["CRIM","ZN","INDUS","CHAS","NOX","RM","AGE","DIs","RAD","TAX","PTRATIO","B-1000","LSTAT","MEDV"]plt.figure(figsize=(12,12))print("现在有如下属性与索引值:\n")for i in titles: print("%d %s\n"%(titles.index(i),i))user=int(input("请输入您想查询的属性与房价的关系(请输入数字):"))print("显示关系如图:")plt.scatter(x_train[:,user],y_tain)plt.xlabel(titles[user])plt.ylabel("Price")plt.title(titles[user]+"与房价的关系图")plt.show()</code></pre><p>这里有一个实践上的问题,需要vpn代理开启全局模式才能正常下载数据集,否则无法下载</p><h2 id="练习6:"><a href="#练习6:" class="headerlink" title="练习6:"></a>练习6:</h2><p>( 20分 )</p><p>使用鸢尾花数据集,绘制如下图形,其中对角线为属性的直方图。</p><p><img src="https://edu-image.nosdn.127.net/AE671975EBF9545FCA03C9576D3FFA7A.png?imageView&thumbnail=890x0&quality=100" alt="示例"></p><pre><code class="python">import tensorflow as tfimport matplotlib.pyplot as pltfrom sklearn.datasets import load_irisfrom sklearn.model_selection import train_test_splitimport numpy as npiris=load_iris()x_train,x_test,y_train,y_test=train_test_split(iris.data,iris.target,test_size=0)plt.rcParams['font.sans-serif'] = ['SimHei']plt.rcParams['axes.unicode_minus'] = Falseplt.figure("鸢尾花数据集", figsize=(15, 15))plt.subplot("鸢尾花数据图像\nBlue->Setosa|Red->Versicolor|Green->Virginica")for i in range(4): for j in range(4): plt.subplot(4, 4, 4 * i + j + 1) if j != i: plt.scatter(x_train[:, j], x_train[:, i], c=y_train, cmap='brg') else: plt.hist(x_train[:i], align=mid, color="g") if i == 0: plt.title(COLUN_NAMES[j]) if j == 0: plt.title(COLUN_NAMES[i])plt.tight_layout(rect=[0, 0, 1, 0.93])plt.show()</code></pre><h2 id="练习7:"><a href="#练习7:" class="headerlink" title="练习7:"></a>练习7:</h2><p>( 20分 )</p><p>按下列要求完成程序,随机显示MNIST数据集中的样本,效果如图1所示。</p><p><img src="https://edu-image.nosdn.127.net/AAB2FE1BD3009B10E3B80BB7492B64CC.png?imageView&thumbnail=890x0&quality=100" alt="图1"></p><p>要求:</p><p>(1)下载手写数字数据集,读取训练集和测试集数据,放在NumPy数组train_x、train_y、test_x、test_y中;(train_x:训练集图像,train_y:训练集标签,test_x:测试集图像,test_y:测试集标签)</p><p>(2)随机从所有测试集数据中显示16幅数字图像;</p><p>(3)16幅图像按照4×4方式排列在一张画布中,每幅图像的子标题为该图像的标签值,字体大小为14,全局标题为“MNIST测试集样本”,字体大小为20,颜色为红色。</p><p>代码如下:</p><pre><code class="python">import tensorflow as tfimport numpy as npimport matplotlib.pyplot as pltmnist=tf.keras.datasets.mnist(x1,y1),(x2,y2)=mnist.load_data()plt.rcParams['font.sans-serif']=['SimHei']plt.rcParams['axes.unicode_minus']=Falsefor i in range(16): num=np.random.randint(1,5000) plt.subplot(4,4,i+1) plt.axis("off") plt.imshow(x1[i],cmap="gray") plt.title(y1[i])plt.tight_layout()plt.suptitle("手写数字样本 ",x=0.5,y=1.02, fontsize=20)plt.show()</code></pre><h2 id="练习8:"><a href="#练习8:" class="headerlink" title="练习8:"></a>练习8:</h2><blockquote><p> 15分 )</p><p>使用TensorFlow张量运算计算w和b,并输出结果。</p><p>已知: </p><p>x=[ 64.3, 99.6, 145.45, 63.75, 135.46, 92.85, 86.97, 144.76, 59.3, 116.03]</p><p>y=[ 62.55, 82.42, 132.62, 73.31, 131.05, 86.57, 85.49, 127.44, 55.25, 104.84]</p><p>计算:</p></blockquote><p><img src="https://edu-image.nosdn.127.net/424E0B9805AEEFD7B6682360C6CA2F26.png?imageView&thumbnail=890x0&quality=100" alt="图片"></p><blockquote><p>(3)分别输出W和b的结果。</p><p>提示:</p><p>正确的输出结果为</p><p>w= 0.83215……</p><p>b= 10.2340…….</p></blockquote><p>代码如下:</p><pre><code class="python">import tensorflow as tfx=tf.constant([ 64.3, 99.6, 145.45, 63.75, 135.46, 92.85, 86.97, 144.76, 59.3, 116.03])y=tf.constant([ 62.55, 82.42, 132.62, 73.31, 131.05, 86.57, 85.49, 127.44, 55.25, 104.84])_x=tf.reduce_mean(x)_y=tf.reduce_mean(y)w=tf.reduce_sum((x-_x)*(y-_y))/tf.reduce_sum(tf.square(x-_x))b=_y-w*_xprint("W的值是:",w)print("b的值是:",b)#输出#W的值是: tf.Tensor(0.83215153, shape=(), dtype=float32)#b的值是: tf.Tensor(10.234009, shape=(), dtype=float32)</code></pre><h2 id="练习9:"><a href="#练习9:" class="headerlink" title="练习9:"></a>练习9:</h2><blockquote><p>( 15分 )</p><p>使用TensorFlow张量运算计算w和b,并输出结果。</p><p>已知: </p><p>x=[ 64.3, 99.6, 145.45, 63.75, 135.46, 92.85, 86.97, 144.76, 59.3, 116.03]</p><p>y=[ 62.55, 82.42, 132.62, 73.31, 131.05, 86.57, 85.49, 127.44, 55.25, 104.84]</p><p>计算:</p></blockquote><p><img src="https://edu-image.nosdn.127.net/E0ACECBF9E75F5992C9722C4B4E1C7C7.png?imageView&thumbnail=890x0&quality=100"></p><p>(3)分别输出W和b的结果。</p><p>代码如下:</p><pre><code class="python">import tensorflow as tfx=tf.constant([ 64.3, 99.6, 145.45, 63.75, 135.46, 92.85, 86.97, 144.76, 59.3, 116.03])y=tf.constant([ 62.55, 82.42, 132.62, 73.31, 131.05, 86.57, 85.49, 127.44, 55.25, 104.84])w=(len(x)*tf.reduce_sum(x*y)-tf.reduce_sum(x)*tf.reduce_sum(y))/(len(x)*tf.reduce_sum(tf.square(x))-tf.square(tf.reduce_sum(x)))b=(tf.reduce_sum(y)-w*tf.reduce_sum(x))/len(x)print("W的值是:",w)print("b的值是:",b)# 输出# W的值是: tf.Tensor(0.83215135, shape=(), dtype=float32)# b的值是: tf.Tensor(10.234021, shape=(), dtype=float32)</code></pre><p>可见结果同上一题,说明这是最小二乘法变式</p><p>注意tf.size()无法获取张量元素数(准确说的返回值不是数字),这里用len 来表示</p><h2 id="练习10:"><a href="#练习10:" class="headerlink" title="练习10:"></a>练习10:</h2><blockquote><p>下载lena.tiff图像(见7.2小节课件),将R、G、B三通道分离,采用灰度图表示颜色的亮度,并分别对各个通道按要求进行处理,结果显示在如图1所示的画布中。</p><p><img src="https://edu-image.nosdn.127.net/14BD7293AF3873250E1366CFC141517E.png?imageView&thumbnail=890x0&quality=100"></p><p>要求:</p><p>(1)将R通道的图像缩小为50×50,显示在子图1中,子标题为:“R-缩放”,字体大小为14;</p><p>(2)将G通道的图像先水平镜像,再顺时针旋转90度,显示在子图2中,子标题为:“G-镜像+旋转”,字体大小为14,并显示坐标轴;</p><p>(3)对B通道的图像进行裁剪,裁剪位置:左上角(0, 0) 右下角(150, 150),显示在子图3中,子标题为:“B-裁剪”,字体大小为14;</p><p>(4)将原始的R、G、B通道的图像合并,显示在子图4中,子标题显示图像的色彩模式,字体大小为14;</p><p>(5)将要求(4)的处理结果保存为PNG格式的图片,路径为当前工作目录,文件名为“test.png”,如图2所示;</p><p>(6)将以上生成的4幅图像显示在2×2的画布中,全局标题为“图像基本操作”,标题字体大小为20,颜色为蓝色。</p><p>代码如下:</p></blockquote><pre><code class="python">from PIL import Imageimport matplotlib.pyplot as pltlenna=Image.open("Lenna.jpg")lenna_r,lenna_g,lenna_b=lenna.split()plt.rcParams['font.sans-serif']=['SimHei']plt.rcParams['axes.unicode_minus']=Falseplt.figure(figsize=(10,10))plt.subplot(221)plt.axis("off")r_resize=lenna_r.resize((50,50))plt.imshow(r_resize,cmap="gray")plt.title("R-缩放",fontsize=14)plt.subplot(222)g_trans=lenna_g.transpose(Image.FLIP_LEFT_RIGHT).transpose(Image.ROTATE_270)plt.imshow(g_trans,cmap="gray")plt.title("G-镜像+旋转",fontsize=14)plt.subplot(223)plt.axis("off")b_sub=lenna_b.crop((0,0,150,150))plt.imshow(b_sub,cmap="gray")plt.title("B-剪切",fontsize=14)plt.subplot(224)plt.axis("off")merge=Image.merge("RGB",[lenna_r,lenna_g,lenna_b])plt.imshow(merge)plt.title("RGB",fontsize=14)plt.tight_layout()plt.suptitle("图像基本操作 ",x=0.5,y=1.02, fontsize=20,color="blue")plt.show()plt.savefig("test.png")</code></pre><p>展示图片如下:</p><p><img src="http://pan-yz.chaoxing.com/preview/showpreview_565779590795227136.html?v=1612821971000" alt="lenna图"></p><p>这里用的图是网上下载的,所以出来的结果和展示不一样(尺寸问题)</p><h2 id="练习11:"><a href="#练习11:" class="headerlink" title="练习11:"></a>练习11:</h2><blockquote><p>使用9.5小节中的“商品房销售记录表”作为样本数据,编程实现一个房价预测系统。</p><p>要求:</p><p>\1. 矩阵运算部分采用TensorFlow实现,数据加载、输入、输出等可以根据需要采用Python/NumPy来实现。</p><p>\2. 提示用户输入商品房面积和房间数,并进行输入校验。合理的输入如下:</p><p>面积:20-500之间的实数</p><p>房间数:1-10之间的整数</p><p>如果输入正确,根据模型估计房价,并显示。</p><p>如果输入数据类型错误,或者输入数据范围不合理,根据错误类型提示,并等待用户重新输入。</p><p>\3. 可视化数据以及预测超平面</p><p>提示:TensorFlow中矩阵求逆函数tf.linalg.inv()</p><p>数据(符合对应关系):</p><p>面积:[137.97,104.50,100.00,124.32,79.20,99.00,124.00,114.00,106.69,138.05,53.75,46.91,68.00,63.02,81.26,86.21]</p><p>房间数:</p><p>[3,2,2,3,1,2,3,2,2,3,1,1,1,1,2,2]</p><p>销售价格:</p><p>[145.00,110.00,93.00,116.00,65.32,104.00,118.00,91.00,62.00,133.00,51.00,45.00,78.50,69.65,75.69,95.30]</p></blockquote><p>代码如下:</p><p>解析法:</p><pre><code class="python">import numpy as npimport tensorflow as tfimport matplotlib.pyplot as pltfrom mpl_toolkits.mplot3d import Axes3Dplt.rcParams['font.sans-serif']=['SimHei']x1=np.array([137.97,104.50,100.00,124.32,79.20,99.00,124.00,114.00,106.69,138.05,53.75,46.91,68.00,63.02,81.26,86.21])x2=np.array([3,2,2,3,1,2,3,2,2,3,1,1,1,1,2,2])y=np.array([145.00,110.00,93.00,116.00,65.32,104.00,118.00,91.00,62.00,133.00,51.00,45.00,78.50,69.65,75.69,95.30])x0=np.ones(len(x1))X=np.stack((x0,x1,x2),axis=1)Y=np.array(y).reshape(-1,1)Xt=np.transpose(X)XtX_1=np.linalg.inv(np.matmul(Xt,X))XtX_1Xt=np.matmul(XtX_1,Xt)W=np.matmul(XtX_1Xt,Y)W=W.reshape(-1)Y_pre=W[1]*x1+W[2]*x2+W[0]X=np.arange(20,150.1)Y=np.arange(1,10,0.1)X,Y=np.meshgrid(X,Y)Z=W[1]*X+W[2]*Y+W[0]fig=plt.figure()ax3d=Axes3D(fig)surf=ax3d.plot_surface(X,Y,Z,cmap="rainbow")ax3d.set_xlabel("X",color="r",fontsize=14)ax3d.set_ylabel("Y",color="r",fontsize=14)ax3d.set_zlabel("price",color="r",fontsize=14)ax3d.scatter(x1,x2,y,color="b",marker="*",label="label")ax3d.scatter(x1,x2,Y_pre,color="r",marker="+",label="pred")plt.suptitle("回归图",fontsize=20)print("请输入商品房面积和房间数,要求符合:\n面积:20-150之间的实数\n房间数:1-10之间的整数")a=float(input("请输入面积:"))b=int(input("请输入房间数:"))# 懒得做输入校验了pred=W[1]*a+W[2]*b+W[0]print("预测的价格是:%.3f"%pred)ax3d.scatter(a,b,pred,color="g",label="U_pred")plt.legend()plt.show()</code></pre><p>结果如下:</p><blockquote><p>请输入商品房面积和房间数,要求符合:<br>面积:20-150之间的实数<br>房间数:1-10之间的整数<br>请输入面积:>? 120<br>请输入房间数:>? 4<br>预测的价格是:133.480</p><p><img src="http://pan-yz.chaoxing.com/preview/showpreview_565801624826130432.html?v=1612827291000" alt="图片1"></p><p><img src="http://pan-yz.chaoxing.com/preview/showpreview_565801623249072128.html?v=1612827322000" alt="图片1"></p></blockquote><p>梯度下降法:</p><pre><code class="python">import numpy as npimport tensorflow as tfimport matplotlib.pyplot as pltfrom mpl_toolkits.mplot3d import Axes3Dplt.rcParams['font.sans-serif']=['SimHei']area=np.array([137.97,104.50,100.00,124.32,79.20,99.00,124.00,114.00,106.69,138.05,53.75,46.91,68.00,63.02,81.26,86.21])room=np.array([3,2,2,3,1,2,3,2,2,3,1,1,1,1,2,2])price=np.array([145.00,110.00,93.00,116.00,65.32,104.00,118.00,91.00,62.00,133.00,51.00,45.00,78.50,69.65,75.69,95.30])num=len(area)x0=np.ones(num)#归一化处理x1=(area-area.min())/(area.max()-area.min())x2=(room-room.min())/(room.max()-room.min())X=np.stack((x0,x1,x2),axis=1)Y=price.reshape(-1,1)learn_rate=0.2epoch=50display_step=5np.random.seed(612)W=tf.Variable(np.random.randn(3,1))mse=[]for i in range(0,epoch+1): with tf.GradientTape() as tape: Pred=tf.matmul(X,W) Loss=0.5*tf.reduce_mean(tf.square(Y-Pred)) mse.append(Loss) dL_dw=tape.gradient(Loss,W) W.assign_sub(learn_rate*dL_dw) if i % display_step==0: print("第%d轮的损失为:%f"%(i,Loss))plt.figure(figsize=(20,8),dpi=120)n=range(0,epoch+1)plt.plot(n,mse,label="损失函数")plt.legend(loc="best")plt.suptitle("损失曲线")plt.show()</code></pre><p><img src="http://pan-yz.chaoxing.com/preview/showpreview_567790281488953344.html?v=1613301355000" alt="损失可视化"></p><h2 id="练习12:"><a href="#练习12:" class="headerlink" title="练习12:"></a>练习12:</h2><blockquote><p>( 20分 )</p><p>使用波士顿房价数据集中的“低收入人口比例”属性,来训练和测试一元线性回归模型,并对模型进行可视化。</p><p>要求:程序+文本(记录下超参数的调试过程,并简要总结。)</p></blockquote><p>结论就是线性回归train不起来</p><p>首先,这个数据长这个样子:</p><p><img src="http://pan-yz.chaoxing.com/preview/showpreview_567849056738590720.html?v=1613315371000"></p><p>我用线性回归硬train了一发,然后显示预测数据nan(无穷大),然后查看损失,损失可视化显示训练到某一轮的时候突然增大,大概是梯度下降的时候出现问题了</p><p>怀疑是数据的问题,然后我就改了下,选择的数据改成了房间数(就改了数据集切片其他一点也没动)</p><p>然后成功了</p><pre><code class="python">import numpy as npimport tensorflow as tfimport matplotlib.pyplot as pltboston_housing=tf.keras.datasets.boston_housing(train_x,train_y),(test_x,test_y)=boston_housing.load_data()x_train=train_x[:,5]y_train=train_yx_test=test_x[:,5]y_test=test_ylearn_rate=0.04epoch=2000display_step=200np.random.seed(612)w=tf.Variable(np.random.randn(),dtype=tf.float32)b=tf.Variable(np.random.randn(),dtype=tf.float32)mse_train=[]mse_test=[]for i in range(0,epoch+1): with tf.GradientTape() as tape: pred_train=w*x_train+b loss=0.5*tf.reduce_mean(tf.square(y_train-pred_train)) pred_test=w*x_test+b loss_=0.5*tf.reduce_mean(tf.square(y_test-pred_test)) mse_train.append(loss) mse_test.append(loss_) dl_dw,dl_db=tape.gradient(loss,[w,b]) w.assign_sub(learn_rate*dl_dw) b.assign_sub(learn_rate*dl_db)plt.figure(figsize=(15,10),dpi=150)plt.rcParams['font.sans-serif'] = ['SimHei']plt.subplot(221)plt.scatter(x_train,y_train,color="blue",label="data")plt.plot(x_train,pred_train,color="red",label="predict")plt.legend(loc="upper right")plt.title("数据与预测曲线")plt.subplot(222)plt.plot(mse_train,color="blue",linewidth=3,label="train loss")plt.plot(mse_test,color="red",linewidth=1.5,label="test loss")plt.legend(loc="upper right")plt.title("损失可视化")plt.subplot(223)plt.plot(y_train,color="blue",marker="*",label="true_price")plt.plot(pred_train,color="red",marker=".",label="predict")plt.legend()plt.title("训练集对照")plt.subplot(224)plt.plot(y_test,color="blue",marker="*",label="true_price")plt.plot(pred_test,color="red",marker=".",label="predict")plt.legend()plt.title("测试集对照")plt.tight_layout()plt.show()</code></pre><p><img src="http://pan-yz.chaoxing.com/preview/showpreview_567850538144219136.html?v=1613315720000"></p><h2 id="练习13:"><a href="#练习13:" class="headerlink" title="练习13:"></a>练习13:</h2><blockquote><p>使用波士顿房价数据集中的所有属性,训练和测试多元线性回归模型,并可视化模型。</p><p>要求:程序+文本(记录下超参数的调试过程,并简要总结)</p></blockquote><pre><code class="python">import numpy as npimport tensorflow as tfimport matplotlib.pyplot as pltboston_housing=tf.keras.datasets.boston_housing(train_x,train_y),(test_x,test_y)=boston_housing.load_data()x_train=(train_x-train_x.min(axis=0))/(train_x.max(axis=0)-train_x.min(axis=0))y_train=train_yx_test=(test_x-test_x.min(axis=0))/(test_x.max(axis=0)-test_x.min(axis=0))y_test=test_yx0_train=np.ones(len(train_x)).reshape(-1,1)x0_test=np.ones(len(test_x)).reshape(-1,1)X_train=tf.cast(tf.concat([x0_train,x_train],axis=1),tf.float32)X_test=tf.cast(tf.concat([x0_test,x_test],axis=1),tf.float32)Y_train=tf.constant(y_train.reshape(-1,1),tf.float32)Y_test=tf.constant(y_test.reshape(-1,1),tf.float32)learn_rate=0.01epoch=2000np.random.seed(612)w=tf.Variable(np.random.randn(14,1),dtype=tf.float32)b=tf.Variable(np.random.randn(14,1),dtype=tf.float32)mse_train=[]mse_test=[]for i in range(0,epoch+1): with tf.GradientTape() as tape: pred_train=tf.matmul(X_train,w) loss=0.5*tf.reduce_mean(tf.square(Y_train-pred_train)) pred_test=tf.matmul(X_test,w) loss_=0.5*tf.reduce_mean(tf.square(Y_test-pred_test)) mse_train.append(loss) mse_test.append(loss_) dl_dw=tape.gradient(loss,w) w.assign_sub(learn_rate*dl_dw)plt.figure(figsize=(15,4),dpi=150)plt.rcParams['font.sans-serif'] = ['SimHei']plt.subplot(131)plt.plot(mse_train,color="blue",linewidth=3,label="train loss")plt.plot(mse_test,color="red",linewidth=1.5,label="test loss")plt.legend(loc="upper right")plt.title("损失可视化")plt.subplot(132)plt.plot(y_train,color="blue",marker="*",label="true_price")plt.plot(pred_train,color="red",marker=".",label="predict")plt.legend()plt.title("训练集对照")plt.subplot(133)plt.plot(y_test,color="blue",marker="*",label="true_price")plt.plot(pred_test,color="red",marker=".",label="predict")plt.legend()plt.title("测试集对照")plt.tight_layout()plt.show()</code></pre><p><img src="http://pan-yz.chaoxing.com/preview/showpreview_567855084990627840.html?v=1613316805000"></p><p>可见预测比单一数据要好</p><h2 id="练习14:"><a href="#练习14:" class="headerlink" title="练习14:"></a>练习14:</h2><blockquote><p>( 15分 )</p><p>选择不同的2种属性组合,区分山鸢尾和维吉尼亚鸢尾,编写程序,记录并分析结果,给出总结。</p><p>(1) 编写代码 (8分)</p><p>(2) 记录结果 (5分)</p><p> 比较选择不同属性组合时的学习率、迭代次数、以及在训练集和测试集上的交叉熵损失和准确率,以表格或合适的图表形式展示。</p><p>(3) 总结 (2分)</p><p> 采用不同的属性组合效果是否相同,如果相同或者不同,对你有什么启发。</p></blockquote><p><img src="https://edu-image.nosdn.127.net/AE671975EBF9545FCA03C9576D3FFA7A.png?imageView&thumbnail=890x0&quality=100" alt="示例"></p><p>由这张之前的图(蓝色和绿色是我们想区分的,可见还是很容易的)</p><p>于是我们选取花瓣长与花瓣宽开始训练</p><p>代码如下:</p><pre><code class="python">import numpy as npimport tensorflow as tfimport matplotlib.pyplot as pltimport matplotlib as mplfrom sklearn.datasets import load_irisfrom sklearn.model_selection import train_test_splitplt.rcParams['font.sans-serif'] = ['SimHei']plt.rcParams['axes.unicode_minus'] = Falseiris=load_iris()x_train,x_test,y_train,y_test=train_test_split(iris.data,iris.target,test_size=0.2,random_state=22)x_train=x_train[y_train!=1][:,2:4]y_train=y_train[y_train!=1]for i in range(len(y_train)): if y_train[i]==2: y_train[i]=1x_test=x_test[y_test!=1][:,2:4]y_test=y_test[y_test!=1]for i in range(len(y_test)): if y_test[i]==2: y_test[i]=1#数据处理区分x_train=x_train-np.mean(x_train,axis=0)#中心化数据x0_train=np.ones(len(x_train)).reshape(-1,1)X=tf.cast(tf.concat((x0_train,x_train),axis=1),tf.float32)Y=tf.cast(y_train.reshape(-1,1),tf.float32)learn_rate=0.2epoch=100display_step=30np.random.seed(612)W=tf.Variable(np.random.randn(3,1),dtype=tf.float32)ce =[]acc=[]for i in range(0,epoch): with tf.GradientTape() as tap: Pred=1/(1+tf.exp(-tf.matmul(X,W))) Loss=-tf.reduce_mean(Y*tf.math.log(Pred)+(1-Y)*tf.math.log(1-Pred)) accuracy=tf.reduce_mean(tf.cast(tf.equal(tf.where(Pred.numpy()<0.5,0.,1.),Y),tf.float32)) ce.append(Loss) acc.append(accuracy) dL_dW=tap.gradient(Loss,W) W.assign_sub(learn_rate*dL_dW) if i % display_step ==0: print("i: %d, Acc:%f, Loss:%f"%(i,accuracy,Loss))plt.figure(figsize=(20,8),dpi=150)plt.subplot(121)plt.plot(ce,color="b",label="Loss")plt.plot(acc,color="r",label="acc")plt.legend()plt.title("损失与准确率")plt.show()plt.subplot(122)cm_pt=mpl.colors.ListedColormap(["blue","red"])plt.scatter(x_train[:,0],x_train[:,1],c=y_train,cmap=cm_pt)x_=[-1.5,1.5]y_=-(W[1]*x_+W[0])/W[2]plt.plot(x_,y_,color='r')plt.title("数据与决策平面")plt.tight_layout()plt.show()</code></pre><p><img src="http://pan-yz.chaoxing.com/preview/showpreview_567881528459591680.html?v=1613323111000" alt="数据可视化结果"></p><h2 id="练习15:"><a href="#练习15:" class="headerlink" title="练习15:"></a>练习15:</h2><blockquote><p>( 20分 )</p><p>分别选择2种、3种和4种属性,编写程序,区分变色鸢尾、山鸢尾和维吉尼亚鸢尾。记录和分析实验结果,并给出总结。</p></blockquote><p>这里属于多分类,这里我们 同样选取花瓣长与花瓣宽</p><pre><code class="python">import matplotlib.pyplot as pltimport tensorflow as tfimport numpy as npimport matplotlib as mplfrom sklearn.datasets import load_irisfrom sklearn.model_selection import train_test_splitplt.rcParams['font.sans-serif'] = ['SimHei']plt.rcParams['axes.unicode_minus'] = Falseiris=load_iris()x_train,x_test,y_train,y_test=train_test_split(iris.data,iris.target,test_size=0.2,random_state=22)x_train=x_train[:,2:4]y_train=y_trainx_test=x_test[:,2:4]y_test=y_test#数据处理区分x0_train=np.ones(len(x_train)).reshape(-1,1)x0_test=np.ones(len(x_test)).reshape(-1,1)X_train=tf.cast(tf.concat([x0_train,x_train],axis=1),tf.float32)Y_train=tf.one_hot(tf.constant(y_train,dtype=tf.int32),3)Y_test=tf.one_hot(tf.constant(y_test,dtype=tf.int32),3)X_test=tf.cast(tf.concat([x0_test,x_test],axis=1),tf.float32)#处理数据learn_rate=0.2epoch=500display_step=100np.random.seed(612)W=tf.Variable(np.random.randn(3,3),dtype=tf.float32)acc=[]cce=[]acc_=[]cce_=[]for i in range(epoch+1): with tf.GradientTape() as tape: pred=tf.nn.softmax(tf.matmul(X_train,W)) Loss_train=-tf.reduce_mean(Y_train*tf.math.log(pred)) pred_= tf.nn.softmax(tf.matmul(X_test, W)) Loss_test = -tf.reduce_mean(Y_test * tf.math.log(pred_)) accuracy = tf.reduce_mean(tf.cast(tf.equal(tf.argmax(pred.numpy() ,axis=1), y_train), tf.float32)) accuracy_= tf.reduce_mean(tf.cast(tf.equal(tf.argmax(pred_.numpy(), axis=1), y_test), tf.float32)) #argmax()返回最大值索引号,所以这里校验时不用独热码而是用原始数据 acc.append(accuracy) cce.append(Loss_train) acc_.append(accuracy_) cce_.append(Loss_test) dl_dw=tape.gradient(Loss_train,W) W.assign_sub(learn_rate*dl_dw) if i%display_step ==0: print("i: %d, trainAcc:%f, trainLoss:%f"%(i,accuracy,Loss_train)) print(" testAcc:%f, testLoss:%f" % (accuracy_, Loss_test))plt.figure(figsize=(20,24),dpi=150)plt.subplot(221)plt.plot(cce,color="b",label="训练集损失")plt.plot(cce_,color="r",label="测试集损失")plt.legend()plt.title("数据集损失")plt.subplot(222)plt.plot(cce,color="b",label="训练集准确率")plt.plot(cce_,color="r",label="测试集准确率")plt.legend()plt.title("数据集准确率")plt.subplot(223)M=500x1_min,x2_min=x_train.min(axis=0)x1_max,x2_max=x_train.max(axis=0)t1=np.linspace(x1_min,x1_max,M)t2=np.linspace(x2_min,x2_max,M)m1,m2=np.meshgrid(t1,t2)m0=np.ones(M*M)X_=tf.cast(np.stack((m0,m1.reshape(-1),m2.reshape(-1)),axis=1),tf.float32)Y_=tf.nn.softmax(tf.matmul(X_,W))Y_=tf.argmax(Y_.numpy(),axis=1)n=tf.reshape(Y_,m1.shape)cm_bg=mpl.colors.ListedColormap(["#A0FFA0","#FFA0A0","#A0A0FF"])plt.pcolormesh(m1,m2,n,cmap=cm_bg)plt.scatter(x_train[:,0],x_train[:,1],c=y_train,cmap="brg")plt.title("训练数据与决策平面")plt.subplot(224)cm_bg_=mpl.colors.ListedColormap(["#A0FFA0","#FFA0A0","#A0A0FF"])plt.pcolormesh(m1,m2,n,cmap=cm_bg)plt.scatter(x_test[:,0],x_test[:,1],c=y_test,cmap="brg")plt.title("测试数据与决策平面")plt.tight_layout()plt.show()</code></pre><blockquote><p>输出如下:</p><p>i: 0, trainAcc:0.366667, trainLoss:1.422851<br> testAcc:0.200000, testLoss:1.845798<br>i: 100, trainAcc:0.683333, trainLoss:0.237928<br> testAcc:0.666667, testLoss:0.234590<br>i: 200, trainAcc:0.808333, trainLoss:0.194367<br> testAcc:0.833333, testLoss:0.200174<br>i: 300, trainAcc:0.858333, trainLoss:0.170748<br> testAcc:0.866667, testLoss:0.180454<br>i: 400, trainAcc:0.875000, trainLoss:0.155550<br> testAcc:0.900000, testLoss:0.167200<br>i: 500, trainAcc:0.916667, trainLoss:0.144651<br> testAcc:0.933333, testLoss:0.157360</p></blockquote><p>画出来图如下,有点丑了,但还算能看:</p><p><img src="http://pan-yz.chaoxing.com/preview/showpreview_568862217696559104.html?v=1613556927000"></p><p>现在有个问题,就是这个决策平面显然并不是我们想要的,直觉告诉我,应该平面像是这样分类的准确性才会高一点:</p><p><img src="http://pan-yz.chaoxing.com/preview/showpreview_568863457222438912.html?v=1613557222000"></p><p>特别是在蓝绿两个类之间,不该是贯穿的切法,而应该是横切,认为是训练不充分,于是把训练轮数提高8倍到4000轮:</p><p>结果是:</p><blockquote><p>i: 0, trainAcc:0.366667, trainLoss:1.422851<br> testAcc:0.200000, testLoss:1.845798<br>i: 100, trainAcc:0.683333, trainLoss:0.237928<br> testAcc:0.666667, testLoss:0.234590<br>i: 200, trainAcc:0.808333, trainLoss:0.194367<br> testAcc:0.833333, testLoss:0.200174<br>i: 300, trainAcc:0.858333, trainLoss:0.170748<br> testAcc:0.866667, testLoss:0.180454<br>i: 400, trainAcc:0.875000, trainLoss:0.155550<br> testAcc:0.900000, testLoss:0.167200<br>i: 500, trainAcc:0.916667, trainLoss:0.144651<br> testAcc:0.933333, testLoss:0.157360</p><p> ……………….</p><p>i: 3800, trainAcc:0.966667, trainLoss:0.068734<br> testAcc:0.933333, testLoss:0.081017<br>i: 3900, trainAcc:0.966667, trainLoss:0.067992<br> testAcc:0.933333, testLoss:0.080229<br>i: 4000, trainAcc:0.966667, trainLoss:0.067277<br> testAcc:0.933333, testLoss:0.079468 </p></blockquote><p>虽然训练集上升并且没有产生过拟合但是测试集的准确率已经不动了(可能因为测试的数据少),不过loss在下降,往后非常慢的降</p><p><img src="http://pan-yz.chaoxing.com/preview/showpreview_568866095669407744.html?v=1613557851000"></p><p>某种意义上是往着我们期望的方向发展,应该是达到了目的,也许会有更好的方法</p><h2 id="练习16:"><a href="#练习16:" class="headerlink" title="练习16:"></a>练习16:</h2><blockquote><p>使用多层神经网络实现鸢尾花分类,编写程序,尝试改变隐含层层数、隐含层中节点数以及其他超参数,记录并分析实验结果,给出总结。</p><p>要求:</p><p>(1)编写程序(7分)</p><p>(2)记录超参数的调整过程和结果(3分)</p><p>(3)总结(5分)</p><p>比较时间代价、分析不同超参数对结果准确性的影响</p></blockquote><pre><code class="python">import matplotlib.pyplot as pltimport tensorflow as tfimport numpy as npimport matplotlib as mplfrom sklearn.datasets import load_irisfrom sklearn.model_selection import train_test_splitplt.rcParams['font.sans-serif'] = ['SimHei']plt.rcParams['axes.unicode_minus'] = Falseiris=load_iris()x_train,x_test,y_train,y_test=train_test_split(iris.data,iris.target,test_size=0.2,random_state=22)x_train=x_train[:,0:4]y_train=y_trainx_test=x_test[:,0:4]y_test=y_test#数据处理区分x_train=x_train-np.mean(x_train,axis=0)x_test=x_test-np.mean(x_test,axis=0)X_train=tf.cast(x_train,tf.float32)Y_train=tf.one_hot(tf.constant(y_train,dtype=tf.int32),3)Y_test=tf.one_hot(tf.constant(y_test,dtype=tf.int32),3)X_test=tf.cast(x_test,tf.float32)#处理数据learn_rate=0.2epoch=4000display_step=100np.random.seed(612)W1=tf.Variable(np.random.randn(4,16),dtype=tf.float32)B1=tf.Variable(tf.zeros([16]),dtype=tf.float32)W2=tf.Variable(np.random.randn(16,3),dtype=tf.float32 )B2=tf.Variable(tf.zeros([3]),dtype=tf.float32)acc=[]cce=[]acc_=[]cce_=[]for i in range(epoch+1): with tf.GradientTape() as tape: Hidden_train=tf.nn.relu(tf.matmul(X_train,W1)+B1) pred=tf.nn.softmax(tf.matmul(Hidden_train,W2)+B2) Loss_train=tf.reduce_mean(tf.keras.losses.categorical_crossentropy(y_true=Y_train,y_pred=pred)) Hidden_test = tf.nn.relu(tf.matmul(X_test, W1) + B1) pred_= tf.nn.softmax(tf.matmul(Hidden_test, W2) + B2) Loss_test = tf.reduce_mean(tf.keras.losses.categorical_crossentropy(y_true=Y_test, y_pred=pred_)) accuracy = tf.reduce_mean(tf.cast(tf.equal(tf.argmax(pred.numpy() ,axis=1), y_train), tf.float32)) accuracy_= tf.reduce_mean(tf.cast(tf.equal(tf.argmax(pred_.numpy(), axis=1), y_test), tf.float32)) #argmax()返回最大值索引号,所以这里校验时不用独热码而是用原始数据 acc.append(accuracy) cce.append(Loss_train) acc_.append(accuracy_) cce_.append(Loss_test) grade=tape.gradient(Loss_train,[W1,B1,W2,B2]) W1.assign_sub(learn_rate*grade[0]) B1.assign_sub(learn_rate * grade[1]) W2.assign_sub(learn_rate * grade[2]) B2.assign_sub(learn_rate * grade[3]) if i>0 and cce_[i]>cce_[i-1]: print("--------------------stop at %d epoch-----------------------"%i) break if i%display_step ==0: print("i: %d, trainAcc:%f, trainLoss:%f"%(i,accuracy,Loss_train)) print(" testAcc:%f, testLoss:%f" % (accuracy_, Loss_test))plt.figure(figsize=(20,8),dpi=150)plt.subplot(121)plt.plot(cce,color="b",label="训练集损失")plt.plot(cce_,color="r",label="测试集损失")plt.legend()plt.title("数据集损失")plt.subplot(122)plt.plot(acc,color="b",label="训练集准确率")plt.plot(acc_ ,color="r",label="测试集准确率")plt.legend()plt.title("数据集准确率")plt.tight_layout()plt.show()</code></pre><p>这次同样训练了4k轮,结果很amzing啊</p><p>过拟合了</p><p><img src="http://pan-yz.chaoxing.com/preview/showpreview_571008578306138112.html?v=1614068655000"></p><p>看起来使用relu优化的两层神经网络好像没有在感知机中表现的好………,因为最后测试集的准确率连80%都没有</p><p>不过relu下降的倒是很快,现在用early_stopping的方法控制,即当验证集损失开始上升时停止训练(这里就把测试集当验证集了</p><pre><code class="python"> if i>0 and cce_[i]>cce_[i-1]: print("--------------------stop at %d epoch-----------------------"%i) break</code></pre><p>输出是:</p><blockquote><p>i: 0, trainAcc:0.450000, trainLoss:2.028374<br> testAcc:0.233333, testLoss:2.409625<br>——————–stop at 30 epoch———————–</p></blockquote><p>30轮就训练完了,可见下降相当之快啊,就是最后泛化性有点差</p><p><img src="http://pan-yz.chaoxing.com/preview/showpreview_571013689459200000.html?v=1614069875000"></p><h2 id="练习17:"><a href="#练习17:" class="headerlink" title="练习17:"></a>练习17:</h2><blockquote><p>使用TensorFlow中的keras库,实现Minist手写数字识别。编写程序,尝试调整神经网络的层数、节点个数以及优化器等参数,记录并分析实验结果,保存最佳训练模型,给出总结。</p><p>要求:</p><p>(1)编写程序(7分)</p><p>(2)记录参数的调整过程和结果(3分)</p><p>(3)总结。(5分)</p><p>从准确率、时间效率等方面对实验结果进行分析</p></blockquote><pre><code class="python">import tensorflow as tfimport numpy as npimport matplotlib.pyplot as pltmnist=tf.keras.datasets.mnist(train_x,train_y),(test_x,test_y)=mnist.load_data()# X_train=train_x.reshape((60000,28*28))# X_test=test_x.reshape((10000,28*28))#如果没有拉伸的层就用这个语句X_train,X_test=tf.cast(train_x/255.0,tf.float32),tf.cast(test_x/255.0,tf.float32)Y_train,Y_test=tf.cast(train_y,tf.int16),tf.cast(test_y,tf.int16)model=tf.keras.Sequential()model.add(tf.keras.layers.Flatten(input_shape=(28,28)))model.add(tf.keras.layers.Dense(128,activation="relu"))model.add(tf.keras.layers.Dense(10,activation="softmax"))model.compile(optimizer="adam",loss="sparse_categorical_crossentropy",metrics=['sparse_categorical_accuracy'])model.fit(X_train,Y_train,batch_size=64,epochs=5,validation_split=0.2)model.evaluate(X_test,Y_test,verbose=2)y_pred=model.predict_classes(X_test[0:1000])plt.rcParams['font.sans-serif']=['SimHei']plt.rcParams['axes.unicode_minus']=Falseplt.figure(dpi=150)for i in range(25): num=np.random.randint(0,1000) plt.subplot(5,5,i+1) plt.axis("off") plt.imshow(test_x[num],cmap="gray") title="y="+str(test_y[num])+"\ny_pred="+str(y_pred[num]) plt.title(title)plt.tight_layout()plt.suptitle("手写数字样本预测 ",x=0.5,y=1.02, fontsize=20)plt.show()</code></pre><p>训练5轮的结果:</p><blockquote><p>Epoch 1/5<br>750/750 [==============================] - 2s 2ms/step - loss: 0.5641 - sparse_categorical_accuracy: 0.8408 - val_loss: 0.1859 - val_sparse_categorical_accuracy: 0.9454<br>Epoch 2/5<br>750/750 [==============================] - 1s 1ms/step - loss: 0.1547 - sparse_categorical_accuracy: 0.9554 - val_loss: 0.1272 - val_sparse_categorical_accuracy: 0.9621<br>Epoch 3/5<br>750/750 [==============================] - 1s 1ms/step - loss: 0.1054 - sparse_categorical_accuracy: 0.9691 - val_loss: 0.1139 - val_sparse_categorical_accuracy: 0.9653<br>Epoch 4/5<br>750/750 [==============================] - 1s 1ms/step - loss: 0.0788 - sparse_categorical_accuracy: 0.9764 - val_loss: 0.0931 - val_sparse_categorical_accuracy: 0.9721<br>Epoch 5/5<br>750/750 [==============================] - 1s 1ms/step - loss: 0.0609 - sparse_categorical_accuracy: 0.9825 - val_loss: 0.0902 - val_sparse_categorical_accuracy: 0.9720<br>313/313 - 0s - loss: 0.0823 - sparse_categorical_accuracy: 0.9748</p></blockquote><p>可见下降很快</p><p><img src="http://pan-yz.chaoxing.com/preview/showpreview_571308404708585472.html?v=1614140140000"></p><p>训练加到100轮后,几次训练集达到100%准确率,时间太长就不展示了</p><p>总的来说使用tensorflow的高阶api不仅代码量少了很多而且更加准确</p><h2 id="练习18:"><a href="#练习18:" class="headerlink" title="练习18:"></a>练习18:</h2><blockquote><p>( 10分 )</p><p>编写程序,使用作业1中训练好的模型,实现对自制手写数字数据集的识别。</p><p>要求:</p><p>(1) 将下面名为<strong>“自制手写数字.zip”</strong>压缩包中自制的手写数字转换为28*28的数组形式,并将数字放在图片中心。(5分)</p><p>(2) 加载作业1中训练好的模型,使用该模型对要求(1)中的手写数字进行识别。(5分)</p><p><strong>提示:</strong></p><p>图像操作部分可参考第7讲“数字图像基础”</p><p>可能用到的函数:</p><p>裁剪图像:crop() </p><p>转换成二值图像 :convert()</p><p>改变大小:resize()</p></blockquote><p>训练模型:</p><pre><code class="python">import tensorflow as tfimport numpy as npmnist=tf.keras.datasets.mnist(train_x,train_y),(test_x,test_y)=mnist.load_data()X_train,X_test=tf.cast(train_x/255.0,tf.float32),tf.cast(test_x/255.0,tf.float32)Y_train,Y_test=tf.cast(train_y,tf.int16),tf.cast(test_y,tf.int16)model=tf.keras.Sequential()model.add(tf.keras.layers.Flatten(input_shape=(28,28)))model.add(tf.keras.layers.Dense(128,activation="relu"))model.add(tf.keras.layers.Dense(10,activation="softmax"))model.compile(optimizer="adam",loss="sparse_categorical_crossentropy",metrics=['sparse_categorical_accuracy'])model.fit(X_train,Y_train,batch_size=64,epochs=100,validation_split=0.2)#训练100轮,由于没有用GPU加速所以每轮用了1smodel.evaluate(X_test,Y_test,verbose=2)model.save("mist_model.h5")</code></pre><p>使用模型:</p><pre><code class="python">import tensorflow as tfimport numpy as npimport matplotlib.pyplot as pltmnist=tf.keras.datasets.mnist(train_x,train_y),(test_x,test_y)=mnist.load_data()X_train,X_test=tf.cast(train_x/255.0,tf.float32),tf.cast(test_x/255.0,tf.float32)Y_train,Y_test=tf.cast(train_y,tf.int16),tf.cast(test_y,tf.int16)model=tf.keras.models.load_model("mist_model.h5")y_pred=model.predict_classes(X_test[0:1000])plt.rcParams['font.sans-serif']=['SimHei']plt.rcParams['axes.unicode_minus']=Falseplt.figure(dpi=150)for i in range(25): num=np.random.randint(0,1000) plt.subplot(5,5,i+1) plt.axis("off") plt.imshow(test_x[num],cmap="gray") title="y="+str(test_y[num])+"\ny_pred="+str(y_pred[num]) plt.title(title)plt.tight_layout()plt.suptitle("手写数字样本预测 ",x=0.5,y=1.02, fontsize=20)plt.show()</code></pre><p><img src="http://pan-yz.chaoxing.com/preview/showpreview_571374154019880960.html?v=1614155820000"></p><p>说明保存成功,并且可以应用了</p><p>现在开始实际应用:</p><p>首先这是我们的测试样本:</p><p><img src="http://pan-yz.chaoxing.com/preview/showpreview_571375447424217088.html?v=1614156125000"></p><p>我们先处理下图片:</p><p>基本处理操作包括:</p><ul><li>加载图像</li><li>处理图像尺寸变成28*28</li><li>二值化图像(事实上是灰度化)</li><li>必要时对图像反色处理(因为这里是黑笔写的所以与MNIST不同)</li></ul><pre><code class="python">import matplotlib.pyplot as pltfrom PIL import Imageimport tensorflow as tfplt.rcParams['font.sans-serif']=['SimHei']plt.rcParams['axes.unicode_minus']=Falseplt.figure(figsize=(10,4),dpi=150)MyData=[]for i in range(9): path="D:\code\ML\data\手写数字\\"+str(i+1)+".png" MyData.append(Image.open(path))for i in range(9): plt.subplot(2,5,i+1) plt.axis("off") plt.imshow(MyData[i], cmap="gray")</code></pre><p>单个图片数据的形状:</p><pre><code class="python">for i in range(9): print(MyData[0].shape)</code></pre><blockquote><p>(93, 73, 4)<br>(93, 73, 4)<br>(93, 73, 4)<br>(93, 73, 4)<br>(93, 73, 4)<br>(93, 73, 4)<br>(93, 73, 4)<br>(93, 73, 4)<br>(93, 73, 4)</p></blockquote><p>可见这是一个尺寸93*73的rgba彩色文件,我们的目标是要把每个文件处理成28x28的二值文件</p><pre><code class="python">import matplotlib.pyplot as pltfrom PIL import Imageimport tensorflow as tfimport numpy as npplt.rcParams['font.sans-serif']=['SimHei']plt.rcParams['axes.unicode_minus']=FalseMyData=[]for i in range(9): path="D:\code\ML\data\手写数字\\"+str(i+1)+".png" Img=Image.open(path) Img=Img.convert("1")#二值化图片 Img=Img.resize((28,28))#转换尺寸 Img=np.array(Img) MyData.append(Img)for i in range(9): plt.subplot(2,5,i+1) plt.axis("off") plt.imshow(MyData[i], cmap="gray")</code></pre><p>但是,加载出来的图片却是这样的:</p><p><img src="http://pan-yz.chaoxing.com/preview/showpreview_571390714891927552.html?v=1614159768000"></p><p>这是个啥玩意。。。。。。,噪声太多了</p><p>看来不是变成二值化啊,于是转换成灰度图</p><p><img src="http://pan-yz.chaoxing.com/preview/showpreview_571391504861474816.html?v=1614159954000"></p><p>效果好很多了,但不是我们想要的,因为我们训练的模型使用的数据是数字白,背景黑,而我们目标数据是数字黑背景白,所以要进行一个反色处理,结果就是这样</p><p><img src="http://pan-yz.chaoxing.com/preview/showpreview_571392683166363648.html?v=1614160236000" alt="与MNIST几乎一样了"></p><p>然后就可以套用模型辣</p><p>结果是:</p><p><img src="http://pan-yz.chaoxing.com/preview/showpreview_571395575248957440.html?v=1614161232000"></p><p>这机器学了个寂寞啊。。。。。。</p><p>但是在测试集上准确率的确是我们想要的,为什么应用起来就有问题了呢</p><p>观察了下手写数字样本:</p><p><img src="http://pan-yz.chaoxing.com/preview/showpreview_571399258676772864.html?v=1614161804000"></p><p>和我们处理的图片比,可见图片中数字的部分占比比我们制作图的要大,应该是我的图还缺少一个裁切主体的部分</p><p>于是把图片裁剪了下:</p><p><img src="http://pan-yz.chaoxing.com/preview/showpreview_571392683166363648.html?v=1614160236000" alt="裁剪前"></p><p><img src="http://pan-yz.chaoxing.com/preview/showpreview_571403782689386496.html?v=1614162881000" alt="裁剪后"></p><p>然后预测。。。。。</p><p><img src="http://pan-yz.chaoxing.com/preview/showpreview_571404697690816512.html?v=1614163099000" alt="裁剪处理后的"></p><p><img src="http://pan-yz.chaoxing.com/preview/showpreview_571405484810211328.html?v=1614163287000" alt="对比之前"></p><p>好歹对了一个……….准确率从10%提升到了20%,可喜可贺可喜可贺(泪目)</p><p>现在分析问题原因可能在于我所用的数据笔画太细,而训练用的数据笔画太粗,也就是说训练的时候学到了不该考虑进去的征兆,很可能是训练次数过大</p><p>调低训练次数到30次,再使用模型,但是并没有用。。。。。。</p><p>可能还是有不足吧,以后学习了更多在再来挑战</p><p>代码在这</p><pre><code class="python">import matplotlib.pyplot as pltfrom PIL import Imageimport tensorflow as tfimport numpy as npplt.rcParams['font.sans-serif']=['SimHei']plt.rcParams['axes.unicode_minus']=FalseMyData=[]for i in range(9): path="D:\code\ML\data\手写数字\\"+str(i+1)+".png" Img=Image.open(path) Img=Img.convert("L")#二值化图片 Img=Img.resize((73,73))#转换尺寸 Img=Img.crop((9,9,63,63)) Img = Img.resize((28, 28)) # 转换尺寸 Img=np.array(Img) Img = 255 - Img # 图像反色 MyData.append(Img)MyData=np.array(MyData)MyData=tf.cast(MyData/255.0,tf.float32)#归一化处理model=tf.keras.models.load_model("mist_model.h5")y_pred=np.argmax(model.predict(MyData[0:9]),axis=1)for i in range(9): plt.subplot(2,5,i+1) plt.axis("off") path = "D:\code\ML\data\手写数字\\" + str(i + 1) + ".png" Img = Image.open(path) plt.imshow(Img,cmap="gray") title="pred="+str(y_pred[i]) plt.title(title)plt.tight_layout()plt.suptitle("自制手写数字样本预测 ",x=0.5,y=1.02, fontsize=20)plt.show()</code></pre><p>自此整个课程的作业就结束了,接下来要学习的是北京大学的Tensorflow课程</p><h3 id="尝试1"><a href="#尝试1" class="headerlink" title="尝试1"></a>尝试1</h3><p>重新制作了数据集,图片更加纯净而且笔画也更加粗</p><p>结果是:</p><p><img src="http://pan-yz.chaoxing.com/preview/showpreview_571451552705400832.html?v=1614174290000"></p><p>实验结果提升到40%诶</p><p>训练20轮的效果比100要好点</p><pre><code class="python">import matplotlib.pyplot as pltfrom PIL import Imageimport tensorflow as tfimport numpy as npplt.rcParams['font.sans-serif']=['SimHei']plt.rcParams['axes.unicode_minus']=FalseMyData=[]for i in range(10): path="D:\code\ML\data\手写数字\\"+str(i)+".png" Img=Image.open(path) Img=Img.convert("L")#二值化图片 Img=Img.resize((73,73))#转换尺寸 Img=Img.crop((9,9,63,63)) Img = Img.resize((28, 28)) # 转换尺寸 Img=np.array(Img) Img = 255 - Img # 图像反色 MyData.append(Img)MyData=np.array(MyData)MyData=tf.cast(MyData/255.0,tf.float32)#归一化处理model=tf.keras.models.load_model("mist_model.h5")y_pred=np.argmax(model.predict(MyData[0:10]),axis=1)for i in range(10): plt.subplot(2,5,i+1) plt.axis("off") path = "D:\code\ML\data\手写数字\\" + str(i) + ".png" Img = Image.open(path) plt.imshow(MyData[i],cmap="gray") title="pred="+str(y_pred[i]) plt.title(title)plt.tight_layout()plt.suptitle("自制手写数字样本预测 ",x=0.5,y=1.02, fontsize=20)plt.show()</code></pre><h3 id="针对练习18的最终解决方案"><a href="#针对练习18的最终解决方案" class="headerlink" title="针对练习18的最终解决方案"></a>针对练习18的最终解决方案</h3><p>今天看了北京大学的mooc展示后我发现一个问题</p><p>tensorflow提供的图片和图片矩阵是这样的:</p><p><img src="http://pan-yz.chaoxing.com/preview/showpreview_572385229865652224.html?v=1614396873000"></p><p><img src="http://pan-yz.chaoxing.com/preview/showpreview_572385228716888064.html?v=1614396919000"></p><p>而要识别的图片经过灰度化以及裁剪反色等处理后,图片以及矩阵是这样的:</p><p><img src="http://pan-yz.chaoxing.com/preview/showpreview_572385970097324032.html?v=1614397050000"></p><p><img src="http://pan-yz.chaoxing.com/preview/showpreview_572385967886036992.html?v=1614397075000"></p><p>也就是说我们处理后的图片还不够纯净,需要对图片进行进一步清洗</p><p>把要识别的图片中所有小于102的数据变成0以后</p><p><img src="http://pan-yz.chaoxing.com/preview/showpreview_572386742274048000.html?v=1614397234000"></p><p>图片纯净多了</p><p>调高阈值到130,进一步清洗,再对每个图片应用清洗的方法后,再套上模型</p><p>这一次准确率大幅度提高:</p><p><img src="http://pan-yz.chaoxing.com/preview/showpreview_572387651691442176.html?v=1614397451000"></p><p>而且判别错误的两个就算判别有误也比原来5更加合理</p><p>至于为什么8和9会判错,原因应该是8和9整体亮度比其他低,而我们用的是统一的阈值,所以更脏的8和9就没有洗干净</p><p>放代码</p><pre><code class="python">import matplotlib.pyplot as pltfrom PIL import Imageimport tensorflow as tfimport numpy as npplt.rcParams['font.sans-serif']=['SimHei']plt.rcParams['axes.unicode_minus']=FalseMyData=[]mnist=tf.keras.datasets.mnist(x1,y1),(x2,y2)=mnist.load_data()for i in range(9): path="D:\code\ML\data\手写数字_\\"+str(i+1)+".png" Img=Image.open(path) Img=Img.convert("L")#二值化图片 Img=Img.resize((73,73))#转换尺寸 Img=Img.crop((9,9,63,63)) Img = Img.resize((28, 28)) # 转换尺寸 Img=np.array(Img) Img = 255 - Img # 图像反色 MyData.append(Img)for k in range(9): for i in range(28): for j in range(28): if MyData[k][i][j] <130: MyData[k][i][j]=0MyData=np.array(MyData)MyData=tf.cast(MyData/255.0,tf.float32)#归一化处理model=tf.keras.models.load_model("mist_model_.h5")y_pred=np.argmax(model.predict(MyData[0:9]),axis=1)for i in range(9): plt.subplot(2,5,i+1) plt.axis("off") path = "D:\code\ML\data\手写数字_\\" + str(i + 1) + ".png" Img = Image.open(path) plt.imshow(Img,cmap="gray") title="pred="+str(y_pred[i]) plt.title(title)plt.tight_layout()plt.suptitle("自制手写数字样本预测 ",x=0.5,y=1.02, fontsize=20)plt.show()</code></pre>]]></content>
<summary type="html"><h1 id="神经网络与深度学习作业"><a href="#神经网络与深度学习作业" class="headerlink" title="神经网络与深度学习作业"></a>神经网络与深度学习作业</h1><p>大垃圾一年没写python辣(其实去年也学的稀烂),今年要机器学习不</summary>
<category term="Python" scheme="http://sweetheart.nefu.site/categories/Python/"/>
<category term="Python" scheme="http://sweetheart.nefu.site/tags/Python/"/>
</entry>
<entry>
<title>李宏毅机器学习笔记</title>
<link href="http://sweetheart.nefu.site/2021/01/15/%E6%9D%8E%E5%AE%8F%E6%AF%85%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"/>
<id>http://sweetheart.nefu.site/2021/01/15/%E6%9D%8E%E5%AE%8F%E6%AF%85%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/</id>
<published>2021-01-14T16:57:47.000Z</published>
<updated>2021-01-14T16:58:45.287Z</updated>
<category term="machin learning" scheme="http://sweetheart.nefu.site/categories/machin-learning/"/>
<category term="machin learning" scheme="http://sweetheart.nefu.site/tags/machin-learning/"/>
</entry>
<entry>
<title>寒假算法训练</title>
<link href="http://sweetheart.nefu.site/2021/01/14/%E5%AF%92%E5%81%87%E7%AE%97%E6%B3%95%E8%AE%AD%E7%BB%83/"/>
<id>http://sweetheart.nefu.site/2021/01/14/%E5%AF%92%E5%81%87%E7%AE%97%E6%B3%95%E8%AE%AD%E7%BB%83/</id>
<published>2021-01-14T09:51:53.000Z</published>
<updated>2021-04-10T14:13:51.172Z</updated>
<content type="html"><![CDATA[<h1 id="寒假算法练习"><a href="#寒假算法练习" class="headerlink" title="寒假算法练习"></a>寒假算法练习</h1><h2 id="week-1"><a href="#week-1" class="headerlink" title="week 1"></a>week 1</h2><p>今天是<strong>2021/1/15</strong></p><p>然而写下这个的时候是2021/2/18</p><p>。。。。。懒人本懒了</p><h3 id="递归实现指数型枚举"><a href="#递归实现指数型枚举" class="headerlink" title="递归实现指数型枚举"></a>递归实现指数型枚举</h3><blockquote><p>链接:<a href="https://ac.nowcoder.com/acm/problem/50911">https://ac.nowcoder.com/acm/problem/50911</a><br>来源:牛客网</p><p>题目描述</p><p>从 1∼n1\sim n1∼n这 n (n≤16)(n \leq 16)(n≤16) 个整数中随机选取任意多个,输出所有可能的选择方案。</p><p>输入描述:</p><pre><code>一个整数n。</code></pre><p>输出描述:</p><pre><code>每行一种方案。同一行内的数必须升序排列,相邻两个数用恰好1个空格隔开。对于没有选任何数的方案,输出空行。本题有自定义校验器(SPJ),各行(不同方案)之间的顺序任意。</code></pre><p>示例1</p><p>输入</p><pre><code>3</code></pre><p>输出</p><pre><code>322 311 31 21 2 3</code></pre></blockquote><pre><code class="c++">/* _ooOoo_ o8888888o 88" . "88 (| -_- |) O\ = /O ____/`---'\____ .' \\| |// `. / \\||| : |||// \ / _||||| -:- |||||- \ | | \\\ - /// | | | \_| ''\---/'' | | \ .-\__ `-` ___/-. / ___`. .' /--.--\ `. . __ ."" '< `.___\_<|>_/___.' >'"". | | : `- \`.;`\ _ /`;.`/ - ` : | | \ \ `-. \_ __\ /__ _/ .-` / /======`-.____`-.___\_____/___.-`____.-'====== `=---='^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 佛祖保佑 永无BUG @Author: xiaomu @Time: 2021/2/18 8:13 @Project_NAME:_Algorithm_training @FileName: NC50911.cpp @IDE: CLion*/#include <cstdio>#include <iostream>using namespace std;int pre[20];int n;void print(int len)&#123; for(int i=0;i<len;i++) &#123; printf("%d%c",pre[i],i==len-1?'\n':' '); &#125; if(len==0) puts(" ");&#125;//升序输出void dfs(int pr,int dep)&#123; for(int i =pr+1;i<=n;i++) &#123; pre[dep]=i; dfs(i,dep+1); &#125; print(dep);&#125;int main()&#123; cin>>n; dfs(0,0); return 0;&#125;</code></pre><p>这道题目主要是为了考察了深度遍历树的建立</p><h3 id="递归实现组合型枚举-·"><a href="#递归实现组合型枚举-·" class="headerlink" title="递归实现组合型枚举 ·"></a>递归实现组合型枚举 ·</h3><blockquote><p>链接:<a href="https://ac.nowcoder.com/acm/problem/50918">https://ac.nowcoder.com/acm/problem/50918</a><br>来源:牛客网</p><p>输入描述:</p><pre><code>两个整数n,m。</code></pre><p>输出描述:</p><pre><code>按照从小到大的顺序输出所有方案,每行1个。首先,同一行内的数升序排列,相邻两个数用一个空格隔开。其次,对于两个不同的行,对应下标的数一一比较,字典序较小的排在前面(例如1 3 9 12排在1 3 10 11前面)。</code></pre><p>输入</p><pre><code>5 3</code></pre><p>输出</p><pre><code>1 2 31 2 41 2 51 3 41 3 51 4 52 3 42 3 52 4 53 4 5</code></pre></blockquote><pre><code class="c++">#include <cstdio>#include <iostream>using namespace std;int n,m;//n表示1-n,m表示行数;int pre[20];void print()&#123; for (int i = 1; i <=m ; ++i) &#123; cout<<pre[i]<<' '; &#125; cout<<'\n';&#125;void dfs(int node,int deep)&#123; if(deep<=m&&node<=n) &#123; while(deep<=m&&node<=n) &#123; pre[deep]=node; dfs(node+1,deep+1); if(deep==m) &#123; print(); &#125; node++; &#125; &#125; else return;&#125;int main()&#123; cin>>n>>m; dfs(1,1); return 0;&#125;</code></pre><p>这里考察递归栈的使用</p><p>第一个没看题解自己写出来的题目<del>~</del>开心</p><h3 id="递归实现排列型枚举"><a href="#递归实现排列型枚举" class="headerlink" title="递归实现排列型枚举"></a>递归实现排列型枚举</h3><blockquote><p>链接:<a href="https://ac.nowcoder.com/acm/problem/50919">https://ac.nowcoder.com/acm/problem/50919</a><br>来源:牛客网</p><p>题目描述</p><p>把 1∼n1\sim n1∼n 这 n(n<10)(n \lt 10)(n<10)个整数排成一行后随机打乱顺序,输出所有可能的次序。</p><p>输入描述:</p><pre><code>一个整数n。</code></pre><p>输出描述:</p><pre><code>按照从小到大的顺序输出所有方案,每行1个。 首先,同一行相邻两个数用一个空格隔开。其次,对于两个不同的行,对应下标的数一一比较,字典序较小的排在前面。</code></pre><p>示例1</p><p>输入</p><pre><code>3</code></pre><p>输出</p><pre><code>1 2 31 3 22 1 32 3 13 1 23 2 1</code></pre></blockquote><pre><code class="c++">#include<stdio.h>int a[11],n,used[11];void dfs(int dep)&#123; int i; if(dep == n + 1)&#123; printf("%d",a[1]); for(i = 2; i <= n; i++) printf(" %d",a[i]); printf("\n"); return ; &#125; for(i = 1; i <= n; i++) if(!used[i])&#123; used[i] = 1, a[dep] = i; dfs(dep + 1); used[i] = 0; &#125;&#125;int main()&#123; scanf("%d",&n); dfs(1); return 0;&#125;</code></pre><p>这次的退栈比较巧妙</p><p>或者利用c++的排列数函数来计算</p><pre><code class="c++">#include<iostream>#include<algorithm>using namespace std;int a[15], n;int main()&#123; cin >> n; for(int i = 1; i <= n; i++) a[i] = i;//先按照升序对创建数组 do//先do否则输出不了123.....n &#123; for(int i = 1; i <= n; i++) cout << a[i] << ' '; cout << endl; &#125;while(next_permutation(a + 1, a + n + 1));//求以ai开头的全排列 return 0;&#125;</code></pre><h3 id="翻硬币"><a href="#翻硬币" class="headerlink" title="翻硬币"></a>翻硬币</h3><blockquote><p>链接:<a href="https://ac.nowcoder.com/acm/problem/14355">https://ac.nowcoder.com/acm/problem/14355</a><br>来源:牛客网</p><p>题目描述</p><p>小明正在玩一个“翻硬币”的游戏。</p><p> 桌上放着排成一排的若干硬币。我们用 * 表示正面,用 o 表示反面(是小写字母,不是零)。 </p><p> 比如,可能情形是:*<em>oo**</em>oooo </p><p> 如果同时翻转左边的两个硬币,则变为:oooo***oooo </p><p> 现在小明的问题是:如果已知了初始状态和要达到的目标状态,每次只能同时翻转相邻的两个硬币,那么对特定的局面,最少要翻动多少次呢? </p><p> 我们约定:把翻动相邻的两个硬币叫做一步操作,那么要求: </p><p>输入描述:</p><pre><code>两行等长的字符串,分别表示初始状态和要达到的目标状态。每行的长度<1000</code></pre><p>输出描述:</p><pre><code>一个整数,表示最小操作步数。</code></pre><p>示例1</p><p>输入</p><pre><code>**********o****o****</code></pre><p>输出</p><pre><code>5</code></pre><p>示例2</p><p>输入</p><pre><code>*o**o***o****o***o**o***</code></pre><p>输出</p><pre><code>1</code></pre></blockquote><pre><code class="c++">#include <cstring>#include <iostream>using namespace std;const int N =110;int n;char str1[N],str2[N];void turn(int i)&#123; if(str1[i]=='*') str1[i]='o'; else str1[i]='*';&#125;int main()&#123; cin>>str1>>str2; n=strlen(str1); int res=0; for(int i=0;i<n-1;i++) if(str1[i]!=str2[i]) &#123; turn(i),turn(i+1); res++; &#125; cout<<res; return 0;&#125;</code></pre><p>这题用暴力搜素法来进行解题</p><p>先读入字符串1和2</p><p>当发现1和2有不同,立即翻1相邻两个硬币</p><h3 id="带分数"><a href="#带分数" class="headerlink" title="带分数"></a>带分数</h3><blockquote><p>链接:<a href="https://ac.nowcoder.com/acm/problem/14353">https://ac.nowcoder.com/acm/problem/14353</a><br>来源:牛客网</p><p>题目描述</p><p> 100 可以表示为带分数的形式:100 = 3 + 69258 / 714。 </p><p> 还可以表示为:100 = 82 + 3546 / 197。 </p><p> 注意特征:带分数中,数字1~9分别出现且只出现一次(不包含0)。 </p><p> 类似这样的带分数,100 有 11 种表示法。 </p><p>输入描述:</p><pre><code>从标准输入读入一个正整数N (N<1000*1000)</code></pre><p>输出描述:</p><pre><code>程序首先输出正整数N,然后在输出该数字用数码1~9不重复不遗漏地组成带分数表示的全部种数n。注意:不要求输出每个表示,只统计有多少表示法!输出格式:N n</code></pre><p>示例1</p><p>输入</p><pre><code>100</code></pre><p>输出</p><pre><code>100 11</code></pre><p>示例2</p><p>输入</p><pre><code>105</code></pre><p>输出</p><pre><code>105 6</code></pre></blockquote><p>这题也是暴力搜索法解</p><p>思路:</p><p>先对1-9进行全排列</p><p>然后对1-9进行分割和组合,然后暴力搜索能否符合和为目标数</p><pre><code class="c++">#include<iostream>#include <cstdio>#include <algorithm>using namespace std;int asw=0;int flag[10],a[10];int sum(int start,int end)//字符串变成数字&#123; int i,sum=0; for(i=start;i<end;i++) sum=sum*10+a[i+1]; return sum;&#125;void Found(int a[],int n,int m)&#123; int i,j,begin=0; //开始裁缝分数组 //吧全排列好的数组分别划分成整数,分子,分母 for (int k = 1; k <n ; ++k) &#123; int m1=sum(0,i);//从1到9开始选择数 if(m1>=m) return;//如果第一个整数就比给定的数要大就直接淘汰 for (int j=i+(n-i)/2; j<n-1 ; ++j) &#123; int m2=sum(i,j); int m3=sum(j,n-1); if(m2>m3&&m2%3==0&&m==m1+m2/3) &#123; asw++; &#125; &#125; &#125;&#125;void DFS(int start,int n,int m)&#123; if (start==n)//表示全排列完成 &#123; Found(a,n,m); &#125; else &#123; for (int i = 1; i <10 ; ++i) &#123; if(flag[i])//如果没有搜索过 &#123; continue;//对于以这个开头的数 a[start]=i; flag[i]=1; DFS(start+1,n,m); flag[i]=0;//重置,让后一个开头的数能够循环 &#125; &#125; &#125;&#125;int main()&#123; int i ,j,m; double s1,s2; fill(flag,flag+10,0); cin>>m; DFS(1,10,m);//1-9进行全排列 cout<<m<<' '<<asw; return 0;&#125;</code></pre><h3 id="非递归实现组合型枚举"><a href="#非递归实现组合型枚举" class="headerlink" title="非递归实现组合型枚举"></a>非递归实现组合型枚举</h3><blockquote><p>链接:<a href="https://ac.nowcoder.com/acm/problem/50925">https://ac.nowcoder.com/acm/problem/50925</a><br>来源:牛客网</p><p>题目描述</p><p>从 1~n 这 n 个整数中随机选出 m 个,输出所有可能的选择方案。n>0n \gt 0n>0, 0≤m≤n0 \leq m \leq n0≤m≤n, n+(n−m)≤25n+(n-m)\leq 25n+(n−m)≤25。</p><p>输入描述:</p><pre><code>两个整数n,m。</code></pre><p>输出描述:</p><pre><code>按照从小到大的顺序输出所有方案,每行1个。首先,同一行内的数升序排列,相邻两个数用一个空格隔开。其次,对于两个不同的行,对应下标的数一一比较,字典序较小的排在前面(例如1 3 9 12排在1 3 10 11前面)。</code></pre><p>示例1</p><p>输入</p><pre><code>5 3</code></pre><p>输出</p><pre><code>1 2 31 2 41 2 51 3 41 3 51 4 52 3 42 3 52 4 53 4 5</code></pre></blockquote><pre><code class="c++">#include<bits/stdc++.h>using namespace std;int sz[100];int n,m;void dfs(int pos,int val)&#123; if(pos==m) &#123; cout<<sz[0]; for(int i=1; i<pos; i++) cout<<" "<<sz[i]; cout<<endl; return ; &#125; for(int i=val+1; i<=n; i++) &#123; sz[pos]=i; dfs(pos+1,i); &#125;&#125;int main()&#123; cin>>n>>m; if(m==0) cout<<endl; else if(m==1) &#123; for(int i=1; i<=n; i++) cout<<i<<endl; &#125; else &#123; for(int i=1; i<=n; i++) &#123; sz[0]=i;//记录数组 dfs(1,sz[0]); &#125; &#125; return 0;&#125;</code></pre><h3 id="费解的开关"><a href="#费解的开关" class="headerlink" title="费解的开关"></a>费解的开关</h3><blockquote><p>链接:<a href="https://ac.nowcoder.com/acm/problem/50920">https://ac.nowcoder.com/acm/problem/50920</a><br>来源:牛客网</p><p>你玩过“拉灯”游戏吗?25盏灯排成一个5x5的方形。每一个灯都有一个开关,游戏者可以改变它的状态。每一步,游戏者可以改变某一个灯的状态。游戏者改变一个灯的状态会产生连锁反应:和这个灯上下左右相邻的灯也要相应地改变其状态。 </p><p> 我们用数字“1”表示一盏开着的灯,用数字“0”表示关着的灯。下面这种状态 </p><p> 10111<br> 01101<br> 10111<br> 10000<br> 11011 </p><p> 在改变了最左上角的灯的状态后将变成: </p><p> 01111<br> 11101<br> 10111<br> 10000<br> 11011 </p><p> 再改变它正中间的灯后状态将变成: </p><p> 01111<br> 11001<br> 11001<br> 10100<br> 11011 </p><p> 给定一些游戏的初始状态,编写程序判断游戏者是否可能在6步以内使所有的灯都变亮。 </p><p>输入描述:</p><pre><code>第一行有一个正整数n,代表数据中共有n个待解决的游戏初始状态。以下若干行数据分为n组,每组数据有5行,每行5个字符。每组数据描述了一个游戏的初始状态。各组数据间用一个空行分隔。对于30%的数据,n≤5n \leq 5n≤5;对于100%的数据,n≤500n \leq 500n≤500。</code></pre><p>输出描述:</p><pre><code>输出数据一共有n行,每行有一个小于等于6的整数,它表示对于输入数据中对应的游戏状态最少需要几步才能使所有灯变亮。对于某一个游戏初始状态,若6步以内无法使所有灯变亮,请输出“-1”。</code></pre><p>示例1</p><p>输入</p><pre><code>3001110101110001110101110011101111011111011111111110111111111111111111111111</code></pre><p>输出</p><pre><code>32-1</code></pre></blockquote><p>说明改变一盏灯后</p><p>其上下左右十字形区域将会都取反</p><p>注意以下:</p><ul><li>所有问题的最后的方案取决于第一行的初态,</li><li>所以列举第一行32种初态,进行改变</li><li>然后像解cube一样,一行行地进行消除,变成灯全开的状态</li><li>每一行灯全开依赖于下一行的同列</li><li>最后最后一行不能由下一行进行啊改变</li><li>所以最后一行如果是全开的话 ,就有解,如果最后一行不是全开的话就无解,换而言之只用判断最后一行状态就行</li><li>由于题目大小限制所以建议使用位运算进行操作</li></ul><p><a href="https://blog.csdn.net/xiaonanxinyi/article/details/84349483?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522161509708516780274122798%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=161509708516780274122798&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-2-84349483.first_rank_v2_pc_rank_v29&utm_term=%E8%B4%B9%E8%A7%A3%E7%9A%84%E5%BC%80%E5%85%B3">题解blog</a></p><pre><code class="c++">#include<iostream>#include<cstring>#include<algorithm>using namespace std;const int INF = 0x3f3f3f3f;char mp[7][7];int dx[5] = &#123; 0,0,-1,1,0 &#125;, dy[5] = &#123; 1,-1,0,0,0 &#125;;//方位数组void turn(int x, int y)//使坐标(x,y)周围的灯的状态改变&#123; for (int i = 0;i < 5;i++) &#123; int a = x + dx[i]; int b = y + dy[i]; if (a >= 0 && a < 5 && b >= 0 && b < 5)//如果没有出边界 mp[a][b] = '0' + '1' - mp[a][b];//使满足条件的灯的状态改变 &#125;&#125;int work()&#123; int res = INF; for (int k = 0;k < (1 << 5);k++)//第0行***有5个灯,每个灯都有按与不按两种选择,对应于k的2进制表示就是每位上的1/0。所以最后共有32种情况。我们将第一行所有按的情况都枚举一下,在第一行确定的情况下,剩下的行数,按与不按也就可以确定了(1往后移动5位,表示2的5次方)1*2次方 &#123; char re[7][7]; int ans = 0; memcpy(re, mp, sizeof (mp));//把mp中的信息拷贝到re中 for (int i = 0;i < 5;i++) if (k >> i & 1)//对于第一行的i个等,如果这个灯是开的 &#123; ans++; turn(0, i);//根据k的2进制表示信息我们可以知道需要将(0,i)上的灯按一下 &#125; for (int i = 0;i < 4;i++)//对于1-4行的灯,其状态都由第一行决定 &#123; for (int j = 0;j < 5;j++) if (mp[i][j] == '0')//如果这一行的为0,按下一行同列的灯来改变,一行一行的进行消除 &#123; ans++; turn(i + 1, j); &#125; &#125; bool is_sucessful = true;//之后只有最后一行会产生错误,判断最后一行的灯是不是全部都是亮的,如果是的话就表示我们枚举的这个方案是成功的 for (int i = 0;i < 5;i++) if (mp[4][i] == '0') &#123; is_sucessful = false; break; &#125; if (is_sucessful)//如果该方案成功的话我们需要维护一下最小值便于最后输出方案最小值 res = min(res, ans); memcpy(mp, re, sizeof (mp));//再把mp中灯的开关情况恢复,便于接下来对k的枚举 &#125; if(res>6) res=-1; return res;&#125;int main()&#123; ios::sync_with_stdio(false); cin.tie(0); int n; cin >> n; while (n--) &#123; for (int i = 0;i < 5;i++) &#123; for (int j = 0;j < 5;j++) cin >> mp[i][j]; &#125; cout << work() << endl; &#125; return 0;&#125;</code></pre><h3 id="汉诺塔问问题"><a href="#汉诺塔问问题" class="headerlink" title="汉诺塔问问题"></a>汉诺塔问问题</h3><blockquote><p>链接:<a href="https://ac.nowcoder.com/acm/problem/50921">https://ac.nowcoder.com/acm/problem/50921</a><br>来源:牛客网</p><p>译文描述</p><p>背景查理·黑褐色(Charlie Darkbrown)参加了另一门无聊的计算机科学课程:目前,老师只是在解释河内塔的标准问题,这使查理感到无聊! 老师指着黑板(图4)说:“所以这是问题所在: </p><p><img src="https://uploadfiles.nowcoder.com/files/20190708/314053_1562564708660_1958_1.jpg" alt="img"></p><ul><li><p>一共有三座塔楼:A,B和C。 </p></li><li><p>有n个磁盘。拼图游戏时,数字n是恒定的。 </p></li><li><p>所有磁盘的大小均不同。 </p></li><li><p>磁盘最初堆叠在塔A上,其大小从顶部到底部逐渐增加。 </p></li><li><p>难题的目标是将所有磁盘从塔A转移到塔C。 </p></li><li><p>一次可以将一个磁盘从塔架顶部移动到空塔架或顶部具有更大磁盘的塔架上。 </p></li></ul><p>因此,您的任务是编写一个程序,以计算将所有磁盘从A塔移动到C所需的最小磁盘移动次数。”<br>Charlie:“这非常无聊,每个人都知道可以使用简单的递归来解决。拒绝编写像这样简单的代码!”<br>老师叹了口气:“好吧,查理,让我们考虑一下要为您做的事情:为您提供第四塔D。计算最小数量的磁盘移动以移动所有磁盘。塔A到D都使用了全部四个塔。”<br>查理看上去很生气:“嗯。。。好吧,我不知道四塔的最佳算法。。。“<br>问题<br>因此,真正的问题是解决问题不属于查理擅长的事情。实际上,查理唯一真正擅长的就是“坐在可以做这项工作的人旁边”。现在,猜猜是什么-完全是!坐在查理旁边的是你,他已经瞪着你。<br>幸运的是,您知道以下算法适用于n <= 12:首先固定塔A上的k> = 1个磁盘,然后使用四个塔的算法将剩余的nk个磁盘从塔A移至塔B.使用三个塔的算法,将k个塔中的k个磁盘移到塔D中。最后,使用用于四个塔的算法,将塔B中的n-k个磁盘再次移动到塔D中(从而不移动塔D上已有的k个磁盘中的任何一个)。对所有k 2∈{1,….,n}执行此操作,并找到移动次数最少的k。<br>因此,对于n = 3和k = 2,您首先需要使用四塔算法(一次移动)将1(3-2)个磁盘从塔A移到塔B。然后,您将使用三个塔的算法将剩余的两个磁盘从塔A移到塔D(三步)。最后一步是再次使用四个塔的算法将磁盘从塔B移到塔D(另一个移动)。因此,对于n = 3和k = 2的解是5个移动。为确保这确实是n = 3的最佳解决方案,您需要检查k的其他可能值1和3。(但是,顺便说一句,5是最佳的。。。)</p><p>输入描述:</p><pre><code>没有输入。</code></pre><p>输出描述:</p><pre><code>对于每个n(1 <= n <= 12),请打印一行以包含最少移动次数,以解决四个塔和n个磁盘的问题。</code></pre></blockquote><p>采用动态规划</p><pre><code class="c++"></code></pre><h2 id="week-2"><a href="#week-2" class="headerlink" title="week 2"></a>week 2</h2><h3 id="九宫重排"><a href="#九宫重排" class="headerlink" title="九宫重排"></a>九宫重排</h3><blockquote><p>题目 1426: [蓝桥杯][历届试题]九宫重排</p><p>时间限制: 1Sec 内存限制: 128MB 提交: 3297 解决: 955</p><p>题目描述</p><p>如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着。与空格子相邻的格子中的卡片可以移动到空格中。经过若干次移动,可以形成第二个图所示的局面。</p><p><img src="https://www.dotcpp.com/oj/upload/image/20170306/20170306084421_13973.png" alt="img"></p><p>我们把第一个图的局面记为:12345678.<br>把第二个图的局面记为:123.46758<br>显然是按从上到下,从左到右的顺序记录数字,空格记为句点。<br>本题目的任务是已知九宫的初态和终态,求最少经过多少步的移动可以到达。如果无论多少步都无法到达,则输出-1。</p><p>输入</p><p>输入第一行包含九宫的初态,第二行包含九宫的终态。 </p><p>输出</p><p>输出最少的步数,如果不存在方案,则输出-1。</p><p>样例输入</p><pre><code>12345678. 123.46758 </code></pre><p>样例输出</p><pre><code>3</code></pre></blockquote><pre><code class="c++">#include <iostream>#include <queue>#include <map>#include <algorithm>#include <algorithm>using namespace std;string first,last,string1,string2;int flag,x,y;map<string,int> dis,vis;queue<string> q1,q2;char a[3][3];const int dir[4][2]=&#123;&#123;0,1&#125;,&#123;0,-1&#125;,&#123;1,1&#125;,&#123;-1,-1&#125;&#125;;int ans;bool isIn(int x,int y)&#123; return (x>=0&&x<=3&&y<=3&&y>=0);&#125;void toMatrix(string str)&#123; for (int i = 0; i <9 ; ++i) &#123; a[i/3][i%3]=str[i]; &#125;&#125;string toString()&#123; string str; for (int i = 0; i < 9; ++i) &#123; str.push_back(a[i/3][i%3]); &#125; return str;&#125;int bfs()&#123; q1.push(first); dis[first]=1; vis[first]=1; q2.push(last); dis[last]=1; vis[last]=2; while (!q1.empty()&&!q2.empty()) &#123; if (q1.size()<q2.size()) &#123; string1=q1.front(); q1.pop(); flag=1; &#125; else&#123; string1=q2.front(); q2.pop(); flag=2; &#125; toMatrix(string1); for (int i = 0; i <9; ++i) &#123; if(a[i/3][i%3]=='.') &#123; x=i/3; y=i%3; &#125; &#125; for (int i = 0; i <4 ; ++i) &#123; int tx=x+dir[i][0]; int ty=y+dir[i][1]; if (isIn(tx,ty)) &#123; swap(a[x][y],a[tx][ty]); //改变数组; string2=toString(); //产生新的状态 if(!dis.count(string2))//如果没有访问过 &#123; dis[string2]=dis[string1]+1;//次态等于初态加一 vis[string2]=vis[string1];//记录由上一个继承而来 if(flag==1) q1.push(string2); if (flag==2) q2.push(string2); &#125; else &#123;//如果访问过 if (vis[string1]+vis[string2]==3)//如果重合,那么1达到的次态二的初态也能达到 &#123; ans=dis[string1]+dis[string2]-1;//注意有减一 return ans; &#125; &#125; swap(a[x][y],a[tx][ty]);//注意转回初态 &#125; &#125; &#125; return -1;&#125;int main()&#123; cin>>first>>last; if (first==last) cout<<0; else cout<<bfs()<<endl; return 0;&#125;</code></pre><h3 id="random蚂蚁"><a href="#random蚂蚁" class="headerlink" title="random蚂蚁"></a>random蚂蚁</h3><blockquote><p>题目 1429: [蓝桥杯][2014年第五届真题]兰顿蚂蚁</p><p>时间限制: 1Sec 内存限制: 128MB 提交: 3824 解决: 1716</p><p>题目描述</p><p><img src="https://www.dotcpp.com/oj/upload/image/20170306/20170306151514_74936.png" alt="img"></p><p>兰顿蚂蚁,是于1986年,由克里斯·兰顿提出来的,属于细胞自动机的一种。</p><p>平面上的正方形格子被填上黑色或白色。在其中一格正方形内有一只“蚂蚁”。<br>蚂蚁的头部朝向为:上下左右其中一方。</p><p>蚂蚁的移动规则十分简单:<br>若蚂蚁在黑格,右转90度,将该格改为白格,并向前移一格;<br>若蚂蚁在白格,左转90度,将该格改为黑格,并向前移一格。</p><p>规则虽然简单,蚂蚁的行为却十分复杂。刚刚开始时留下的路线都会有接近对称,像是会重复,但不论起始状态如何,蚂蚁经过漫长的混乱活动后,会开辟出一条规则的“高速公路”。</p><p>蚂蚁的路线是很难事先预测的。</p><p>你的任务是根据初始状态,用计算机模拟兰顿蚂蚁在第n步行走后所处的位置。</p><p>输入</p><p>输入数据的第一行是 m n 两个整数(3 < m, n < 100),表示正方形格子的行数和列数。<br>接下来是 m 行数据。<br>每行数据为 n 个被空格分开的数字。0 表示白格,1 表示黑格。 </p><p>接下来是一行数据:x y s k, 其中x y为整数,表示蚂蚁所在行号和列号(行号从上到下增长,列号从左到右增长,都是从0开始编号)。s 是一个大写字母,表示蚂蚁头的朝向,我们约定:上下左右分别用:UDLR表示。k 表示蚂蚁走的步数。 </p><p>输出</p><p>输出数据为一个空格分开的整数 p q, 分别表示蚂蚁在k步后,所处格子的行号和列号。</p><p>样例输入</p><pre><code>5 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 3 L 5</code></pre><p>样例输出</p><pre><code>1 3</code></pre></blockquote><pre><code class="c++">#include <iostream>#include <string>using namespace std;typedef struct &#123; int x; int y; int dict;&#125;ant;string a="ULDR";//逆时针顺序,黑色加1,白色减1int dict[4][2]=&#123;&#123;0,-1&#125;,&#123;-1,0&#125;,&#123;0,1&#125;,&#123;1,0&#125;&#125;;int MAP[20][100]=&#123;0&#125;;int K;int n,m;char d;int main()&#123; ant an; cin>>m>>n; for (int i=1;i<=m;i++) for (int j = 1; j <=n ; ++j) &#123; cin>>MAP[i][j]; &#125; cin>>an.x>>an.y>>d>>K; an.dict=a.find(d); cout<<an.dict<<endl; while (K--) &#123; if (MAP[an.x][an.y])//如果是黑色的地区是话 &#123; MAP[an.x][an.y]=0; an.dict=(an.dict+1)%4; an.y+=dict[an.dict][0]; an.x+=dict[an.dict][1]; &#125; else//如果是白色的地区的话 &#123; MAP[an.x][an.y]=1;//改变颜色 if (an.dict==0) an.dict=3; else an.dict--;//改变方向 an.y+=dict[an.dict][0]; an.x+=dict[an.dict][1];//改变位置 &#125; &#125; cout<<an.x<<' '<<an.y<<' '<<endl; return 0;&#125;</code></pre><h3 id="剪格子"><a href="#剪格子" class="headerlink" title="剪格子"></a>剪格子</h3><blockquote><p>题目 1432: [蓝桥杯][2013年第四届真题]剪格子</p><p>时间限制: 1Sec 内存限制: 128MB 提交: 3196 解决: 1106</p><p>题目描述</p><p>历届试题 剪格子<br>时间限制:1.0s 内存限制:256.0MB</p><p>问题描述<br>如下图所示,3 x 3 的格子中填写了一些整数。<br>+–<em>–+–+<br>|10</em> 1|52|<br>+–<strong><strong>–+<br>|20|30* 1|<br>***</strong></strong>–+<br>| 1| 2| 3|<br>+–+–+–+<br>我们沿着图中的星号线剪开,得到两个部分,每个部分的数字和都是60。<br>本题的要求就是请你编程判定:对给定的m x n 的格子中的整数,是否可以分割为两个部分,使得这两个区域的数字和相等。<br>如果存在多种解答,请输出包含左上角格子的那个区域包含的格子的最小数目。<br>如果无法分割,则输出 0。</p><p>输入</p><p>程序先读入两个整数 m n 用空格分割 (m,n< 10)。<br>表示表格的宽度和高度。<br>接下来是n行,每行m个正整数,用空格分开。每个整数不大于10000。 </p><p>输出</p><p>输出一个整数,表示在所有解中,包含左上角的分割区可能包含的最小的格子数目。 </p><p>样例输入</p><pre><code>3 310 1 5220 30 11 2 3</code></pre><p>样例输出</p><pre><code>3</code></pre></blockquote><pre><code class="c++">#include <iostream>using namespace std;int map_[11][11];using namespace std;int ans=1;int goal=0;int dic[4][2]=&#123;&#123;0,1&#125;,&#123;1,0&#125;,&#123;0,-1&#125;,&#123;-1,0&#125;&#125;;int tx,ty;int visited[10][10];int m,n;void dfs(int x,int y,int total,int cnt)&#123; if (total==goal) &#123; ans<cnt?ans:cnt; return; &#125; if (total>goal) return; else &#123; for (auto & i : dic) &#123; tx=x+i[0]; ty=y+i[1]; if (tx>=0&&tx<=m&&ty>=0&&ty<=n&&!visited[ty][tx]) &#123; total+=map_[ty][tx]; cnt++; visited[ty][tx]= 1; dfs(tx,ty,total,cnt); visited[ty][tx]=0; &#125; else &#123; continue; &#125; &#125; &#125;&#125;int main()&#123; cin>>m>>n; fill(visited,visited+10*10,0);//访问数组初始化 for (int i = 0; i < n; ++i) &#123; for (int j = 0; j < m; ++j) &#123; cin>>map_[i][j]; goal+=map_[i][j]; &#125; &#125; goal=goal/2; dfs(0,0,map_[0][0],1); return 0;&#125;</code></pre><h2 id="蓝桥杯第十一届真题"><a href="#蓝桥杯第十一届真题" class="headerlink" title="蓝桥杯第十一届真题"></a>蓝桥杯第十一届真题</h2><h3 id="既约分数"><a href="#既约分数" class="headerlink" title="既约分数"></a>既约分数</h3><p><img src="https://img-blog.csdnimg.cn/20210213191801692.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_5rqQ5Luj56CB4oCi5a64,size_16,color_FFFFFF,t_70"></p><pre><code class="c++">#include<iostream>using namespace std;int gcd(int a, int b)&#123; return b ? gcd(b, a % b) : a;&#125;int main()&#123; int sum = 0; //分子分母相同的情况 sum = 1; int sum2 = 0; //分子小于分母的情况 for(int i = 1; i < 2020; i++) &#123; for(int j = i + 1; j <= 2020; j++) &#123; if(gcd(i, j) == 1) &#123; sum2++; &#125; &#125; &#125; sum += sum2 * 2; cout << sum << endl; return 0;&#125;</code></pre><pre><code class="python">def fun(a,b): if a%b: return fun(b,a%b) else: return btotal=0for i in range(1,2020): for j in range(1,2021): if fun(i,j)==1: total+=1print(total)#注意以上C++写法不对,要加1</code></pre><h3 id="蛇形填数"><a href="#蛇形填数" class="headerlink" title="蛇形填数"></a>蛇形填数</h3><blockquote><p>题目<br>试题 C: 蛇形填数<br>本题总分:10 分</p><p>【问题描述】<br>如下图所示,小明用从 1 开始的正整数“蛇形”填充无限大的矩阵。<br>1 2 6 7 15 …<br>3 5 8 14 …<br>4 9 13 …<br>10 12 …<br>11 …<br>…</p><p>容易看出矩阵第二行第二列中的数是 5。请你计算矩阵中第 20 行第 20 列的数是多少?</p></blockquote><pre><code class="c++">#include<bits/stdc++.h>using namespace std;int main()&#123; int s,t=0,sum=0; s=2*20-1; // 根据等差数列计算出第二十行二十列是第几条对角线 for(int i=1;i<=s-1;i++) // 计算前38条对角线数字之和 &#123; t++; sum+=t; &#125; s=s/2+1; // 第39条对角线上属于范围内的数字之和 sum+=s; cout<<sum; &#125; </code></pre><pre><code class="python">#蛇形填数def func(x): if x == 1: return 1 elif x == 2: return 5 else: return func(x - 1) + 4 * (x - 1)print(func(20))</code></pre><h3 id="七段码"><a href="#七段码" class="headerlink" title="七段码"></a>七段码</h3><p><img src="https://img-blog.csdnimg.cn/20201018100053598.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQzNzE3OTcy,size_16,color_FFFFFF,t_70#pic_center"></p><pre><code class="c++">#include<bits/stdc++.h>using namespace std;const int N=10;int use[N],ans,e[N][N],fa[N];void init()&#123; //连边建图,e[i][j]==1表示i和j相邻 //a b c d e f g //1 2 3 4 5 6 7 e[1][2]=e[1][6]=1; e[2][1]=e[2][7]=e[2][3]=1; e[3][2]=e[3][4]=e[3][7]=1; e[4][3]=e[4][5]=1; e[5][4]=e[5][6]=e[5][7]=1; e[6][1]=e[6][5]=e[6][7]=1;&#125;int find(int u)&#123;if(fa[u]==u)return u;fa[u]=find(fa[u]);return fa[u];&#125;//并查集void dfs(int d)&#123; if(d>7)&#123; /* 并查集判联通 */ for(int i=1;i<=7;i++)fa[i]=i; for(int i=1;i<=7;i++) for(int j=1;j<=7;j++) if(e[i][j]&&use[i]&&use[j])&#123; int fx=find(i),fy=find(j); if(fx!=fy)&#123; fa[fx]=fy; &#125; &#125; int k=0; for(int i=1;i<=7;i++)if(use[i]&&fa[i]==i)k++; if(k==1)ans++; return; &#125; use[d]=1;//打开d这个灯,继续开关下一个灯 dfs(d+1); use[d]=0;//关闭d这个灯,继续开关下一个灯 dfs(d+1);&#125;int main()&#123; init(); dfs(1); cout<<ans;&#125;</code></pre><pre><code class="python">import numpy as npimport itertools as itclass UnionFind: def __init__(self, n): self.father = list(range(n)) self.size = [1] * n # 当前连通分量数目 self.setCount = n def find(self, x): if self.father[x] == x: return x self.father[x] = self.find(self.father[x]) return self.father[x] def merge(self, x, y): x, y = self.find(x), self.find(y) if x == y: return False if self.size[x] < self.size[y]: x, y = y, x self.father[y] = x self.size[x] += self.size[y] self.setCount -= 1 return Trueres = 0data = list(np.zeros((7, 7)))data[0][1] = data[0][5] = 1data[1][0] = data[1][6] = data[1][2] = 1data[2][1] = data[2][3] = data[2][6] = 1data[3][2] = data[3][4] = 1data[4][3] = data[4][5] = data[4][6] = 1data[5][0] = data[5][4] = data[5][6] = 1num = [i for i in range(0, 7)]for i in range(1, 8): total = it.combinations(num, i) for j in total: uf = UnionFind(7) for z in j: for k in range(len(data[z])): z = int(z) b = int(data[z][k]) if b == 1 and k in j: uf.merge(z, k) if uf.setCount == 7 - len(j) + 1: res += 1print(res)</code></pre><h3 id="成绩分析"><a href="#成绩分析" class="headerlink" title="成绩分析"></a>成绩分析</h3><p><img src="https://output-course-file.oss-cn-hangzhou.aliyuncs.com/courses%2F2786%2Fattachments%2F1614059341424%2F7.png?OSSAccessKeyId=LTAI4G6JuPaCndB3pE1nSCz9&Expires=1615105172&Signature=bNuQxcEwKwpinm9TluOc3ugYTFw="></p><p>太简单就不贴代码了</p><h3 id="回文日期"><a href="#回文日期" class="headerlink" title="回文日期"></a>回文日期</h3><p><img src="https://output-course-file.oss-cn-hangzhou.aliyuncs.com/courses%2F2786%2Fattachments%2F1614059341424%2F9.png?OSSAccessKeyId=LTAI4G6JuPaCndB3pE1nSCz9&Expires=1615105172&Signature=oGlQGxLIqXYAR3e0BDNkY7bnQ/g="></p><pre><code class="c++">#include <cstring>#include <iostream>using namespace std;int days[13] = &#123;0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31&#125;;bool check(int date)&#123; int year = date / 10000; int mouth = (date / 100) % 100; int day = date % 100; if(mouth < 0 || mouth > 12) return false; if(day == 0 || mouth != 2 && day > days[mouth]) return false; if(mouth == 2) &#123; int leap = year % 100 && year % 4 == 0 || year % 400 == 0; if(day > days[mouth] + leap) return false; &#125; return true;&#125;int main()&#123; int date1, date2; cin >> date1 >> date2; int res = 0; for(int i = 1000; i < 10000; i ++) &#123; int date = i, x = i; for(int j = 0; j < 4; j ++ ) date = date * 10 + x % 10, x /= 10; if(date1 <= date && date <= date2 && check(date)) res ++; &#125; cout << res << endl; return 0;&#125;</code></pre><h3 id="子串分值"><a href="#子串分值" class="headerlink" title="子串分值"></a>子串分值</h3><p><img src="https://output-course-file.oss-cn-hangzhou.aliyuncs.com/courses%2F2786%2Fattachments%2F1614059341424%2F11.png?OSSAccessKeyId=LTAI4G6JuPaCndB3pE1nSCz9&Expires=1615105172&Signature=W9nNpL2cMSq6/8W9spMyn0K/nY0="></p><p><img src="https://output-course-file.oss-cn-hangzhou.aliyuncs.com/courses%2F2786%2Fattachments%2F1614059341424%2F12.png?OSSAccessKeyId=LTAI4G6JuPaCndB3pE1nSCz9&Expires=1615105172&Signature=PbuPUxKXs3rmaSoClVQ+0DrqOjg="></p><pre><code class="c++">#include <iostream>#include <cstring>using namespace std;int flag[26];int num;int main()&#123; string str; cin >> str; long long sum = 0; for(int i = 0; i < str.length(); ++i)&#123; for(int j = i; j < str.length(); ++j)&#123; flag[str[j] - 'a']++; if(flag[str[j] - 'a'] == 1)&#123; num++; &#125; sum += num; &#125; memset(flag, 0, sizeof(flag)); num = 0; &#125; cout << sum << '\n'; return 0;&#125;</code></pre><h3 id="字串排序"><a href="#字串排序" class="headerlink" title="字串排序"></a>字串排序</h3><p><img src="https://output-course-file.oss-cn-hangzhou.aliyuncs.com/courses%2F2786%2Fattachments%2F1614059341424%2F15.png?OSSAccessKeyId=LTAI4G6JuPaCndB3pE1nSCz9&Expires=1615105172&Signature=Xd69ZvdnXAqa35LDuf+PZeVeTSs="></p><p>DP</p><pre><code class="c++">#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int N = 135, M = 10010;int f[N][30][N];//chcnt[i][j]记录第i个位置取字母j+'a'的逆序对最大值 int chcnt[N][30];//mlen[i]记录每个位置的最大值 int mlen[N];void dp()&#123; for (int i = 2; i < N; ++i) &#123; int m = 0; for (int j = 1; j <= 'z' - 'a'; ++j) &#123; for (int k = 1; k < i; ++k) &#123; if (k > 1) f[i][j][k] = f[i - 1][j][k - 1] + i - k; else f[i][j][k] = chcnt[i - 1][j - 1] + i - 1; chcnt[i][j] = max(chcnt[i][j], f[i][j][k]); &#125; m = max(m, chcnt[i][j]); &#125; mlen[i] = m; &#125;&#125;int main()&#123; dp(); int score = 0; cin >> score; //找出最短长度值 int beg = 0; for (int i = 1; i < N; ++i) if (mlen[i] >= score) &#123; beg = i; break; &#125; int curr = 0; //用于记录逆序值 int same = 1; //记录后缀中有多少个相同字母 char last = 'z' + 1;//记录上一个字母是什么 for (int i = beg; i > 0; --i) &#123; //从a开始枚举 int j = 0; for (; j <= last - 'a'; ++j) &#123; if (j == last - 'a') curr -= same; if (curr + chcnt[i][j] >= score) &#123; curr += i - 1; break; &#125; &#125; if (j == last - 'a') same++; else &#123; last = j + 'a'; same = 1; &#125; cout << last; &#125; cout << endl; return 0;&#125;</code></pre><h2 id="蓝桥杯第十届"><a href="#蓝桥杯第十届" class="headerlink" title="蓝桥杯第十届"></a>蓝桥杯第十届</h2><h3 id="平方和"><a href="#平方和" class="headerlink" title="平方和"></a>平方和</h3><p><img src="https://output-course-file.oss-cn-hangzhou.aliyuncs.com/courses%2F2786%2Fattachments%2F1605771924939%2F2.png?OSSAccessKeyId=LTAI4G6JuPaCndB3pE1nSCz9&Expires=1615105521&Signature=gl5UYg5AUVUW3zpvD9TXrgB2nkg="></p><h3 id="数列求和"><a href="#数列求和" class="headerlink" title="数列求和"></a>数列求和</h3><p><img src="https://output-course-file.oss-cn-hangzhou.aliyuncs.com/courses%2F2786%2Fattachments%2F1605771924939%2F3.png?OSSAccessKeyId=LTAI4G6JuPaCndB3pE1nSCz9&Expires=1615105521&Signature=iOmCIFJ4VAg3RLLW74clT/cN0Qw="></p><pre><code class="c++">#include<bits/stdc++.h>using namespace std;int main()&#123; int a[4]=&#123;1,1,1&#125;; int s = 0; for(int i = 4;i<=20190324;i++)&#123; s = a[0]+a[1]+a[2]; s = s%10000; a[0]=a[1]; a[1]=a[2]; a[2]=s;// cout<<a[2]<<endl; &#125; cout<<a[2]<<endl; return 0;&#125;</code></pre><h3 id="最大降雨量"><a href="#最大降雨量" class="headerlink" title="最大降雨量"></a>最大降雨量</h3><p><img src="https://output-course-file.oss-cn-hangzhou.aliyuncs.com/courses%2F2786%2Fattachments%2F1605771924939%2F4.png?OSSAccessKeyId=LTAI4G6JuPaCndB3pE1nSCz9&Expires=1615105521&Signature=04Ik9D5vXBGzcUP8pelB7yJm5GY="></p><p>34</p><p>证明:无法找到比34更优的方案了。如下图,假设每周选的数已经排好序</p><p>第一周: x x x x x x x ( x1,x2,x3,x4,x5,x6 满足 x1<x2<x3<x4<x5<x6)<br>第二周: x x x x x x x<br>第三周: x x x x x x x<br>第四周: x x x x x x x<br>第五周: x x x x x x x<br>第六周: x x x x x x x<br>第七周: x x x x x x x </p><p>则标记红色的是每周的中位数:</p><p>第一周: x x x x x x x<br>第二周: x x x x x x x<br>第三周: x x x x x x x<br>第四周: x x x x x x x<br>第五周: x x x x x x x<br>第六周: x x x x x x x<br>第七周: x x x x x x x </p><p>此时不看第几周,每一行里:红色的x右边的x必然比x大。</p><p>假设上面的七行按行按照x由小到大重新排序后得到</p><p>x x x x1 x x x<br>x x x x2 x x x<br>x x x x3 x x x<br>x x x x4 x x x<br>x x x x5 x x x<br>x x x x6 x x x<br>x x x x7 x x x </p><p>则x1<x2<x3<x4<x5<x6<x7 题目要求的中位数的中位数就是x4了</p><p>问题是x4最大能取到多少呢?注意到上图中x4右下角(如下图)的元素都应比x4大。。(共15个)</p><p>因此答案为49-15=34</p><p>x x x x x x x<br>x x x x x x x<br>x x x x x x x<br>x x x x4 x x x<br>x x x x x x x<br>x x x x x x x<br>x x x x x x x </p><p>————————————————<br>原文链接:<a href="https://blog.csdn.net/linruier2017/article/details/88803441">https://blog.csdn.net/linruier2017/article/details/88803441</a></p><h3 id="迷宫"><a href="#迷宫" class="headerlink" title="迷宫"></a>迷宫</h3><p>bfs搜索即可</p><pre><code class="#include<iostream>">#include<queue>#include<cstdio>#include<string>#include<cstring>using namespace std;char map[501][501]; //存成字符型 int vis[500][500];/*010101010010110010010101100101101001000010001010100000100010000010101001000010000000100110011010010101111011010010001000001101001011100011000000010000010000000010101000110100001010000010101010110010110001111100000010100001001010001010000010110000000011001000110101000010101100011010011010101011110111000110110101010010010010100000010001010011100000001010000010100010011010101011111001100001000011101000111000001010100001100010000001000101001100001001110001101000011100100010010101010101010100011010000001000010010000010100101010111010001010101000010111100100101001001000010000010101010100100100010100000000100000001010110011110100011000001010101000111010101001110000100001100001011001111011010000100010101010100001101010100101000010100000111011101001100000001011000100001011001011010010111000000001001010100100000001010010000100010000010001111010100100101001010101101001010100011010101101110000110101110010100001000011000000101001010000010001110000100000100011000011010110100000010010100100100001110110100101000101000000001110110010110101101010100001001010000100001101010100001000101010010001000101011010000100011001000100001010100111010101111101001000000100101000000110010100101001100001000000000010110100000010011101110010010000111010010110111010000000011010001000100010000000100001110100000011001110101000101000100010001111100010101001010000001000100000101001010010101100000001001010100010111010000011110000100001000000011011100000000100000000101110000001100111010111010001000110111010101101111000*/int dir[4][2] = &#123; &#123;1, 0&#125;, //下 &#123;0, -1&#125;, //左 &#123;0, 1&#125;, //右 &#123;-1, 0&#125; //上 &#125;;char dic[4]= &#123;'D','L','R','U'&#125;;struct node &#123; int x,y; int step; //到达该节点的步数 string path; //到达该点路径&#125;;int x1,x2,y1,y2,n,m; //(x1,y1)起点,(x2,y2)终点 void bfs() &#123; queue<node> q; node p; //当前所在的节点 p.x=x1;p.y=y1;p.step=0;p.path=""; vis[x1][y1]=1; q.push(p); while(!q.empty())&#123; node p=q.front(); //宽搜 队列待遍历节点 if(p.x==x2&&p.y==y2)&#123; if(p.step==0)&#123; &#125; cout<<p.step<<endl<<p.path; &#125; node v; //下一步所要去往的节点 for(int i=0;i<4;i++)&#123; //依次四个方向遍历 v.x=p.x+dir[i][0]; v.y=p.y+dir[i][1]; if(v.x>=0&&v.y>=0&&v.x<n&&v.y<m&&vis[v.x][v.y]==0&&map[v.x][v.y]!='1')&#123; //不能重复访问且走得通 vis[v.x][v.y]=1; //已访问 v.step=p.step+1; v.path=p.path+dic[i]; q.push(v); &#125; &#125; q.pop(); &#125;&#125;int main() &#123; n=30,m=50; memset(map,'1',sizeof(map)); memset(vis,0,sizeof(vis)); for(int i=0;i<n;i++)&#123; for(int j=0;j<m;j++)&#123; cin>>map[i][j]; &#125; &#125; x1=0;y1=0; x2=n-1;y2=m-1; bfs(); return 0;&#125;</code></pre><h3 id="完全二叉树权值"><a href="#完全二叉树权值" class="headerlink" title="完全二叉树权值"></a>完全二叉树权值</h3><blockquote><p>时间限制: 1.0s 内存限制: 256.0MB 本题总分:15 分</p><p>【问题描述】<br>给定一棵包含 N 个节点的完全二叉树,树上每个节点都有一个权值,按从上到下、从左到右的顺序依次是 A1, A2, · · · AN,如下图所示:<br>现在小明要把相同深度的节点的权值加在一起,他想知道哪个深度的节点权值之和最大?如果有多个深度的权值和同为最大,请你输出其中最小的深度。<br>注:根的深度是 1。<br>【输入格式】<br>第一行包含一个整数 N。<br>第二行包含 N 个整数 A1, A2, · · · AN 。<br>【输出格式】<br>输出一个整数代表答案。<br>【样例输入】<br>7<br>1 6 5 4 3 2 1</p><p>【样例输出】<br>2</p><p>【评测用例规模与约定】<br>对于所有评测用例,1 ≤ N ≤ 100000,−100000 ≤ Ai ≤ 100000<br>————————————————<br>原文链接:<a href="https://blog.csdn.net/linruier2017/article/details/88803441">https://blog.csdn.net/linruier2017/article/details/88803441</a></p></blockquote><pre><code class="c++">#include<bits/stdc++.h>using namespace std;typedef long long ll;int a[100005];int n;int main()&#123; scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d",&a[i]); int level=1;//层数 ll MAX=a[1]; ll ans=1;//第一层 int num=1;//该层的节点数 int pos=2;//下一层开头指针位置 for(;;) &#123; level++; num*=2; ll sum=0; for(int j=pos;j<=min(pos+num-1,n);j++)sum+=a[j]; if(sum>MAX) &#123; ans=level; MAX=sum; &#125; pos=pos+num; if(pos>n)break; &#125; printf("%lld\n",ans); return 0;&#125;</code></pre><h3 id="外卖店优先级"><a href="#外卖店优先级" class="headerlink" title="外卖店优先级"></a>外卖店优先级</h3><p><img src="https://img-blog.csdnimg.cn/20200512172351279.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQzNjUyMzI3,size_16,color_FFFFFF,t_70"></p><p><img src="https://img-blog.csdnimg.cn/20200512172513541.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQzNjUyMzI3,size_16,color_FFFFFF,t_70"></p><p><img src="https://img-blog.csdnimg.cn/20200512172532964.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQzNjUyMzI3,size_16,color_FFFFFF,t_70"></p><pre><code class="c++">package JC2019;import java.util.*;public class Main &#123; public static void main(String[] args) &#123; Scanner sc=new Scanner(System.in); int n=sc.nextInt(); int m=sc.nextInt(); int t=sc.nextInt(); HashMap<Integer,Integer> arr[]=new HashMap[t+1]; for(int i=0;i<t+1;i++)&#123; arr[i]=new HashMap<Integer,Integer>(); &#125; int id,ti; for(int i=0;i<m;i++)&#123; ti=sc.nextInt(); id=sc.nextInt(); if(arr[ti].containsKey(id))&#123; arr[ti].put(id, arr[ti].get(id)+1); &#125;else&#123; arr[ti].put(id, 1); &#125; &#125; int last[]=new int[n+1]; int scor[]=new int[n+1]; int prio[]=new int[n+1]; for(int i=0;i<=t;i++)&#123; for(int temp:arr[i].keySet())&#123; scor[temp]=Math.max(scor[temp]-(i-last[temp]-1),0); if(scor[temp]>5&&prio[temp]==0)&#123; prio[temp]=1; &#125;else if(scor[temp]<4&&prio[temp]==1)&#123; prio[temp]=0; &#125; scor[temp]+=arr[i].get(temp)*2; if(scor[temp]>5&&prio[temp]==0)&#123; prio[temp]=1; &#125; last[temp]=i; &#125; &#125; for(int i=0;i<=n;i++)&#123; scor[i]=Math.max(scor[i]-(t-last[i]),0); if(scor[i]<4&&prio[i]==1)&#123; prio[i]=0; &#125; &#125; int ans=0; for(int i=0;i<=n;i++)&#123; ans+=prio[i]; &#125; System.out.println(ans); &#125;&#125;</code></pre><h3 id="修改数组"><a href="#修改数组" class="headerlink" title="修改数组"></a>修改数组</h3><blockquote><p>时间限制: 1.0s 内存限制: 256.0MB 本题总分:20 分</p><p>【问题描述】<br>给定一个长度为 N 的数组 A = [A1, A2, · · · AN],数组中有可能有重复出现的整数。<br>现在小明要按以下方法将其修改为没有重复整数的数组。小明会依次修改<br>A2, A3, · · · , AN。<br>当修改 Ai 时,小明会检查 Ai 是否在 A1 ∼ Ai−1 中出现过。如果出现过,则小明会给 Ai 加上 1 ;如果新的 Ai 仍在之前出现过,小明会持续给 Ai 加 1 ,直到 Ai 没有在 A1 ∼ Ai−1 中出现过。<br>当 AN 也经过上述修改之后,显然 A 数组中就没有重复的整数了。现在给定初始的 A 数组,请你计算出最终的 A 数组。<br>【输入格式】<br>第一行包含一个整数 N。<br>第二行包含 N 个整数 A1, A2, · · · , AN 。<br>【输出格式】<br>输出 N 个整数,依次是最终的 A1, A2, · · · , AN。<br>【样例输入】<br>5<br>2 1 1 3 4</p><p>【样例输出】<br>2 1 3 4 5</p><p>【评测用例规模与约定】<br>对于 80% 的评测用例,1 ≤ N ≤ 10000。<br>对于所有评测用例,1 ≤ N ≤ 100000,1 ≤ Ai ≤ 1000000。<br>————————————————</p></blockquote><pre><code class="c++">#include<bits/stdc++.h>using namespace std;typedef long long ll;int bit[2000050];int n=1000001;int sum(int i)&#123; int s=0; while(i>0) &#123; s+=bit[i]; i-=i&-i; &#125; return s;&#125;void add(int i,int x)&#123; while(i<=n) &#123; bit[i]+=x; i+=i&-i; &#125;&#125;bool ok(int k,int pre)&#123; int l=k-pre+1; int cnt=sum(k)-sum(pre-1); return cnt<l;&#125;bool vis[1000005];int ans[100005];int N;int a[100005];int main()&#123; scanf("%d",&N); for(int i=0;i<N;i++)scanf("%d",&a[i]); for(int i=0;i<N;i++) &#123; if(!vis[a[i]]) &#123; ans[i]=a[i]; vis[a[i]]=1; add(a[i],1); &#125; else &#123; int l=a[i];int r=1000002; int mid; while(r-l>1) &#123; mid=(l+r)/2; if(ok(mid,a[i]))r=mid; else l=mid; &#125; ans[i]=r; vis[r]=1; add(r,1); &#125; &#125; for(int i=0;i<N;i++)printf("%d%c",ans[i],i==N-1?'\n':' '); return 0;&#125;</code></pre><h3 id="糖果"><a href="#糖果" class="headerlink" title="糖果"></a>糖果</h3><blockquote><p>糖果店的老板一共有 M 种口味的糖果出售。为了方便描述,我们将 M 种口味编号 1 ∼ M。<br>小明希望能品尝到所有口味的糖果。遗憾的是老板并不单独出售糖果,而 是 K 颗一包整包出售。<br>幸好糖果包装上注明了其中 K 颗糖果的口味,所以小明可以在买之前就知道每包内的糖果口味。<br>给定 N 包糖果,请你计算小明最少买几包,就可以品尝到所有口味的糖果。</p><p>【输入格式】<br>第一行包含三个整数 N、M 和 K。<br>接下来 N 行每行 K 这整数 T1, T2, · · · , TK,代表一包糖果的口味。<br>【输出格式】<br>一个整数表示答案。如果小明无法品尝所有口味,输出 −1。<br>【样例输入】<br>6 5 3<br>1 1 2<br>1 2 3<br>1 1 3<br>2 3 5<br>5 4 2<br>5 1 2</p><p>【样例输出】<br>2</p><p>【评测用例规模与约定】<br>对于 30% 的评测用例,1 ≤ N ≤ 20 。<br>对于所有评测样例,1 ≤ N ≤ 100,1 ≤ M ≤ 20,1 ≤ K ≤ 20,1 ≤ Ti ≤ M。</p></blockquote><pre><code class="c++">#include<bits/stdc++.h>using namespace std;int dp[1000005];int n,m,k;int s[105];//代表第i包糖果int main()&#123; memset(dp,-1,sizeof(dp)); scanf("%d%d%d",&n,&m,&k); for(int i=0;i<n;i++) &#123; int ss=0; int t; for(int j=0;j<k;j++) &#123; scanf("%d",&t); ss|=(1<<(t-1)); &#125; s[i]=ss; dp[ss]=1; &#125; for(int i=0;i<n;i++) &#123; for(int j=0;j<(1<<m);j++) &#123; if(dp[j]==-1)continue; if(dp[j|s[i]]==-1)dp[j|s[i]]=dp[j]+dp[s[i]]; else dp[j|s[i]]=min(dp[j|s[i]],dp[j]+dp[s[i]]); &#125; &#125; printf("%d\n",dp[(1<<m)-1]); return 0;&#125;</code></pre><h3 id="组合数问题"><a href="#组合数问题" class="headerlink" title="组合数问题"></a>组合数问题</h3><p>弃疗弃疗了</p>]]></content>
<summary type="html"><h1 id="寒假算法练习"><a href="#寒假算法练习" class="headerlink" title="寒假算法练习"></a>寒假算法练习</h1><h2 id="week-1"><a href="#week-1" class="headerlink" titl</summary>
<category term="算法" scheme="http://sweetheart.nefu.site/categories/%E7%AE%97%E6%B3%95/"/>
<category term="算法" scheme="http://sweetheart.nefu.site/tags/%E7%AE%97%E6%B3%95/"/>
<category term="c++" scheme="http://sweetheart.nefu.site/tags/c/"/>
</entry>
<entry>
<title>css前端页面布局</title>
<link href="http://sweetheart.nefu.site/2021/01/02/css%E5%89%8D%E7%AB%AF%E9%A1%B5%E9%9D%A2%E5%B8%83%E5%B1%80/"/>
<id>http://sweetheart.nefu.site/2021/01/02/css%E5%89%8D%E7%AB%AF%E9%A1%B5%E9%9D%A2%E5%B8%83%E5%B1%80/</id>
<published>2021-01-02T10:38:03.000Z</published>
<updated>2021-01-14T09:51:00.090Z</updated>
<content type="html"><![CDATA[<h1 id="css前端页面布局"><a href="#css前端页面布局" class="headerlink" title="css前端页面布局"></a>css前端页面布局</h1><p>前端三件套里面除了javascript之外,比较难学的就是css的页面布局操作,可以说css掌握好布局那么基本上就能写出一个一般通俗的静态页面了,其他都可以现学现抄</p><p>开始前补充关于div几个比较重要的知识点:</p><ul><li>div独占一行,所以第二个div默认情况下永远在div的下面,纵向排列</li><li>即使div设置了宽高,依旧会根据孩子进行宽高调整,而我们设置的宽高只是背景颜色范围,这也是为什么很多时候子div看起来溢出了页面的原因</li><li>div有自身的固有属性,比如总是会有8px的margin,为了美观记得消除margin等效果</li></ul><h2 id="浮动布局"><a href="#浮动布局" class="headerlink" title="浮动布局"></a>浮动布局</h2><p>浮动布局指:</p><ul><li>将元素排除在普通流之外</li><li>元素不在页面占据空间</li><li>将浮动元素放置在包含框的左右边</li><li>浮动元素依旧位于包含框之内</li></ul><p>浮动的框可以向左或者向右移动,直到外边缘碰到包含框或另一个浮动边框为止</p><ul><li>浮动元素的外边缘不会超过其父元素的内边缘</li><li>浮动元素不会相互重叠</li><li>浮动元素不会上下浮动</li><li>任何一个元素浮动,display属性完全失效,并且不会独占一行</li></ul><p>语法:</p><ul><li>float:none/left/right;</li></ul><pre><code class="html"><!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> #box&#123; width: 600px; height: 600px; background: deeppink; &#125; #box>div:first-child&#123; width: 200px; height: 200px; background: green; &#125; #box>div:nth-child(2) &#123; width: 200px; height: 200px; background: blue; &#125; #box>div:nth-child(3 ) &#123; width: 200px; height: 200px; background:red; &#125; </style></head><body> <div id="box"> <div></div> <div></div> <div></div> </div></body></html></code></pre><p>效果图如下:</p><p><img src="http://pan-yz.chaoxing.com/preview/showpreview_555513261589626880.html?v=1610374614000"></p><p>倘若设置浮动:</p><pre><code class="css"> <style> #box&#123; width: 600px; height: 600px; background: deeppink; &#125; #box>div:first-child&#123; width: 200px; height: 200px; background: green; float: right; &#125; #box>div:nth-child(2) &#123; width: 200px; height: 200px; background: blue; float: right; &#125; #box>div:nth-child(3 ) &#123; width: 200px; height: 200px; background:red; &#125; </style></code></pre><p>效果图如下:</p><p><img src="http://pan-yz.chaoxing.com/preview/showpreview_555513256077426688.html?v=1610374826000"></p><p>说明float碰到边缘停止,</p><p>打个比方,大的div外边框相当于七巧板的框</p><p>而不浮动的div相当于七巧板的框内花纹,而浮动的div相当于七巧板,碰到同样的七巧板或者边框就停止</p><p>原有的行容不下div的时候,会自动到下一行找更大空间</p><p>覆盖关系由孩子关系决定</p><ul><li>div的本质属性是不设置宽度的时候独占一行,</li><li>span标签的特点是没有宽高属性,并且不会独占一行</li><li>如果设置了float,给无宽高属性的元素会生效宽高属性</li></ul><p>如果父元素没有设置宽高,而子元素有设置宽高,那么父元素会根据子元素调整自己的宽高属性</p><p>例如:</p><pre><code class="css"> <style> #box&#123; /* width: 600px; height: 600px; */ background: deeppink; &#125; #box>div:first-child&#123; width: 200px; height: 200px; background: green; /* float: right; */ &#125; #box>div:nth-child(2) &#123; width: 200px; height: 200px; background: blue; /* float: right; */ &#125; #box>div:nth-child(3 ) &#123; width: 200px; height: 200px; background:red; &#125; </style></code></pre><p>效果图如下,说明:</p><ul><li>div的本质属性是不设置宽度的时候独占一行,<ul><li>所以父元素占了一整行</li><li>子元素虽然宽没有满行,但是依旧占了一整行,导致排成一列</li></ul></li><li>父div根据子div调整宽高</li></ul><p>如果给部分元素恢复浮动,如下:</p><pre><code class="css"> <style> #box&#123; /* width: 600px; height: 600px; */ background: deeppink; &#125; #box>div:first-child&#123; width: 200px; height: 200px; background: green; float: right; &#125; #box>div:nth-child(2) &#123; width: 200px; height: 200px; background: blue; float: right; &#125; #box>div:nth-child(3 ) &#123; width: 200px; height: 200px; background:red; &#125; </style></code></pre><p>效果图如下:</p><p><img src="http://pan-yz.chaoxing.com/preview/showpreview_555513241930924032.html?v=1610374864000"></p><p>那么说明在有浮动条件下div感受根据浮动调整,可以认为外边框是一个可伸缩的长方形边框</p><p>内部元素float的情况下,父亲感知不到内元素高度</p><p>解决方法:</p><ul><li><p>设置父元素宽高</p></li><li><p>父元素设置overflow:hidden;</p><p>如下:</p><pre><code class="css"> <style> #box&#123; /* width: 600px; height: 600px; */ background: deeppink; overflow: hidden; &#125; #box>div:first-child&#123; width: 200px; height: 200px; background: green; float: right; &#125; #box>div:nth-child(2) &#123; width: 200px; height: 200px; background: blue; float: right; &#125; #box>div:nth-child(3 ) &#123; width: 200px; height: 200px; background:red; float: right; &#125; </style></code></pre><p>如下图所示:</p></li><li><p>父类设置浮动,兄弟元素清除浮动clear</p></li></ul><p>注意浮动是优先在行内操作</p><p>假设现在有一个div,宽度不比行内宽度小,所以不足以移到下一行,若想移到下一行,则要设置</p><pre><code class="css">clear:both;/*清除两边浮动*/</code></pre><p>这个可以抵消其他元素浮动对当前元素的影响</p><p>属性:clear</p><p>值:left,right,both</p><h2 id="头部布局以及font字体图标使用"><a href="#头部布局以及font字体图标使用" class="headerlink" title="头部布局以及font字体图标使用"></a>头部布局以及font字体图标使用</h2><p>网页布局的时候一般是先水平再垂直,头部布局一般适用于网页导航栏</p><p>这里先学习导航栏的布局:</p><p>html:</p><pre><code class="html"><!DOCTYPE html><html> <head> <meta charset="utf-8" /> <title>test</title> <link rel="stylesheet" type="text/css" href="./css/style.css"/> <!-- 这里引入css文件 --> </head> <body> <div id="header"> <div class="header"> <div class="header_left"> </div> <div class="header_right"> </div> </div> </div> </body></html></code></pre><p>引入的css文件:</p><pre><code class="css">#header&#123; width: 100%; height: 40px; background: red;&#125;.header&#123; width: 50%; height: 40px; background: green;&#125;.header_left&#123; width: 200px; height: 40px; background: aqua;&#125;.header_right&#123; width: 300px; height: 40px; background: pink;&#125;</code></pre><p>初步的效果图如下:</p><p><img src="http://pan-yz.chaoxing.com/preview/showpreview_555513260343988224.html?v=1610374496000"></p><p>但是注意到由于div独占一行的原因</p><p>这里pink的div出来了,说明等待解决问题</p><p>利用上次学到的浮动属性,让pink和aqua在green里面浮动:</p><pre><code class="css">#header&#123; width: 100%; height: 40px; background: red;&#125;.header&#123; width: 50%; height: 40px; background: green;&#125;.header_left&#123; width: 200px; height: 40px; background: aqua; float: left;&#125;.header_right&#123; width: 300px; height: 40px; background: pink; float: right;&#125;</code></pre><p>效果图如下:</p><p> 图丢了</p><p>这时首页头部的基本框架搭好了,取消父类容器颜色,并且加入子类文字:</p><p>html:</p><pre><code class="html"><!DOCTYPE html><html> <head> <meta charset="utf-8" /> <title>test</title> <link rel="stylesheet" type="text/css" href="./css/style.css"/> <!-- 这里引入css文件 --> </head> <body> <div id="header"> <div class="header"> <div class="header_left"> <div > <span > 我是头部 </span> </div> </div> <div class="header_right"> </div> </div> </div> </body></html></code></pre><p>css:</p><pre><code class="css">#header&#123; width: 100%; height: 40px; /* background: red; */&#125;.header&#123; width: 50%; height: 40px; /* background: green; */ border:1px solid #FF0000;&#125;.header_left&#123; width: 200px; height: 40px; /* background: aqua; 取消父类容器颜色*/ float: left;&#125;.header_right&#123; width: 300px; height: 40px; background: pink; float: right;&#125;.header_left>div&#123; float: left; line-height: 40px; color: dimgray; /* 设置字体颜色,在父类中 */&#125;.header_left>div>span&#123; font-weight: bold; /* 设置字体加粗 */&#125;</code></pre><p>效果如下</p><p> 图又无了</p><p>设置超链接:</p><pre><code class="html"><div > <a href=""> <img src="" alt="" > 核心产品 <i></i> </a></div></code></pre><p>为了清除原有超链接丑不拉几的样式,css里面设置为</p><pre><code class="css">a&#123; text-decoration: none;&#125;</code></pre><p>这样去掉了下划线的样式</p><p>然后设置添加图片</p><p>html:</p><pre><code class="html"><body> <div id="header"> <div class="header"> <div class="header_left"> <div > <span > 我是头部 </span> </div> <div > <a href=""> <img src="./img/imag.png" alt="" > 核心产品 <i></i> </a> </div> </div> <div class="header_right"> </div> </div> </div> </body></code></pre><p>css:</p><pre><code class="css">.header>div:nth-child(2)>a,.header_left>div:nth-child(2)>a>img,.header_left>div:nth-child(2)>a>i&#123; float: left;&#125;.header_left>div:nth-child(2)>a>img&#123; width: 17px;&#125;</code></pre><p>这里全部设置为浮动布局,并且调整了图片大小如图:</p><p><img src="http://pan-yz.chaoxing.com/preview/showpreview_555513259392987136.html?v=1610374390000"></p><p>下面是给文字添加图标:</p><p>阿里图标库,找到想要的图标后</p><ul><li><p>点击加入购物车</p></li><li><p>点击购物车添加到项目</p></li><li><p>点击项目更新代码</p></li><li><p>复制更新后的链接,引入到页面的css的link,这样:</p><pre><code class="css"><linkrel="stylesheet"type="text/css"href="//at.alicdn.com/t/font_2076021_pp0wtm9fh8j.css"/></code></pre></li><li><p>复制好想要的图标的代码后,如下(注意复制好代码后再标注iconfont才能显示出来):</p><pre><code class="html"><div > <a href=""> <img src="./img/imag.png" alt="" > 核心产品 <i class="icon-arrow-down iconfont"></i> </a></div></code></pre></li><li><p>取消i标签的浮动(不取消浮动i标签跑前面去),并且修改超链接字体颜色:</p><p>去除样式的一篇参考blog:<a href="https://blog.csdn.net/hl_qianduan/article/details/84964511?ops_request_misc=%25257B%252522request%25255Fid%252522%25253A%252522161037371816780266298133%252522%25252C%252522scm%252522%25253A%25252220140713.130102334.pc%25255Fall.%252522%25257D&request_id=161037371816780266298133&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_v2~rank_v29-1-84964511.pc_search_result_cache&utm_term=%E5%8E%BB%E9%99%A4%E9%BB%98%E8%AE%A4%E6%A0%B7%E5%BC%8F">去除css中的默认样式</a></p><pre><code class="css">.header>div:nth-child(2)>a,.header_left>div:nth-child(2)>a>img,&#123; float: left; color:dimgrey;&#125;.header_left>div:nth-child(2)>a>img&#123; width: 17px;&#125; a&#123;text-decoration: none;color:#333;&#125; a:hover, a:visited, a:link, a:active &#123; color:dimgrey; // 设置使所有a标签的四种状态都和本身颜色保持一致,样式代码自己写&#125;</code></pre></li></ul><p>最终的效果图如下:</p><p><img src="http://pan-yz.chaoxing.com/preview/showpreview_555513257500176384.html?v=1610374336000"></p><h2 id="定位属性"><a href="#定位属性" class="headerlink" title="定位属性"></a>定位属性</h2><p>接下来由于时间原因进行总结性概括,不再进行详细描述,反正csdn都能找到</p><h3 id="相对定位"><a href="#相对定位" class="headerlink" title="相对定位"></a>相对定位</h3><p>相对于div原有位置进行的定位,相对于自己</p><pre><code class="css">position:relative;top:200px;left:200;</code></pre><p>会占有原有位置</p><h3 id="绝对定位"><a href="#绝对定位" class="headerlink" title="绝对定位"></a>绝对定位</h3><p>绝对定位相对于整个大的div的右上角定位</p><pre><code class="css">position:absolute;top:200px;left:200;</code></pre><p>不会占有原有位置</p><h3 id="相对父容器的绝对定位"><a href="#相对父容器的绝对定位" class="headerlink" title="相对父容器的绝对定位"></a>相对父容器的绝对定位</h3><p>由于决定定位是全局的,若要设置局部绝对</p><p>父类(外层谁设置相对谁)的position设置为相对,或者absulute(非static默认</p><p>子类为absolute;</p><p>可以实现子类相对于父类的绝对定位</p><p>如果元素外层没有一个设置为定位,那么参考点就是body</p><h3 id="固定定位"><a href="#固定定位" class="headerlink" title="固定定位"></a>固定定位</h3><p>很多吧不随滚动条移动的效果就是用这个做出来的</p><p>视差网页也是这样</p><pre><code class="css">position:fixed;right:200px;top:200px;</code></pre><h3 id="堆叠顺序"><a href="#堆叠顺序" class="headerlink" title="堆叠顺序"></a>堆叠顺序</h3><p>z-index</p><ul><li>一旦修改了元素的定位方式,则元素可能会发生堆叠</li><li>可以使用z-index属性来控制元素框出现的重叠顺序</li><li>z-index仅能在定位的元素上生效</li><li>z-index属性:<ul><li><strong>值为数值,数值越大表示堆叠顺序越高,即离用户越近</strong></li><li>可以设置为负值,表示离用户更远,一般不要设置</li><li><strong>Z-index仅能在定位元素上奏效</strong></li></ul></li></ul><p>比如当元素进行absolute定位产生堆叠的时候</p><p>写法如下:</p><pre><code class="css">z-index:1;z-index:2;z-index:3;</code></pre><h2 id="display属性"><a href="#display属性" class="headerlink" title="display属性"></a>display属性</h2><p>根据CSS规范的规定,每一个网页元素都有一个display属性,用于确定该元素的类型,每一个元素都有默认的display属性值,比如div元素,它的默认display属性值为“block”,称为块元素,而span元素的默认display属性值为“inline”,称为“行内”元素。</p><p>块元素与行元素是可以转换的,也就是说display的属性值可以由我们来改变</p><p>display常见属性值:</p><ul><li><ol><li>none:隐藏对象,<strong>体积同样消失,不占据原有位置</strong><ul><li>visibility:hidden同样可以隐藏,但是占据空间</li><li>opacity:50%设置透明度</li><li>怎么隐藏怎么显示</li></ul></li><li>inline:指定对象为内联元素<strong>在行内布局,没有宽高属性</strong></li><li>block:指定对象为块元素<strong>独占一行</strong></li><li>inline-block:指定对象为内联块元素<strong>让几个div在行内并列显示,有宽高属性</strong></li><li>table-cell:指定对象作为表格单元格<strong>同上</strong></li><li><strong>flex:弹性盒</strong></li></ol></li></ul><h2 id="标准盒子模型"><a href="#标准盒子模型" class="headerlink" title="标准盒子模型"></a>标准盒子模型</h2><p>盒子模型是css中一个重要的概念,理解了盒子模型才能更好的排版。W3C组织建议把网页上元素看成是一个个盒子。盒模型主要定义四个区域:内容(content)内边距(padding)、边框(border)、外边距(margin)。转换到我们日常生活中,可以拿手机盒来对比,手机=内容,内边距=盒子中的填充物,边框-盒子的厚度,外边距两个手机盒之间的距离。</p><p>通常我们设置的宽和高是指“手机”content的宽高,一整个盒子还包含了“填充物”、盒子、盒子与盒子的距离</p><p>关系如图:</p><p><img src="http://pan-yz.chaoxing.com/preview/showpreview_556533883375620096.html?v=1610617629000" alt="示意图"></p><p>margin与padding的写法不再赘述;自己查csdn;</p><h3 id="关于margin"><a href="#关于margin" class="headerlink" title="关于margin"></a>关于margin</h3><ul><li><p>利用margin可以设置块状元素居中</p><pre><code class="css"> margin:10px auto;</code></pre><p>上下10px,内部居中</p></li><li><p>上下margin会合并<strong>无左右合并</strong></p><p>比如上容器margin-bottom:150px;下容器margin-top=50px;但是这两者间距是150px,取最大值margin</p><p>浮动元素不合并;</p></li><li><p><strong>包含式margin合并</strong></p><p>子容器的margin并不会导致与父容器内部产生距离,而是会让父容器也有一个margin</p><p>建议父容器padding或者bottom;</p></li><li><p>margin可以负值</p></li></ul><h3 id="关于border"><a href="#关于border" class="headerlink" title="关于border"></a>关于border</h3><ul><li><p>写法见csdn:宽度 样式 颜色</p></li><li><p>style(实线或者虚线)属性为空,边框不出现</p></li><li><p>style取值:</p><ul><li>点:dotted</li><li>实线:solid</li><li>双线:double(需要三像素以上</li><li>虚线:dashed</li><li>无边框:none</li></ul></li></ul><h3 id="关于padding"><a href="#关于padding" class="headerlink" title="关于padding"></a>关于padding</h3><ul><li><p>简写:</p><ul><li>padding :value(四个方向相同);</li><li>padding: value(上下) value(左右);</li><li>padding: value (上) value(左右)vadue(下);</li><li>padding: value(上) value(右) value(下)value(左);</li></ul></li><li><p>当内边距挤压子容器的时候,内边距会扩大外部容器,并不会覆盖子容器,border也是</p><p>所以容器原始大小设置因为padding与border改动,margin不会</p></li></ul><h2 id="怪异盒子模型"><a href="#怪异盒子模型" class="headerlink" title="怪异盒子模型"></a>怪异盒子模型</h2><p>适配ie浏览器的盒子模型,</p><p>特点是padding与border不会改变盒子大小</p><p>其他不赘述</p><h2 id="浏览器私有前缀"><a href="#浏览器私有前缀" class="headerlink" title="浏览器私有前缀"></a>浏览器私有前缀</h2><p>根据不同的浏览器内核,css前缀会有不同。最基本的浏览器内核有如下四种,其它的内核都是基于此四种进行再研发的。</p><ul><li><ol><li>Gecko内核 前缀为-moz-火狐浏览器</li><li>Webkit内核 前缀为-webkit-也叫谷歌内核,chrome浏览器最先开发使用,safari浏览器也使用,该内核。国内很多浏览器也使用了webkit内核,如360极速、世界之窗、猎豹等。</li><li>Trident内核 前缀为-ms-也称IE内核</li><li>Presto内核 前缀-o-目前只有opera采用</li></ol></li></ul><p>为了适配不同浏览器,如果写法是css3实验性阶段的语句,保险起见不但要吧所有浏览器前缀写一遍,还要再写一次原属性</p><p>但是如果都是css2标准就不用啦~~</p><h2 id="圆角边框与阴影渐变"><a href="#圆角边框与阴影渐变" class="headerlink" title="圆角边框与阴影渐变"></a>圆角边框与阴影渐变</h2><p>这里给出一个好用的圆角边框生成网站,以及参考blog:</p><p><a href="https://neumorphism.io/#586d79">懒癌专用</a></p><p><a href="https://blog.csdn.net/qq_42221334/article/details/87806624?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522161060780016780277083403%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=161060780016780277083403&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_v2~rank_v29-1-87806624.pc_search_result_cache&utm_term=css%E9%98%B4%E5%BD%B1&spm=1018.2226.3001.4187">具体阴影调整写法</a></p><p><a href="https://blog.csdn.net/qq_42039281/article/details/82153805?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522161060796616780255218050%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=161060796616780255218050&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_v2~rank_v29-2-82153805.pc_search_result_cache&utm_term=css%E6%B8%90%E5%8F%98&spm=1018.2226.3001.4187">渐变设置</a></p><p>好了你已经学完了</p><h2 id="hover应用之小标签实战"><a href="#hover应用之小标签实战" class="headerlink" title="hover应用之小标签实战"></a>hover应用之小标签实战</h2><p>CSS部分:</p><pre><code class="css">#box&#123; /* border: 1px solid blue; */ float: left; position: relative;&#125;/* 父容器设置相对定位,让子容器能对父容器定位 */#box>div&#123; /* border: 1px solid green; */ float: left; padding: 10px 20px; color: #fff; font-weight: bold;&#125;/* 每个头标签的基本配置 */#box>div:first-child&#123; background-color: #009764;&#125;#box>div:nth-child(2)&#123; background-color:#da1941;&#125;#box>div:last-child&#123; background-color: #eab719;&#125;#box>div>div&#123; position: absolute;/* border: #DA1941 solid 1px; */ top: 40px; left: 0px; padding: 20px; width: 205px; height: 80px; display: none;&#125;/* 先将块元素隐藏,absolu下标签会一个一个覆盖 */#box>div:hover>div&#123; display: block;&#125;/* 当鼠标移到标签的时候,设置展示 */#box>div:first-child>div&#123; background:linear-gradient(50deg,#009764,#009764);&#125;#box>div:nth-child(2)>div&#123; background:linear-gradient(50deg,#da1941,#da1941);&#125;#box>div:last-child>div&#123; background:linear-gradient(50deg,#eab719,#eab719);&#125;</code></pre><p>HTML部分:</p><pre><code class="html"><!DOCTYPE html><html> <head> <meta charset="utf-8" /> <title>小标签</title> <link rel="stylesheet" type="text/css" href="./css/style.css"/> <!-- 这里引入css文件 --> <link rel="stylesheet" type="text/css" href="//at.alicdn.com/t/font_2076021_pp0wtm9fh8j.css"/> </head> <body> <div id="box"> <div > 标签1 <div > 标签1的内容 </div> </div> <div > 标签2 <div> 标签2的内容 </div> </div> <div > 标签3 <div> 标签3的内容 </div> </div> </div> </body></html></code></pre><p>最后效果如图:</p><p><img src="http://pan-yz.chaoxing.com/preview/showpreview_556533843555368960.html?v=1610617723000" alt="鼠标不触碰div"></p><p><img src="http://pan-yz.chaoxing.com/preview/showpreview_556533879492800512.html?v=1610617775000" alt="鼠标移到div上"></p><p><img src="http://pan-yz.chaoxing.com/preview/showpreview_556533902329606144.html?v=1610617834000" alt="鼠标移到div上"></p>]]></content>
<summary type="html"><h1 id="css前端页面布局"><a href="#css前端页面布局" class="headerlink" title="css前端页面布局"></a>css前端页面布局</h1><p>前端三件套里面除了javascript之外,比较难学的就是css的页面布局操作,可以</summary>
<category term="web" scheme="http://sweetheart.nefu.site/categories/web/"/>
<category term="前端" scheme="http://sweetheart.nefu.site/categories/web/%E5%89%8D%E7%AB%AF/"/>
<category term="html" scheme="http://sweetheart.nefu.site/tags/html/"/>
<category term="css" scheme="http://sweetheart.nefu.site/tags/css/"/>
<category term="前端" scheme="http://sweetheart.nefu.site/tags/%E5%89%8D%E7%AB%AF/"/>
</entry>
<entry>
<title>tensoflow基础</title>
<link href="http://sweetheart.nefu.site/2020/11/11/tensoflow%E5%9F%BA%E7%A1%80/"/>
<id>http://sweetheart.nefu.site/2020/11/11/tensoflow%E5%9F%BA%E7%A1%80/</id>
<published>2020-11-11T09:57:31.000Z</published>
<updated>2021-01-12T09:39:08.391Z</updated>
<content type="html"><![CDATA[<h1 id="Tensorflow基础"><a href="#Tensorflow基础" class="headerlink" title="Tensorflow基础"></a>Tensorflow基础</h1><p> TensorFlow是现在比较火爆的一个深度学习的框架,内部集成了多种优化算法还有模型框架,所以对初学者十分友好,所以今天起开始自己的TensorFlow第一步</p><h2 id="训练自己的第一个神经网络"><a href="#训练自己的第一个神经网络" class="headerlink" title="训练自己的第一个神经网络"></a>训练自己的第一个神经网络</h2><p>代码如下</p><ul><li><p>第一次上手tensorflow结果发现憨憨的自己抄的代码是temsoflow1.0的版本</p><p>但是安装的tensorflow版本是2.1.3,在咨询了下csdn后在原代码的基础上做了下版本转换</p><p>然而只是试水了下而已,个人认为tensorflow2.0版本更加友好,更简洁,没有session这种操作,后面都会用tensorflow2.0版本实现,指导课程为北大</p></li></ul><pre><code class="python">import tensorflow.compat.v1 as tfimport numpy as nptf.disable_v2_behavior()# create datax_data = np.random.rand(100).astype(np.float32)##随机生成100个数据y_data = x_data * 0.1 + 0.3 #随机生成y# create tensorflow struct start 新建Weights = tf.Variable(tf.random_uniform((1,), -1.0, 1.0))#随机生成权重biases = tf.Variable(tf.zeros((1,)))#初始化Biasesy = Weights * x_data + biases#定义函数loss = tf.reduce_mean(tf.square(y - y_data))#根据均方根差进行梯度下降optimizer = tf.train.GradientDescentOptimizer(0.5)#梯度下降,设置学习率为0.5train = optimizer.minimize(loss)init = tf.initialize_all_variables()# 创建sessionsess = tf.Session()#session是一个对话控制,对sess.run(init)for step in range(201):#训练200轮 sess.run(train) if step % 20 == 0: print(step, sess.run(Weights), sess.run(biases), sess.run(loss)) ##每20轮输出一次训练后的权重还有偏差还有损失</code></pre><p>输出如下:</p><pre><code class="python">0 [-0.00268313] [0.5169402] 0.02760824420 [0.0633762] [0.32074773] 0.0001312771540 [0.09214579] [0.3044495] 6.037642e-0660 [0.0983156] [0.30095425] 2.7768752e-0780 [0.09963877] [0.30020466] 1.2771677e-08100 [0.09992254] [0.3000439] 5.874353e-10120 [0.09998339] [0.30000943] 2.7032572e-11140 [0.09999646] [0.300002] 1.2318857e-12160 [0.09999923] [0.30000046] 6.0014216e-14180 [0.09999982] [0.3000001] 3.7214676e-15200 [0.09999991] [0.30000007] 1.2079227e-15##可见训练次数越多</code></pre><p>进行线性回归预测</p><pre><code class="python">##懒得下数据集了,所以就自己生成了一个数据集##线性回归import numpy as npimport matplotlib.pyplot as pltimport tensorflow as tfx_data = np.random.rand(100).astype(np.float32)y_data = x_data * 0.1 + 0.3 # 很显然这个是个非常明显的线性回归plt.scatter(x_data, y_data) #绘制数据集的形状,是一个严格符合线性回归的散点图# 建立顺序模型model = tf.keras.Sequential() # 实例化一个模型model.add(tf.keras.layers.Dense(1, input_shape=(1,)))#定义神经元的数目,由于输入的维度就一个就定义一个输入model.compile( optimizer='adam', loss='mse')#选择优化算法,这里我们选择adam优化的梯度下降算法,基于均方根差model.fit(x_data,y_data,epochs=10)#对模型训练10轮print(model.predict(x_data))#这时训练结束,对输入X进行预测</code></pre><h2 id="神经网络计算"><a href="#神经网络计算" class="headerlink" title="神经网络计算"></a>神经网络计算</h2><h3 id="神经网络设计过程"><a href="#神经网络设计过程" class="headerlink" title="神经网络设计过程"></a>神经网络设计过程</h3><p>鸢尾花设计分类</p><p>Y=x*w+b 一般神经网络的设计过程</p><pre><code class="python">import tensorflow as tfw=tf.Variable(tf.constant(5,dtype=tf.float32))#设置w的随机初始值为5lr=0.2#学习率epoch=40#迭代次数for i in range(epoch):#在每一次的迭代中 with tf.GradientTape() as tape:#执行梯度下降算法 loss=tf.square(w+1)#损失函数定义为loss=(w+1)^2 grads=tape.gradient(loss,w)#告知对w求偏导 w.assign_sub((lr*grads))#每次减去学习率乘上导数 print("在%s 次迭代后,w变为%f ,loss变为 %f"%(epoch,w.numpy(),loss))</code></pre><p>结果如下:</p><p>在1 次迭代后,w变为2.600000 ,loss变为 36.000000<br>在2 次迭代后,w变为1.160000 ,loss变为 12.959999<br>在3 次迭代后,w变为0.296000 ,loss变为 4.665599<br>在4 次迭代后,w变为-0.222400 ,loss变为 1.679616<br>在5 次迭代后,w变为-0.533440 ,loss变为 0.604662<br>在6 次迭代后,w变为-0.720064 ,loss变为 0.217678<br>在7 次迭代后,w变为-0.832038 ,loss变为 0.078364<br>在8 次迭代后,w变为-0.899223 ,loss变为 0.028211<br>在9 次迭代后,w变为-0.939534 ,loss变为 0.010156<br>在10 次迭代后,w变为-0.963720 ,loss变为 0.003656<br>在11 次迭代后,w变为-0.978232 ,loss变为 0.001316<br>在12 次迭代后,w变为-0.986939 ,loss变为 0.000474<br>在13 次迭代后,w变为-0.992164 ,loss变为 0.000171<br>在14 次迭代后,w变为-0.995298 ,loss变为 0.000061<br>在15 次迭代后,w变为-0.997179 ,loss变为 0.000022<br>在16 次迭代后,w变为-0.998307 ,loss变为 0.000008<br>在17 次迭代后,w变为-0.998984 ,loss变为 0.000003<br>在18 次迭代后,w变为-0.999391 ,loss变为 0.000001<br>在19 次迭代后,w变为-0.999634 ,loss变为 0.000000<br>在20 次迭代后,w变为-0.999781 ,loss变为 0.000000<br> …..</p><p> …..<br>在40 次迭代后,w变为-1.000000 ,loss变为 0.000000</p><p>多次改变学习率,发现结果不一样,</p><p>学习率过小时,40次loss都没达到0</p><p>学习率过大时也找不到</p><h3 id="张量生成"><a href="#张量生成" class="headerlink" title="张量生成"></a>张量生成</h3><h4 id="张量含义"><a href="#张量含义" class="headerlink" title="张量含义"></a>张量含义</h4><p>tensorflow中的tensor就是指张量的意思,多维数组和列表的意思</p><p>0-D的张量表示一个单独的数 1,2,3,4…..</p><p>1-D的张量表示一个向量 [1,2,3,4,…..]</p><p>2-D的张量表示一个矩阵[[1,2,3],[4,5,6],……]</p><p>3-D的张量表示一个立方,每一层是一个矩阵</p><p>[[[1,2,3],[3,4,5]],</p><p>[[8,9,0],[7,8,5]]]</p><p>n-D以此类推……</p><h4 id="数据类型"><a href="#数据类型" class="headerlink" title="数据类型"></a>数据类型</h4><ul><li><p>tf.int,tf.float…….</p><ul><li>tf.int32,tf.float32,tf.float64</li></ul></li><li><p>tf.bool</p><ul><li>tf.constant([True,False])</li></ul></li><li><p>tf.string</p><ul><li>tf.constant(“hollow”)</li></ul></li></ul><h4 id="创建张量"><a href="#创建张量" class="headerlink" title="创建张量"></a>创建张量</h4><p>直接创建:</p><pre><code class="python">import tensorflow as tfa=tf.constant([1,5],dtype=tf.int64)#实例化一个张量print(a)print(a.dtyppe)print(a.shape)</code></pre><p>numpy转换:</p><pre><code class="python">import tensorflow as tfimport numpy as npa=np.arange(0,5)b=tf.convert_to_tensor(a,dtype=tf.int64)#将numpy格式转换成tf张量格式print(a)print(b)#[0 1 2 3 4]#tf.Tensor([0 1 2 3 4], shape=(5,), dtype=int64)</code></pre><p>一维直接写个数,二维用行列,三维用[n,m,j,k,…..]</p><pre><code class="python">#tf.zreos(维度)#tf.fill(维度,指定值)#tf.ones(维度)a=tf.zeros([2,3])b=tf.fill([2,2],9)</code></pre><p>其他生成张量:</p><pre><code class="python">#tf.random.normal(维度,meaan=均值,stddv=标准差)#生成符合正态分布的张量#tf.random.truncated_normal(维度,均值,标准差)#生成截断式分布的随机数,保证生成数在2sitar之间a=tf.random.normal([2,2],mean=0.5,stddev=1)b=tf.random.truncated_normal([2,2],mean=0.5,stddev=1)#结果如下tf.Tensor([[ 1.1104964 -0.04805636] [ 0.00457174 -0.14143777]], shape=(2, 2), dtype=float32)tf.Tensor([[ 2.312311 1.8229972 ] [-0.07491392 0.20661339]], shape=(2, 2), dtype=float32)a=tf.random.uniform([2,2],minval=0,maxval=1)#生成平均分布的随机数print(a)#结果如下tf.Tensor([[0.33741152 0.5539886 ] [0.8860432 0.18990982]], shape=(2, 2), dtype=float32)</code></pre><h3 id="常用函数"><a href="#常用函数" class="headerlink" title="常用函数"></a>常用函数</h3><h4 id="张量操作"><a href="#张量操作" class="headerlink" title="张量操作"></a>张量操作</h4><h5 id="tf-cast-tf-reduce"><a href="#tf-cast-tf-reduce" class="headerlink" title="tf.cast()/tf.reduce"></a>tf.cast()/tf.reduce</h5><pre><code class="python">tf.cast(a,dtype=iny64)#转换数据类型用tf.reduce_min(a)#计算张量上的最小值#同理tf.reduce_操作 还有其他的方法,</code></pre><p>轴axis:</p><p>axis=0:表示纵轴</p><p>axis=1:表示横轴,</p><p>则可用其表示求解均值还有最大值的方向</p><p>不指定axis时,对所有元素进行操作</p><pre><code class="python">x=tf.constant([[1,2,3],[2,2,3]])print(x)print(tf.reduce_mean(x))print(tf.reduce_mean(x,axis=1))#结果如下:tf.Tensor([[1 2 3] [2 2 3]], shape=(2, 3), dtype=int32)tf.Tensor(2, shape=(), dtype=int32)tf.Tensor([2 2], shape=(2,), dtype=int32)</code></pre><h5 id="tf-Variable"><a href="#tf-Variable" class="headerlink" title="tf.Variable"></a>tf.Variable</h5><p>tf.Variable将变量标记为可训练,被标记的变量会在反向传播中记录梯度信息,神经网络中,常用该函数标记待训练参数</p><p>tf.Variable(初始值)</p><pre><code class="python">w=tf.Variable(tf.random.normal([2,2],mean=0,stddev=1))</code></pre><h4 id="数学运算操作"><a href="#数学运算操作" class="headerlink" title="数学运算操作"></a>数学运算操作</h4><h5 id="四则运算函数"><a href="#四则运算函数" class="headerlink" title="四则运算函数"></a>四则运算函数</h5><pre><code class="python">x=tf.constant([[1,2],[2,5]])x=tf.cast(x,dtype=float)y=tf.random.normal([2,2],mean=1,stddev=0.5)print(x)print(y)print(tf.add(x,y))print(tf.subtract(x,y))print(tf.multiply(x,y))print(tf.divide(x,y))</code></pre><p>结果如下:</p><pre><code class="python">tf.Tensor([[1. 2.] [2. 5.]], shape=(2, 2), dtype=float32)tf.Tensor([[1.2040572 0.82556653] [0.49909478 1.6746361 ]], shape=(2, 2), dtype=float32)tf.Tensor([[2.2040572 2.8255665] [2.4990947 6.674636 ]], shape=(2, 2), dtype=float32)tf.Tensor([[-0.20405722 1.1744335 ] [ 1.5009053 3.3253639 ]], shape=(2, 2), dtype=float32)tf.Tensor([[1.2040572 1.6511331 ] [0.99818957 8.37318 ]], shape=(2, 2), dtype=float32)tf.Tensor([[0.83052534 2.4225788 ] [4.007255 2.9857233 ]], shape=(2, 2), dtype=float32)</code></pre><p>注意只有维度相同的张量才可以进行四则运算,所以是点乘点加,不是矩阵运算</p><h5 id="幂操作"><a href="#幂操作" class="headerlink" title="幂操作"></a>幂操作</h5><pre><code class="python">x=tf.constant([[1,2],[2,5]])x=tf.cast(x,dtype=float)print(x)print(tf.pow(x,3))print(tf.square(x))print(tf.sqrt(x))#结果如下:tf.Tensor([[1. 2.] [2. 5.]], shape=(2, 2), dtype=float32)tf.Tensor([[ 1. 8.] [ 8. 125.]], shape=(2, 2), dtype=float32)tf.Tensor([[ 1. 4.] [ 4. 25.]], shape=(2, 2), dtype=float32)tf.Tensor([[1. 1.4142135] [1.4142135 2.236068 ]], shape=(2, 2), dtype=float32)</code></pre><p>以上都是矩阵的点操作</p><h5 id="矩阵乘法"><a href="#矩阵乘法" class="headerlink" title="矩阵乘法"></a>矩阵乘法</h5><pre><code class="python">tf.matmul(矩阵1,矩阵2)</code></pre><p>要符合矩阵运算</p><h4 id="训练操作"><a href="#训练操作" class="headerlink" title="训练操作"></a>训练操作</h4><h5 id="特征与标签配对的函数"><a href="#特征与标签配对的函数" class="headerlink" title="特征与标签配对的函数"></a>特征与标签配对的函数</h5><pre><code class="python">data=tf.data.Dataset.from_tensor_slices((输入特征,标签))</code></pre><p>举例如下</p><pre><code class="python">features = tf.constant([12,23,10,17])labels = tf.constant([0,1,1,0])dataset= tf.data.Dataset.from_tensor_slices((features, labels))print(dataset)for element in dataset: print(element)#结果如下<TensorSliceDataset shapes: ((), ()), types: (tf.int32, tf.int32)>(<tf.Tensor: shape=(), dtype=int32, numpy=12>, <tf.Tensor: shape=(), dtype=int32, numpy=0>)(<tf.Tensor: shape=(), dtype=int32, numpy=23>, <tf.Tensor: shape=(), dtype=int32, numpy=1>)(<tf.Tensor: shape=(), dtype=int32, numpy=10>, <tf.Tensor: shape=(), dtype=int32, numpy=1>)(<tf.Tensor: shape=(), dtype=int32, numpy=17>, <tf.Tensor: shape=(), dtype=int32, numpy=0>)</code></pre><h5 id="求取梯度"><a href="#求取梯度" class="headerlink" title="求取梯度"></a>求取梯度</h5><p>tf.GradientTape()</p><pre><code class="python">with tf.GradientTape() as tape:#执行梯度下降算法 w=tf.Variable(tf.constant(3.0)) loss=tf.square(w+1)#损失函数定义为loss=(w+1)^2grad=tape.gradient(loss,w)print(grad)#结果如下:tf.Tensor(8.0, shape=(), dtype=float32)</code></pre><h5 id="枚举"><a href="#枚举" class="headerlink" title="枚举"></a>枚举</h5><p>enumerate是python内建的函数,可以遍历每个列表元素</p><p>组合为索引 元素</p><pre><code class="python">seq=['one','two','three']for i,element in enumerate(seq): print(i,element)</code></pre><h5 id="独热码"><a href="#独热码" class="headerlink" title="独热码"></a>独热码</h5><p>tf.one_hot 特征向量形式表示分类</p><p>tf.one_hot(待转换数据,depth=几分类)</p><pre><code class="python">classes=3label=tf.constant([1,0,2])output=tf.one_hot(label,depth=classes)print(output)#表示如下tf.Tensor([[0. 1. 0.] [1. 0. 0.] [0. 0. 1.]], shape=(3, 3), dtype=float32)</code></pre><h5 id="使符合概率分布"><a href="#使符合概率分布" class="headerlink" title="使符合概率分布"></a>使符合概率分布</h5><p>归一化处理:softmax()</p><p>让输出的每个分类的概率和为1</p><pre><code class="python">y=tf.constant([1.01,2.01,-0.66])y_pro=tf.nn.softmax(y)print("归一化处理后为:",y_pro)#归一化处理后为: tf.Tensor([0.25598174 0.69583046 0.04818781], shape=(3,), dtype=float32)</code></pre><h5 id="参数自更新"><a href="#参数自更新" class="headerlink" title="参数自更新"></a>参数自更新</h5><p>相当于c语言中的++或者–</p><pre><code class="python">w=tf.Variable(4)#标记为可训练才能更新w.assign_sub(1)print(w)#即w-1</code></pre><h5 id="返回索引"><a href="#返回索引" class="headerlink" title="返回索引"></a>返回索引</h5><p>tf.argmax(张量名,axis=操作轴)</p><pre><code class="python">test=np.array([[1,2,3],[2,3,4],[4,5,3],[8,7,2]])print(test)print(tf.argmax(test,axis=0))#纵向最大值索引print(tf.argmax(test,axis=1))#横向最大值索引#结果如下[[1 2 3] [2 3 4] [4 5 3] [8 7 2]]tf.Tensor([3 3 1], shape=(3,), dtype=int64)tf.Tensor([2 2 1 0], shape=(4,), dtype=int64)</code></pre><h3 id="鸢尾花数据集读入"><a href="#鸢尾花数据集读入" class="headerlink" title="鸢尾花数据集读入"></a>鸢尾花数据集读入</h3><p>通过sklearn中的dataset数据集引入</p><pre><code class="python">import tensorflow as tffrom sklearn import datasetsimport pandas as pdfrom pandas import DataFramex_data=datasets.load_iris().data#.data 返回鸢尾花的输入特征y_data=datasets.load_iris().target#.target返回鸢尾花的所有标签print("x_data:\n",x_data)print("y_data:\n",y_data)x_data=DataFrame(x_data,columns=["花萼长","花萼宽","花瓣长","花瓣宽"])#把数据变成表格形式,增加可读性pd.set_option('display.unicode.east_asian_width',True)#设置列名对齐print("x_data and index:\n",x_data)x_data['类别']=y_data#给增加一个类别标签print("x_data add a colum:\n",x_data)</code></pre><p>展示如下:</p><pre><code>x_data: [[5.1 3.5 1.4 0.2] [4.9 3. 1.4 0.2] [4.7 3.2 1.3 0.2] [4.6 3.1 1.5 0.2] .......... [6.5 3. 5.2 2. ] [6.2 3.4 5.4 2.3] [5.9 3. 5.1 1.8]]y_data: [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2]x_data and index: 花萼长 花萼宽 花瓣长 花瓣宽0 5.1 3.5 1.4 0.21 4.9 3.0 1.4 0.22 4.7 3.2 1.3 0.23 4.6 3.1 1.5 0.24 5.0 3.6 1.4 0.2.. ... ... ... ...145 6.7 3.0 5.2 2.3146 6.3 2.5 5.0 1.9147 6.5 3.0 5.2 2.0148 6.2 3.4 5.4 2.3149 5.9 3.0 5.1 1.8[150 rows x 4 columns]x_data add a colum: 花萼长 花萼宽 花瓣长 花瓣宽 类别0 5.1 3.5 1.4 0.2 01 4.9 3.0 1.4 0.2 02 4.7 3.2 1.3 0.2 03 4.6 3.1 1.5 0.2 04 5.0 3.6 1.4 0.2 0.. ... ... ... ... ...145 6.7 3.0 5.2 2.3 2146 6.3 2.5 5.0 1.9 2147 6.5 3.0 5.2 2.0 2148 6.2 3.4 5.4 2.3 2149 5.9 3.0 5.1 1.8 2[150 rows x 5 columns]</code></pre><h3 id="神经网络实现鸢尾花分类"><a href="#神经网络实现鸢尾花分类" class="headerlink" title="神经网络实现鸢尾花分类"></a>神经网络实现鸢尾花分类</h3><ul><li><p>准备数据</p><ul><li>数据集读入</li><li>数据集乱序</li><li>生成测试集和训练集</li><li>标签配对,每次读入一个batch</li></ul></li><li><p>搭建网络</p><ul><li>定义神经网络中所有可训练参数</li></ul></li><li><p>参数优化</p><ul><li>嵌套迭代循环,with结构更新参数,显示当前loss</li></ul></li><li><p>测试效果</p><ul><li>计算当前参数前向传播后的准确率,显示当前acc</li></ul></li><li><p>acc/loss可视化</p><ul><li>matplotlib库使用</li></ul></li></ul><p>以下是训练用代码,只用一层网络进行训练,Mooc的要求是都能把代码背下来</p><pre><code class="python"># -*- coding: UTF-8 -*-# 利用鸢尾花数据集,实现前向传播、反向传播,可视化loss曲线# 导入所需模块import tensorflow as tffrom sklearn import datasetsfrom matplotlib import pyplot as pltimport numpy as np# 导入数据,分别为输入特征和标签x_data = datasets.load_iris().datay_data = datasets.load_iris().target# 随机打乱数据(因为原始数据是顺序的,顺序不打乱会影响准确率)# seed: 随机数种子,是一个整数,当设置之后,每次生成的随机数都一样(为方便教学,以保每位同学结果一致)np.random.seed(116) # 使用相同的seed,保证输入特征和标签一一对应np.random.shuffle(x_data)np.random.seed(116)np.random.shuffle(y_data)tf.random.set_seed(116)# 将打乱后的数据集分割为训练集和测试集,训练集为前120行,测试集为后30行x_train = x_data[:-30]y_train = y_data[:-30]x_test = x_data[-30:]y_test = y_data[-30:]# 转换x的数据类型,否则后面矩阵相乘时会因数据类型不一致报错x_train = tf.cast(x_train, tf.float32)x_test = tf.cast(x_test, tf.float32)# from_tensor_slices函数使输入特征和标签值一一对应。(把数据集分批次,每个批次batch组数据)train_db = tf.data.Dataset.from_tensor_slices((x_train, y_train)).batch(32)test_db = tf.data.Dataset.from_tensor_slices((x_test, y_test)).batch(32)# 生成神经网络的参数,4个输入特征故,输入层为4个输入节点;因为3分类,故输出层为3个神经元# 用tf.Variable()标记参数可训练# 使用seed使每次生成的随机数相同(方便教学,使大家结果都一致,在现实使用时不写seed)w1 = tf.Variable(tf.random.truncated_normal([4, 3], stddev=0.1, seed=1))b1 = tf.Variable(tf.random.truncated_normal([3], stddev=0.1, seed=1))lr = 0.1 # 学习率为0.1train_loss_results = [] # 将每轮的loss记录在此列表中,为后续画loss曲线提供数据test_acc = [] # 将每轮的acc记录在此列表中,为后续画acc曲线提供数据epoch = 500 # 循环500轮loss_all = 0 # 每轮分4个step,loss_all记录四个step生成的4个loss的和# 训练部分for epoch in range(epoch): #数据集级别的循环,每个epoch循环一次数据集 for step, (x_train, y_train) in enumerate(train_db): #batch级别的循环 ,每个step循环一个batch with tf.GradientTape() as tape: # with结构记录梯度信息 y = tf.matmul(x_train, w1) + b1 # 神经网络乘加运算 y = tf.nn.softmax(y) # 使输出y符合概率分布(此操作后与独热码同量级,可相减求loss) y_ = tf.one_hot(y_train, depth=3) # 将标签值转换为独热码格式,方便计算loss和accuracy loss = tf.reduce_mean(tf.square(y_ - y)) # 采用均方误差损失函数mse = mean(sum(y-out)^2) loss_all += loss.numpy() # 将每个step计算出的loss累加,为后续求loss平均值提供数据,这样计算的loss更准确 # 计算loss对各个参数的梯度 grads = tape.gradient(loss, [w1, b1]) # 实现梯度更新 w1 = w1 - lr * w1_grad b = b - lr * b_grad w1.assign_sub(lr * grads[0]) # 参数w1自更新 b1.assign_sub(lr * grads[1]) # 参数b自更新 # 每个epoch,打印loss信息 print("Epoch &#123;&#125;, loss: &#123;&#125;".format(epoch, loss_all/4)) train_loss_results.append(loss_all / 4) # 将4个step的loss求平均记录在此变量中 loss_all = 0 # loss_all归零,为记录下一个epoch的loss做准备 # 测试部分 # total_correct为预测对的样本个数, total_number为测试的总样本数,将这两个变量都初始化为0 total_correct, total_number = 0, 0 for x_test, y_test in test_db: # 使用更新后的参数进行预测 y = tf.matmul(x_test, w1) + b1 y = tf.nn.softmax(y) pred = tf.argmax(y, axis=1) # 返回y中最大值的索引,即预测的分类 # 将pred转换为y_test的数据类型 pred = tf.cast(pred, dtype=y_test.dtype) # 若分类正确,则correct=1,否则为0,将bool型的结果转换为int型 correct = tf.cast(tf.equal(pred, y_test), dtype=tf.int32) # 将每个batch的correct数加起来 correct = tf.reduce_sum(correct) # 将所有batch中的correct数加起来 total_correct += int(correct) # total_number为测试的总样本数,也就是x_test的行数,shape[0]返回变量的行数 total_number += x_test.shape[0] # 总的准确率等于total_correct/total_number acc = total_correct / total_number test_acc.append(acc) print("Test_acc:", acc) print("--------------------------")# 绘制 loss 曲线plt.figure(figsize=(20,8),dpi=120)plt.title('Loss Function Curve') # 图片标题plt.xlabel('Epoch') # x轴变量名称plt.ylabel('Loss') # y轴变量名称plt.plot(train_loss_results, label="$Loss$") # 逐点画出trian_loss_results值并连线,连线图标是Lossplt.legend() # 画出曲线图标plt.show() # 画出图像# 绘制 Accuracy 曲线plt.title('Acc Curve') # 图片标题plt.xlabel('Epoch') # x轴变量名称plt.ylabel('Acc') # y轴变量名称plt.plot(test_acc, label="$Accuracy$") # 逐点画出test_acc值并连线,连线图标是Accuracyplt.legend()plt.show()plt.savefig("./firstNetwork.png")#保存图片</code></pre><h2 id="神经网络优化"><a href="#神经网络优化" class="headerlink" title="神经网络优化"></a>神经网络优化</h2><h3 id="预备知识"><a href="#预备知识" class="headerlink" title="预备知识"></a>预备知识</h3><h4 id="tf-where"><a href="#tf-where" class="headerlink" title="tf.where()"></a>tf.where()</h4><ul><li><p>条件语句真返回A,条件语句假返回B</p></li><li><p>tf.where(条件语句,真返回A,假返回B)</p><pre><code class="python">a=tf.constant([1,2,3,1,1])b=tf.constant([0,1,3,4,5])c=tf.where(tf.greater(a,b), a, b) 若a>b,返 回a对应位置的元素,否则 返回b对应位置的元素print("c:",c) 运行结果:c:tf.Tensor([1 2345], shape=(5,), dtype=int32)</code></pre></li></ul><h4 id="np-random-RandomState-rand"><a href="#np-random-RandomState-rand" class="headerlink" title="np.random.RandomState.rand()"></a>np.random.RandomState.rand()</h4><ul><li>返回一个[0,1)之间的随机数</li><li>np.random.RandomState.rand(维度)<br>维度为空,返回标量</li></ul><pre><code class="python">import numpy as nprdm=np.random.RandomState(seed:1) #seed=常数每次生成随机数相同a=rdm.rand()#返回一个随机标量b=rdm.rand(2,3)#返回维度为2行3列随机数矩阵print("a:",a)print("b:",b)#运行结果:a: 0.417022004702574b: [[7.20324493e-01 1.14374817e-04 3.02332573e-01][1.46755891e-01 9.23385948e-02 1.86260211e-01]]</code></pre><h4 id="np-vstack"><a href="#np-vstack" class="headerlink" title="np.vstack()"></a>np.vstack()</h4><ul><li>将两个数组按垂直方向叠加np.vstack(数组1,数组2)</li></ul><pre><code class="python">import numpy as npa=np.array([1,2,3])b = np.array([4,5,6])C=np.vstack((a,b))np.vstack()print("c:ln",c)运行结果:c: [[1,2,3], [4,5,6]]</code></pre><h4 id="np-mgrid-ravel-np-c"><a href="#np-mgrid-ravel-np-c" class="headerlink" title="np.mgrid[ ] .ravel() np.c_[]"></a>np.mgrid[ ] .ravel() np.c_[]</h4><p>生成网格坐标点</p><ul><li>np.mgrid[起始值:结束值:步长,起始值:结束值:步长,…]</li><li>x.ravel() 将x变为一维数组,“把.前变量拉直”</li><li>np.c [1使返回的间隔数值点配对<br>np.c_[数组1,数组2,….]</li></ul><pre><code class="python">- import numpy as np X, y= np.mgrid[1:3:1,2:4:0.5] grid =np.c_[x.ravel(), y.ravel print("x:",x) print("y:",y) print('grid:\n", grid)</code></pre><h3 id="复杂学习率"><a href="#复杂学习率" class="headerlink" title="复杂学习率"></a>复杂学习率</h3><h4 id="神经网络(NN)复杂度"><a href="#神经网络(NN)复杂度" class="headerlink" title="神经网络(NN)复杂度"></a>神经网络(NN)复杂度</h4><ul><li><p>√NN复杂度:多用NN层数和NN参数的个数表示</p><ul><li><p>空间复杂度:</p><ul><li>√层数=隐藏层的层数+1个输出层左图为2层NN</li><li>√总参数=总w+总b</li></ul></li><li><p>时间复杂度:</p><ul><li>√乘加运算次数</li></ul></li></ul></li></ul><h4 id="学习率"><a href="#学习率" class="headerlink" title="学习率"></a>学习率</h4><p>可以先用较大的学习率,快速得到较优的解,然后逐步减小学习率,使模型后期稳定</p><p>指数衰减学习率=初始学习率*当习率衰减率(当前轮数/多少轮衰减一次)</p><pre><code class="python">epoch=40LR BASE =0.2LR DECAY =0.99LR STEP =1for epoch in range (epoch): lr = LR BASE *LR DECAY **(epoch / LR STEP) with tf.GradientTape()as tape: loss = tf.square(w +1) grads = tape.gradient (loss, w) w.assign sub (lr *grads) print ("After s epoch,w is %f,loss is %f,lr is %f"%(epoch, w.numpy() , loss,lr))</code></pre><h3 id="激活函数"><a href="#激活函数" class="headerlink" title="激活函数"></a>激活函数</h3><h4 id="√优秀的激活函数"><a href="#√优秀的激活函数" class="headerlink" title="√优秀的激活函数:"></a>√优秀的激活函数:</h4><ul><li><p>非线性:激活函数非线性时,多层神经网络可逼近所有函数(只有网络是非线性的时候才不会被单层网络替代)</p></li><li><p>可微性:优化器大多用梯度下降更新参数</p></li><li><p>单调性:当激活函数是单调的,能保证单层网络的损失函数是凸函数(保证单层网络的损失函数是凸函数)</p></li><li><p>近似恒等性:f(x)sx当参数初始化为随机小值时,神经网络更稳定</p></li></ul><h4 id="√激活函数输出值的范围"><a href="#√激活函数输出值的范围" class="headerlink" title="√激活函数输出值的范围:"></a>√激活函数输出值的范围:</h4><ul><li>激活函数输出为有限值时,基于梯度的优化方法更稳定(权重对特征的影响更加显著)</li><li>激活函数输出为无限值时,建议调小学习</li></ul><h4 id="常用激活函数"><a href="#常用激活函数" class="headerlink" title="常用激活函数"></a>常用激活函数</h4><h5 id="sigmoid"><a href="#sigmoid" class="headerlink" title="sigmoid"></a>sigmoid</h5><p>近年来用sigmoid作为激活函数的网络越来越少,因为深层神经网络进行链式求导的时候,需要从输出层到输入层逐层进行链式求导,但是sigmoid函数的导数是0到0.25之间的小数,链式求导需要多层连续相乘,会出现多个0到0.25之间的连续相乘,结果将会趋于0,产生梯度消失,让参数无法继续更新</p><p>我们希望输入每层神经网络的特征是以0为均值的小数,但是sigmoid后的都是正数,收敛变慢,幂运算计算复杂度大训练时间长</p><ul><li>容易造成梯度消失</li><li>输出非0均值,收敛慢</li><li>幂运算复杂,训练时间长</li></ul><h5 id="tanh"><a href="#tanh" class="headerlink" title="tanh"></a>tanh</h5><ul><li>输出0均值</li><li>同样梯度消失</li><li>幂运算复杂,训练时间长</li></ul><h5 id="Relu"><a href="#Relu" class="headerlink" title="Relu"></a>Relu</h5><p>tf.nn.relu(x)</p><p>是个分段函数,</p><p>优点:</p><ul><li>解决了梯度消失问题</li><li>只需判断输入是否大于0,计算速度快</li><li>收敛远远快于前两者</li></ul><p>缺点:</p><ul><li>输出不是0均值,收敛慢</li><li>dead ReIU问题:当激活特征是负数时,某些神经元无法被激活,导致参数无法被更新<ul><li>设置更小学习率</li><li>减少参数分布的巨大变化</li></ul></li></ul><h5 id="Leaky-Relu"><a href="#Leaky-Relu" class="headerlink" title="Leaky Relu"></a>Leaky Relu</h5><p>tf.nn.leaky_relu(x)</p><p>为了解决relu负区间为0引起神经元死亡而设置的,使其负区间斜率不为0,无完全证明标书leaky relu比relu更好</p><p>但一般都用relu</p><h4 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h4><ul><li>首选relu激活函数;</li><li>√学习率设置较小值;</li><li>输入特征标准化,即让输特征满足以0为均值,1为标准差的正态分布;</li><li>初始参数中心化,即让随机生成的参数满足以0为均值,根下输入特征分之2为标准差的正态分布</li></ul><h3 id="损失函数"><a href="#损失函数" class="headerlink" title="损失函数"></a>损失函数</h3><p>损失函数(loss) :预测值(y)与已知答案(y_)的差距</p><p>NN优化目标:loss最小</p><p>主流的损失函数:</p><ul><li><p>mse (Mean Squared Error)</p></li><li><p>自定义</p></li><li><p>ce(Cross Entropy)交叉熵</p></li></ul><h4 id="均方误差mse"><a href="#均方误差mse" class="headerlink" title="均方误差mse:"></a>均方误差mse:</h4><pre><code class="python">loss_mse = tf.reduce_mean(tf.square(y_-y))</code></pre><h4 id="自定义损失函数:"><a href="#自定义损失函数:" class="headerlink" title="自定义损失函数:"></a>自定义损失函数:</h4><p>对不同的损失赋予不同的惩罚</p><pre><code class="python">loss zdy= tf.reduce _sum(where :(tf.greatery,y_b, cOST(y -y_),PROFT(y_-y))</code></pre><h4 id="交叉熵:"><a href="#交叉熵:" class="headerlink" title="交叉熵:"></a>交叉熵:</h4><p>√交叉嫡损失函数CE(Cross Entropy):表征两个概率分布之间的距离</p><p>eg.二分类已知答案y_=(1,0)预测y,=(0.6, 0.4)y2=(0.8, 0.2)哪个更接近标准答案?</p><p>H1((1.0),(0.6,0.4))=-(1<em>ln0.6+O</em>ln0.4)~~(-0.511 +0)=0.511</p><p>H2((1,0).(0.8,0.2))=-(1<em>ln0.8+O</em>ln0.2)~~(-0.223+0)=0.223</p><p>因为H>H,所以y,预测更准</p><pre><code class="python">tf.losses.categorical_crossentropy(y ,y)loss_ce1=tf.losses.categorical_ crossentropy([1,0],[0.6,0.4])loss_ce1=tf.losses.categorical_ crossentropy([1,0],[0.8,0.2])print("loss_ce1:", loss_ce1)print("loss_ce2:", loss_ce2)</code></pre><p>softmax与交叉结合</p><p>√输出先过softmax函数,再计算第y与y_的交叉嫡损失函数。</p><pre><code class="python">tf.nn.softmax_cross_entropy_with_logits(y_,y)Y_= np.array([[1, 0, 0],[0,1,0],[0, 0,1],[1,0,0],[0,1,0]])y = np.array([[12,3,2],[3,10,1],[1,2, 5],[4,6.5,1.2],[3,6, 1]])y_pro= tf.nn.softmax(y)loss_ce1 = tf.losses.categorical_crossentropy(y_,y_pro)loss_ce2 = tf.nn.softmax_cross_entropy_with_logits(y_y)print('分步计算的结果:ln', loss_ce1)print('结合计算的结果:ln', loss_ce2)</code></pre><h3 id="缓解过拟合"><a href="#缓解过拟合" class="headerlink" title="缓解过拟合"></a>缓解过拟合</h3><p>过拟合把数据点记住了,导致模型过度训练,泛化性弱</p><h4 id="欠拟合的解决方法:"><a href="#欠拟合的解决方法:" class="headerlink" title="欠拟合的解决方法:"></a>欠拟合的解决方法:</h4><ul><li>增加输入特征</li><li>增加网络参数</li><li>减少正则化参数</li></ul><h4 id="过拟合的解决方法:"><a href="#过拟合的解决方法:" class="headerlink" title="过拟合的解决方法:"></a>过拟合的解决方法:</h4><ul><li>数据清洗减少噪声</li><li>增大训练集</li><li>采用正则项</li><li>增大正则化参数</li></ul><p>下面详细介绍正则化:</p><p>正则化就是在损失函数中引入模型复杂度指标:,给每个参数w加上权重,抑制训练集中的噪声(一般不正则化b)</p><p>loss = loss(y与y)+ REGULARIZER * loss(w)</p><p>loss(y与y)是模型中所有参数的损失函数<br>超参数REGULARIZER给出参数w在总loss中的比例,即正则化的权重<br>w是需要正则化的参数</p><p>一般:</p><ul><li>L1正则:loss(w)=lwI</li><li>L2正则:loss 2(w)=sum(w^2)</li></ul><p>√正则化的选择:</p><ul><li><p>L1正则化大概率会使很多参数变为零,<br>因此该方法可通过稀疏参数,即减少参数的数量,降低复杂度。</p></li><li><p>L2正则化会使参数很接近零但不为零,<br>因此该方法可通过减小参数<br>值的大小降低复杂度。</p><p>下面是代码:</p><pre><code class="python">with tf.GradientTape() as tape: hl = tf.matmul(x train, wl)+ b1 h1 = tf.nn.relu(hl) y = tf.matmul(h1, w2)+ b2 loss mse = tf.reduce mean (tf.square(y train - y)) loss regularization = [] loss regularization.append (tf.nn.l2_loss(wl)) loss regularization. append (tf.nn. l2_ loss(w2)) loss regularization = tf.reduce sum (loss regularization) loss = loss mse + 0.03 *loss regularizationvariables = [w1,b1, w2,b2]grads = tape. gradient (loss, variables)</code></pre></li></ul>]]></content>
<summary type="html"><h1 id="Tensorflow基础"><a href="#Tensorflow基础" class="headerlink" title="Tensorflow基础"></a>Tensorflow基础</h1><p> TensorFlow是现在比较火爆的一个深度学习的</summary>
<category term="machinlearning" scheme="http://sweetheart.nefu.site/categories/machinlearning/"/>
<category term="DeepLearning" scheme="http://sweetheart.nefu.site/tags/DeepLearning/"/>
</entry>
<entry>
<title>机器学习之sklearn</title>
<link href="http://sweetheart.nefu.site/2020/10/21/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0%E4%B9%8Bsklearn/"/>
<id>http://sweetheart.nefu.site/2020/10/21/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0%E4%B9%8Bsklearn/</id>
<published>2020-10-21T06:59:54.000Z</published>
<updated>2020-10-22T15:56:06.748Z</updated>
<content type="html"><![CDATA[<h1 id="机器学习笔记之sklearn"><a href="#机器学习笔记之sklearn" class="headerlink" title="机器学习笔记之sklearn"></a>机器学习笔记之sklearn</h1><p> sklearn是机器学习中重要的测试数据集来源之一,并且可以提供特征提取以及降维聚类等功能</p><p> 蒟蒻从今天起开始机器学习调库调参的第一步,</p><h3 id="sklearn数据集介绍"><a href="#sklearn数据集介绍" class="headerlink" title="sklearn数据集介绍"></a>sklearn数据集介绍</h3><h3 id="引入:"><a href="#引入:" class="headerlink" title="引入:"></a>引入:</h3><p>数据集的操作有:</p><ul><li>load_*获取自带的较小的数据集</li><li>fetchg_*获取外部的较大的数据集</li></ul><pre><code class="python">import sklearn.datasets from sklearn.datasets import load_iris //导入鸢尾花数据集iris=load_iris()print("鸢尾花的数据集返回值",iris)print("鸢尾花数据的描述",iris["DESCR"])print("鸢尾花数据的特征值",iris.data)print("鸢尾花的目标值",iris.target)print("鸢尾花的特征值名字",iris.data.shape)print("鸢尾花的特征值名字",iris.feture_name)</code></pre><p>sklearn返回值介绍:</p><ul><li>load 和fetch返回的是字典格式<ul><li>data:特征数据集</li><li>target:标签数据</li><li>DESCR:数据描述</li><li>feature_names:特征名字,新闻数据,手写数字,回归数据集没有</li><li>target_name:标签名</li></ul></li></ul><h3 id="数据集划分"><a href="#数据集划分" class="headerlink" title="数据集划分"></a>数据集划分</h3><p>进行机器学习的时候我们要对数据集进行划分,划分成训练集和测试集</p><p> 一般来说,测试集所占比例比较少:</p><ul><li>一般:测试集一般占比20%~30%{sklearn库中划分函数默认25%}</li><li>训练集特征值,测试集特征值,训练集特征值。测试目标集特征值分别是:x_train x_test y_train y_test</li></ul><p>训练集划分api:</p><pre><code class="python">from sklearn.datasets import load_irisfrom sklearn.model_selection import train_test_splitiris=load_iris()print("鸢尾花的数据集返回值", iris)print("鸢尾花数据的描述", iris["DESCR"])print("鸢尾花数据的特征值", iris.data)print("鸢尾花的目标值", iris.target)print("鸢尾花的特征值名字", iris.data.shape)print("鸢尾花的特征值名字", iris.feature_names)x_train,x_test,y_train,y_test=train_test_split(iris.data,iris.target,test_size=0.2,random_state=22)//第一个参数:数据集x的特征值,第二个参数数据集y的特征值,测试集的占比,第三个随机分配时数种子//返回:训练集特征值,测试集特征值,训练集目标值,测试集目标值</code></pre><h3 id="特征提取"><a href="#特征提取" class="headerlink" title="特征提取"></a>特征提取</h3><p>即是对一些非数值的数据,比如对文本语音图像等,将其转换成数值化,便于进行矩阵运算</p><p>特征提取用于降维等等</p><p>特征工程:</p><p>一般用sklearn进行特征提取、</p><p>而用pandas进行数据清洗,数据抽取,等预处理工作</p><ul><li><p>目标</p><ul><li>应用DicVectorizer实现对类别特征进行数值化离散化</li><li>应用CountVectorizer实现对文本特征进行数值化</li><li>应用TfidVectorizer实现对文本特征进行数值化</li></ul></li><li><p>特征提取api</p><pre><code class="python">sklearn.feature_extraction</code></pre></li></ul><h4 id="对字典进行数值化抽取"><a href="#对字典进行数值化抽取" class="headerlink" title="对字典进行数值化抽取"></a>对字典进行数值化抽取</h4><pre><code class="python">from sklearn.feature_extraction import DictVectorizerdef dict_demo(): data = [&#123;'city': 'beijing', 'number': 1&#125;, &#123;'city': 'guangdong', 'number': 4&#125;, &#123;'city': 'shanghai', 'number': 3&#125;] transfer = DictVectorizer() # 实例化转换器 data_new = transfer.fit_transform(data) print("data_new:", data_new) print("data_new的名字:", transfer.feature_names_)#查看矩阵各列代表属性 return Noneif __name__ == "__main__": dict_demo()</code></pre><p>返回的矩阵:</p><pre><code>data_new: (0, 0) 1.0 (0, 3) 1.0 (1, 1) 1.0 (1, 3) 4.0 (2, 2) 1.0 (2, 3) 3.0返回的是一个稀疏矩阵,当把稀疏矩阵转换成矩阵形式的时候,设置稀疏矩阵falsetransfer = DictVectorizer(sparse=False)输出:data_new: [[1. 0. 0. 1.] [0. 1. 0. 4.] [0. 0. 1. 3.]] data_new的名字: ['city=beijing', 'city=guangdong', 'city=shanghai', 'number']</code></pre><h4 id="文本特征提取"><a href="#文本特征提取" class="headerlink" title="文本特征提取"></a>文本特征提取</h4><pre><code class="python">from sklearn.feature_extraction.text import CountVectorizerdef count_demo(): data = ["lfe is short l like python", "life is short ,code more"] transfer = CountVectorizer() data_new = transfer.fit_transform(data) print("data_new:\n", data_new) print("特征名字:\n",transfer.get_feature_names())#调用此方法获取矩阵的值 return Noneif __name__ == "__main__": count_demo()</code></pre><p>同样返回的是一个稀疏矩阵:</p><pre><code class="python">data_new: (0, 2) 1 (0, 1) 1 (0, 7) 1 (0, 4) 1 (0, 6) 1 (1, 1) 1 (1, 7) 1 (1, 3) 1 (1, 0) 1 (1, 5) 1 特征名字: ['code', 'is', 'lfe', 'life', 'like', 'more', 'python', 'short'] #可见过滤了I等低频词汇 #若对中文进行词频抽取,要用空格隔开词语</code></pre><h4 id="中文文本抽取"><a href="#中文文本抽取" class="headerlink" title="中文文本抽取"></a>中文文本抽取</h4><p>from sklearn.feature_extraction.text import CountVectorizer(stop_word=[])</p><p>这里的stop_word是跳过词,抽取时忽略这个词,自然语言处理时用停顿词表进行无关词语忽略</p><p>这里把把is和like作为停顿词</p><pre><code class="python">transfer = CountVectorizer(stop_words=['is', 'like'])</code></pre><p>输出特征名字:<br> [‘code’, ‘lfe’, ‘life’, ‘more’, ‘python’, ‘short’]</p><p>中文文本抽取:</p><p>由于中文文本在CountVectorizer中使用必需分词,所以要调用jieba的分词函数</p><pre><code class="python">import jieba # 对中文文本进行分词处理def cut_word(text): # 中文文本分词函数 text = "".join(list(jieba.cut(text))) # jibe分词函数->转化成;列表—>转化成字符串 return textdef count_Chinese(): data = ["一种还是一种今天很残酷,明天更加残酷,但是对大部分人来说", "进行机器学习的时候我们要对数据集进行划分,划分成训练集和测试集", "一般来说,测试集所占比例比较少", "训练集特征值,测试集特征值,训练集特征值。测试目标集特征值分别是:x_train x_test y_train y_test"] data_new = [] for i in data: data_new.append(cut_word(i)) print(data_new) return Noneif __name__ == "__main__": count_Chinese()</code></pre><p>然后对生成列表进行特征抽取</p><p>然而这样的特征抽取没有突出高频率词汇,所以要对高频率词汇进行提取</p><p>但是有些词比较辣鸡,不该作为信息抽取</p><h4 id="文本特征抽取2"><a href="#文本特征抽取2" class="headerlink" title="文本特征抽取2"></a>文本特征抽取2</h4><p>关键词:在某一个类别的文章中出现次数多,但在其他文章中出现次数少的词汇,标志了一个文本的特征</p><p>Tf-idf文本特征抽取原理即是如此</p><p>tf:词频</p><p>idf:逆向文本频率:</p><p>由文本文件数目除以包含词语的文件的数目,再将得到的商取以10为底的对数</p><p>Tf-idf=tf*idf</p><p>举例:</p><p>语料库:1000文章</p><p>100文章有非常</p><p>10偏有经济</p><p>两篇文章:</p><p> A文章(100词):经济10词</p><p> ‘经济’:</p><p> tf=0.1</p><p> idf=log 10 1000/10=2</p><p> Tf-idf=0.2</p><p> B文章(100词):非常10词</p><p> ‘非常’:</p><p> tf=0.1</p><p> idf=log 10 1000/100=1</p><p> Tf-idf=0.1</p><p>ApI</p><pre><code class="python">from sklearn.feature_extraction.text import TfidfVectorizerdef Tfidf_demo(): data = ["lfe is short l like python", "life is short ,code more"] transfer = TfidfVectorizer(stop_words=['is', 'like']) data_new = transfer.fit_transform(data) print("data_new:\n", data_new) print("特征名字:\n", transfer.get_feature_names()) return None#就实例化的时候改了下转换器的名字if __name__ == "__main__": Tfidf_demo()</code></pre><p>实例化和提取操作类似于CountVectorizer,同样有停顿词功能</p><p>返回:</p><pre><code class="python">data_new: (0, 4) 0.6316672017376245 (0, 5) 0.4494364165239821 (0, 1) 0.6316672017376245 (1, 3) 0.534046329052269 (1, 0) 0.534046329052269 (1, 2) 0.534046329052269 (1, 5) 0.37997836159100784特征名字: ['code', 'lfe', 'life', 'more', 'python', 'short']</code></pre><h3 id="数据预处理"><a href="#数据预处理" class="headerlink" title="数据预处理"></a>数据预处理</h3><h4 id="归一化"><a href="#归一化" class="headerlink" title="归一化"></a>归一化</h4><p>为了使数据更加适合算法模型处理</p><p>归一化就是在将数据处理在一定中范围内</p><p>如果不对数据进行归一化处理,那么数据将会由于某一个特征值过于巨大而导致其他特征值被忽略,(在聚类中的欧式距离计算中尤为明显)</p><p>所以要将几个数据项的值固定在一个统一的范围内:</p><p>数学上叫做无量纲化</p><p>公式</p><pre><code class="python">x'=(x-min)/(max-min)x''=x'*(mx-mi)+mi</code></pre><p>例如有数据[90,60,75]</p><p>对于数据90:</p><p>x’=(90-60)/(90-60)=1</p><p>x”=1*(1)+0=1 #放缩到1-0区间,mx=1,mi=0</p><p>ApI:</p><pre><code class="python">import pandas as pd#调用pandas清洗函数from sklearn.preprocessing import MinMaxScaler#调用归一化函数def minmax(): data=pd.read_csv("titanic/test.csv") data=data.iloc[:6, :2] #截取数据前两列前6行 trans=MinMaxScaler()#实例化转换器 datanew=trans.fit_transform(data) print(datanew) return Noneif __name__ == "__main__": minmax()</code></pre><p>输出:</p><pre><code class="python">[[0. 1. ] [0.2 1. ] [0.4 0. ] [0.6 1. ] [0.8 1. ] [1. 1. ]]</code></pre><p>这样在处理聚类数据的时候可以减少特征值之间的差距</p><h4 id="标准化处理"><a href="#标准化处理" class="headerlink" title="标准化处理"></a>标准化处理</h4><p>当数据中有缺失值和异常值,做归一化处理得到的数据可能会有缺陷,这种方式鲁棒性较差,只适合传统的精确度小的数据处理</p><p>异常值通常是:</p><ul><li>最大值</li><li>最小值</li></ul><p>标准化定义</p><p>对原始数据变换将数据变为均值为0,标准差为1</p><p>公式:</p><p>x’=(x-mean)/std</p><p>std=标准差</p><p>API</p><pre><code class="python">from sklearn.preprocessing import MinMaxScaler,StandardScaler#即在原来归一化基础上实例的时候改了转换器就行def std_demo(): data = pd.read_csv("titanic/test.csv") data = data.iloc[:6, :2] # 截取数据前两列前6行 trans = StandardScaler() # 实例化转换器 datanew = trans.fit_transform(data) print(datanew) return Noneif __name__ == "__main__": std_demo()</code></pre><p>返回:</p><pre><code class="python">[[-1.46385011 0.4472136 ] [-0.87831007 0.4472136 ] [-0.29277002 -2.23606798] [ 0.29277002 0.4472136 ] [ 0.87831007 0.4472136 ] [ 1.46385011 0.4472136 ]]</code></pre><h3 id="降维"><a href="#降维" class="headerlink" title="降维"></a>降维</h3><p>降维是在某些限定的条件,降低随机特征的个数,得到一组不相关主变量的过程</p><p>维数:嵌套层数</p><ul><li>0维:标量</li><li>1维:向量</li><li>2维:矩阵</li></ul><p>降低的对象:二维数组</p><p>此处降维:降低列数</p><ul><li>相关特征:<ul><li>相对湿度与降雨量之间的关系</li><li>等等</li></ul></li></ul><blockquote><p>正是因为在进行训练的时候,我们都是使用特征进行学习的,如果有特征本身存在问题或者特征之间相关性比较强,对于算法学习的预测影响会比较大</p></blockquote><p>降维的两种方法:</p><ul><li>特征选择</li><li>主成分分析</li></ul><p>特征选择:</p><p>数据中包含冗余的或相关变量,希望在原有特征中找出主要特征</p><p>方法:</p><ul><li>filter过滤式<ul><li>方差选择法:低方差特征过滤(说明此属性共有不必要)</li><li>相关系数法:特征与特征之间的相关程度</li></ul></li><li>embeded嵌入式<ul><li>决策树</li><li>正则化</li><li>深度学习</li></ul></li></ul><h4 id="低方差特征过滤"><a href="#低方差特征过滤" class="headerlink" title="低方差特征过滤"></a>低方差特征过滤</h4><p>API</p><pre><code class="python">import pandas as pdfrom sklearn.feature_selection import VarianceThresholddef varianse_demo(): # 过滤低方差 data = pd.read_csv("titanic/test.csv") data = data.iloc[:5, :2] transfer = VarianceThreshold() data = transfer.fit_transform(data) print(data) return Noneif __name__ == "__main__": varianse_demo()</code></pre><h4 id="相关系数"><a href="#相关系数" class="headerlink" title="相关系数"></a>相关系数</h4><p>皮尔森相关系数:</p><p>公式略</p><p>特点:</p><ul><li>当r>0正相关,R<0负相关</li><li>当r=-1or1完全相关,r=0表示毫无关系</li><li>越近于1相关性越强</li><li>0.4<abs(r)<0.7说明有一定相关性</li></ul><p>Api:</p><pre><code class="python">import pandas as pdfrom scipy.stats import pearsonrdef varianse_demo(): # 过滤低方差 data = pd.read_csv("titanic/test.csv") data = data.iloc[:5, :2] r = pearsonr(data["pe_ratio"], data["pb_ratio"]) print(r) return Noneif __name__ == "__main__": varianse_demo()</code></pre><p>如果特征与多个特征之间相关性很高:</p><ul><li><p>选取其中一个</p></li><li><p>加权求和</p></li><li><p>主成分分析</p></li></ul>]]></content>
<summary type="html"><h1 id="机器学习笔记之sklearn"><a href="#机器学习笔记之sklearn" class="headerlink" title="机器学习笔记之sklearn"></a>机器学习笔记之sklearn</h1><p> sklearn是机器学习中重要的测试数据</summary>
<category term="machine learning" scheme="http://sweetheart.nefu.site/categories/machine-learning/"/>
<category term="sklearn" scheme="http://sweetheart.nefu.site/tags/sklearn/"/>
<category term="machine learning" scheme="http://sweetheart.nefu.site/tags/machine-learning/"/>
</entry>
<entry>
<title>pandaa&&numpy学习笔记</title>
<link href="http://sweetheart.nefu.site/2020/10/04/pandas-numpy%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"/>
<id>http://sweetheart.nefu.site/2020/10/04/pandas-numpy%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/</id>
<published>2020-10-04T08:02:15.000Z</published>
<updated>2020-12-31T12:35:01.214Z</updated>
<content type="html"><![CDATA[<h1 id="numpy-matplotlib-pandas以及文件批量操作"><a href="#numpy-matplotlib-pandas以及文件批量操作" class="headerlink" title="numpy,matplotlib,pandas以及文件批量操作"></a>numpy,matplotlib,pandas以及文件批量操作</h1><p>写在前面,由于自己python基础能力有点菜,并且基本上每上手一个框架都需要这四方面的操作以及掌握,所以我决定恶补这方面的不足,故有了这样一篇博客,持续更新中~</p><ul><li>环境:conda,jupyter notebook</li></ul><h2 id="matplotlib"><a href="#matplotlib" class="headerlink" title="matplotlib"></a>matplotlib</h2><p>绘图用库,进行数据可视化,</p><h3 id="练手项目1-初识matplotlib,绘制折线图"><a href="#练手项目1-初识matplotlib,绘制折线图" class="headerlink" title="练手项目1 初识matplotlib,绘制折线图"></a>练手项目1 初识matplotlib,绘制折线图</h3><h4 id="教学部分"><a href="#教学部分" class="headerlink" title="教学部分"></a>教学部分</h4><p>假设一天中每隔两个小时(range(2,26,2))的气温分别是:</p><p>[15,13,14,5,17,20,25,26,27,22,18,15]</p><pre><code class="python">from matplotlib import pyplot as plt#导入pyplot模块x = range(2, 26, 2)#设置x轴的步距以及上下限y = [15, 13, 14, 5, 17, 20, 25, 26, 27, 22, 18, 15]#y轴的数据,和x对应plt.plot(x, y)#执行方法plt.show()#show方法#最后画出一个折线图</code></pre><p>要点:x和y的数据量一定要一一对应,不然会直接报错,要求步长和上下限list的数据大小和y中一样</p><p>但是这样生成的图表示的数据很模糊,没有标注以及并不好看</p><p>目前存在以下几个问题:</p><ul><li>设置图片大小</li><li>保存到本地</li><li>描述信息,比如x轴和y轴表示什么,这个图表示什么</li><li>描述x或者y的刻度的间距</li><li>标记出特殊点的(比如最高以及最低点)</li><li>给图片添加一个水印(防伪)</li></ul><p>设置图片大小/保存图片:</p><pre><code class="python">from matplotlib import pyplot as pltfig = plt.figure(figsize=(20, 8), dpi=80)# figure图形图标的意思,这里指的是我们画的图,通过实例化一个figure并且传递参数,能够在后台自动使用该figure实例# dpi参数,让图片更加清楚x = range(2, 26, 2)y = [15, 13, 14.5, 17, 20, 25, 26, 26, 27, 22, 18, 15]plt.plot(x, y)# 或者这种方法_xtick_labels=[i/2 for i in range(2,50)]# plt.xticks(_xtick_labels)采用传入数组的方法式# plt.yticks(range(min(y),max(y)+1))步距自动为1plt.xticks(range(2, 25)) # 设置x轴显示步距plt.yticks(range(10, 30, 1)) # range,(start ,end,step)plt.savefig("./first.png") # 在本地保存plt.show()</code></pre><h4 id="项目"><a href="#项目" class="headerlink" title="项目"></a>项目</h4><h5 id="内容"><a href="#内容" class="headerlink" title="内容"></a>内容</h5><p>如果a表示10到12点的每一分钟的气温,如何绘制折线观察每分钟的气温变化</p><p> a=[random.randint(20,35) for i in range(120)]</p><pre><code class="python">from matplotlib import pyplot as pltimport random as rd#记得导入随机数库a = [rd.randint(20, 35) for i in range(120)]#设置x,y轴x = range(1, 121)plt.plot(x, a)#实例化图形plt.xticks(range(1, 121))plt.yticks(range(15, 41))#设置xy轴参数plt.show()#显示plt.savefig("./firstproject.png")#保存</code></pre><p>现在这个代码有点问题,问题在于x轴并不能如实反映钟点数,而是10进制</p><h5 id="转化成时间形式"><a href="#转化成时间形式" class="headerlink" title="转化成时间形式"></a>转化成时间形式</h5><p>修改后</p><pre><code class="python">from matplotlib import pyplot as pltimport random as rda = [rd.randint(20, 35) for i in range(120)]x = range(1, 121)plt.figure(figsize=(20,8),dpi=80)#修改长宽比,修改像素 这是决定图片好看与否的一个因素plt.plot(x, a)_x = list(x)[::3] # 修改步长变成3,要修改成列表形式 _xtick_label = ["10:&#123;&#125;".format(i) for i in range(60)]_xtick_label += ["11:&#123;&#125;".format(i) for i in range(60)] # 追加列表尾plt.xticks(_x, _xtick_label[::3],rotation=300) # rotation旋转的度数#前两个参数数量大小应该一样,则不能完全覆盖整个轴#第一个参数:上下限,是个列表,第二个参数吗,同样是个列表,表示参数注释,注释基本上没有中文plt.yticks(range(15, 41))plt.show()plt.savefig("./firstproject.png")</code></pre><h5 id="显示中文以及修改设置"><a href="#显示中文以及修改设置" class="headerlink" title="显示中文以及修改设置"></a>显示中文以及修改设置</h5><p>在pycharm中,ctrol加上鼠标可查看模块源码</p><p>比如修改matplotlib的绘图设置,可以</p><pre><code class="python">import matplotlibmatplotlib.rc</code></pre><p>然后点开源码,进行查看</p><pre><code class="python"> """ Set the current `.rcParams`. *group* is the grouping for the rc, e.g., for ``lines.linewidth`` the group is ``lines``, for ``axes.facecolor``, the group is ``axes``, and so on. Group may also be a list or tuple of group names, e.g., (*xtick*, *ytick*). *kwargs* is a dictionary attribute name/value pairs, e.g.,:: rc('lines', linewidth=2, color='r')可以设置线条样式 sets the current `.rcParams` and is equivalent to:: rcParams['lines.linewidth'] = 2 rcParams['lines.color'] = 'r' The following aliases are available to save typing for interactive users: ===== ================= Alias Property ===== ================= 'lw' 'linewidth' 'ls' 'linestyle' 'c' 'color' 'fc' 'facecolor' 'ec' 'edgecolor' 'mew' 'markeredgewidth' 'aa' 'antialiased' ===== ================= Thus you could abbreviate the above call as:: rc('lines', lw=2, c='r') Note you can use python's kwargs dictionary facility to store dictionaries of default parameters. e.g., you can customize the font rc as follows:: font = &#123;'family' : 'monospace',或者这种字典写法,引入后一一对应 'weight' : 'bold', 'size' : 'larger'&#125; rc('font', **font) # pass in the font dict as kwargs This enables you to easily switch between several configurations. Use ``matplotlib.style.use('default')`` or :func:`~matplotlib.rcdefaults` to restore the default `.rcParams` after changes. Notes ----- Similar functionality is available by using the normal dict interface, i.e. ``rcParams.update(&#123;"lines.linewidth": 2, ...&#125;)`` (but ``rcParams.update`` does not support abbreviations or grouping). """</code></pre><p>则可以</p><pre><code class="python">import matplotlibfont = &#123;'family' : 'monospace' 'weight' : 'bold', 'size' : 'larger'&#125;matplotlib.rc('font', **font)</code></pre><p>或者通过此显示中文</p><pre><code class="python">from matplotlib import font_managermy_font=font_manager.FontProperties(fname="C:\Windows\Fonts\PingFang.ttc")#字体所在地址</code></pre><p>具体中文显示可以见此博客</p><p><a href="https://blog.csdn.net/fengdu78/article/details/111189331?ops_request_misc=%25257B%252522request%25255Fid%252522%25253A%252522160933291616780265368901%252522%25252C%252522scm%252522%25253A%25252220140713.130102334.pc%25255Fall.%252522%25257D&request_id=160933291616780265368901&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_v2~rank_v29-6-111189331.pc_search_result_cache&utm_term=font_manager.FontProperties">使用matplotlib绘图时中文字体的解决方案</a></p><h5 id="给图添加描述信息"><a href="#给图添加描述信息" class="headerlink" title="给图添加描述信息"></a>给图添加描述信息</h5><pre><code class="python">plt.xlabel("Time")plt.ylabel("temperaturec")#x与y轴分别标注plt.title("10:00-12:00")#给图添加标题</code></pre><p>总结:</p><ul><li><p>学习了怎么绘图:</p><ul><li>from matplotlib import pyplot as plt</li><li>plt.plot(x,y)</li><li>plt.show()</li></ul><p>这三个是绘图的主要流程,即调库,导入数据,显示</p></li><li><p>对图形进行优化</p><ul><li>plt.figure(长宽比,像素)</li><li>_xtick_label实例化一个列表后,作为参数导入plt.xticks()方法,从而对x轴进行优化、</li><li>plt.xlabel()和plt.ylabel()解释参数plt.title()给图片命名</li><li>保存图片plt.savefig()</li><li>字体设置,详见博客</li></ul></li></ul><h4 id="课后作业"><a href="#课后作业" class="headerlink" title="课后作业"></a>课后作业</h4><p><img src="http://pan-yz.chaoxing.com/preview/showpreview_551150525955559424.html?v=1609334127000" alt="课后作业"></p><p>代码如下</p><pre><code class="python">from matplotlib import pyplot as pltx = [i for i in range(11,31)]y = [1, 0, 1, 1, 2, 4, 3, 2, 3, 4, 4, 5, 6, 5, 4, 3, 3, 1, 1, 1]plt.figure(figsize=(20, 8), dpi=80)plt.plot(x, y)plt.xlabel("age")plt.ylabel("the number of girl(boy) friends")plt.title("my plot")_x = list(x)x_label= ["&#123;&#125;year".format(i) for i in range(11,31)]y_label = ["&#123;&#125; boys or girls".format(i) for i in y]plt.xticks(_x,x_label,rotation=300)plt.yticks(range(0,9))#注意名字不能写错,plt.show()</code></pre><h3 id="练手项目2-绘制散点图和折线图"><a href="#练手项目2-绘制散点图和折线图" class="headerlink" title="练手项目2 绘制散点图和折线图"></a>练手项目2 绘制散点图和折线图</h3><h4 id="绘制散点图"><a href="#绘制散点图" class="headerlink" title="绘制散点图"></a>绘制散点图</h4><p>假设通过爬虫你获取到了北京2016年3,10月份每天白天的最高气温(分别位于列表a,b),那么此时如何寻找出气温和随时间(天)变化的某种规律?</p><p>a =[11,17,16,11,12,11,12,6,6,7,8,9,12,15,14,17,18,21,16,17,20,14,15,15,15,19,21,22,22,22,23]</p><p>b =[26,26,28,19,21,17,16,19,18,20,20,19,22,23,17,20,21,20,22,15,11,15,5,13,17,10,11,13,12,13,6]</p><p>三月单独绘制代码如下:</p><pre><code class="python">from matplotlib import pyplot as pltfrom matplotlib import font_managery_3 = [11, 17, 16, 11, 12, 11, 12, 6, 6, 7, 8, 9, 12, 15, 14, 17, 18, 21, 16, 17, 20, 14, 15, 15, 15, 19, 21, 22, 22, 22, 23]y_10 = [26, 26, 28, 19, 21, 17, 16, 19, 18, 20, 20, 19, 22, 23, 17, 20, 21, 20, 22, 15, 11, 15, 5, 13, 17, 10, 11, 13, 12, 13, 6]x=range(1,32)plt.scatter(x,y_3)plt.show()</code></pre><p>但是这时并没有达到我们想要的结果,我们想要绘制一个三月十月同时存在的图,并且有完整图例</p><pre><code class="python">from matplotlib import pyplot as pltfrom matplotlib import font_managermyfont=font_manager.FontProperties(fname="C:\Windows\Fonts\STKAITI.TTF")y_3 = [11, 17, 16, 11, 12, 11, 12, 6, 6, 7, 8, 9, 12, 15, 14, 17, 18, 21, 16, 17, 20, 14, 15, 15, 15, 19, 21, 22, 22, 22, 23]y_10 = [26, 26, 28, 19, 21, 17, 16, 19, 18, 20, 20, 19, 22, 23, 17, 20, 21, 20, 22, 15, 11, 15, 5, 13, 17, 10, 11, 13, 12, 13, 6]x_3 = range(1, 32)x_10 = range(51, 82)plt.figure(figsize=(20, 8), dpi=120)#与绘制折线图唯一的区别plt.scatter(x_3, y_3,label="三月份")plt.scatter(x_10, y_10,label="十月份")_x = list(x_3) + list(x_10)_xticks_labels = ["三月&#123;&#125;日".format(i) for i in x_3]_xticks_labels += ["十月&#123;&#125;日".format(i - 50) for i in x_10]plt.legend(loc="upper left",prop=myfont)#添加图例plt.xticks(_x[::3], _xticks_labels[::3],fontProperties=myfont, rotation=300)plt.ylabel("气温C",fontProperties=myfont)plt.title("气温对照表",fontProperties=myfont)plt.show()</code></pre><p>之后会利用散点图绘制线性回归的拟合曲线</p><h4 id="绘制条形图"><a href="#绘制条形图" class="headerlink" title="绘制条形图"></a>绘制条形图</h4><p>a =[“战狼2”,”速度与激情8” “功夫瑜伽”∵”西游伏妖篇”,”变形金刚5∶最后的骑士”,”摔跤吧!爸爸” ,”加勒比海盗5∶死无对证”,”金刚:骷髅岛”,”极限特工:终极回归”,”生化危机6:终章”, “乘风破浪”∵”神偷奶爸3”,”智取威虎山”;”大闹天竺”,”金刚狼3∶殊死一战” ,”蜘蛛侠:英雄归来”,”悟空传”,”银河护卫队2”,”情圣”,”新木乃伊”,]</p><p>b=[56.01,26.94,17.53,16.49,15.45,12.96,11.8,11.61,11.28,11.12,10.49,10.3,8.75,7.55,7.32,6.99,6.88,6.86,6.58,6.23]单位:亿</p><p>代码如下</p><pre><code class="python">from matplotlib import pyplot as pltfrom matplotlib import font_managermyfont=font_manager.FontProperties(fname="C:\Windows\Fonts\STKAITI.TTF")a = ["战狼2","速度与激情8", "功夫瑜伽","西游伏妖篇","变形金刚5∶最后的骑士","摔跤吧!爸爸" ]b = [56.01,26.94,17.53,16.49,15.45,12.96]plt.figure(figsize=(20, 8), dpi=120)#与绘制折线图唯一的区别plt.bar(range(len(a)),b,width=0.3)plt.xticks(range(len(a)),a,fontProperties=myfont, rotation=300)plt.show()</code></pre><p>截断了前6个</p><p>但是我们更加希望是变成竖着的条形图,那么就改成barh,于是代码如下</p><pre><code class="python">from matplotlib import pyplot as pltfrom matplotlib import font_managermyfont=font_manager.FontProperties(fname="C:\Windows\Fonts\STKAITI.TTF")a = ["战狼2","速度与激情8", "功夫瑜伽","西游伏妖篇","变形金刚5∶最后的骑士","摔跤吧!爸爸" ]b = [56.01,26.94,17.53,16.49,15.45,12.96]plt.figure(figsize=(20, 8), dpi=120)#与绘制折线图唯一的区别plt.barh(range(len(a)),b,height=0.3,color="red")#改成竖图后,wight应该改成hightplt.yticks(range(len(a)),a,fontProperties=myfont)plt.grid(alpha=0.3)#设置网格plt.show()</code></pre><h4 id="课后练习"><a href="#课后练习" class="headerlink" title="课后练习"></a>课后练习</h4><p>假设你知道了列表a中电影分别在2017-09-14(b_ 14), 2017-09 -15(b _15),2017-09-16(b _16)三天的票房,为了展示列表中电影本身的票房以及同其他假设你知道了列表a中电影分别在2017-09- -14(b14), 2017-09 -15(b15),<br>2017-09- 16(b16)三天的票房,为了展示列表中电影本身的票房以及同其他电影的数据对比情况,应该如何更加直观的呈现该数据?<br>a= [“猩球崛起3:终极之战”,”敦刻尔克”,”蜘蛛侠:英雄归来”,”战狼2”]<br>b16 = [15746,312,4497,319]<br>b15 = [12357,156,2045,168]<br>b14 = [2358,399,2358,362]</p><p>代码如下</p><pre><code class="python">from matplotlib import pyplot as pltfrom matplotlib import font_managermyfont=font_manager.FontProperties(fname="C:\Windows\Fonts\STKAITI.TTF")a= ["猩球崛起3:终极之战","敦刻尔克","蜘蛛侠:英雄归来","战狼2"]b16 = [15746,312,4497,319]b15 = [12357,156,2045,168]b14 = [2358,399,2358,362]plt.figure(figsize=(20, 8), dpi=120)#与绘制折线图唯一的区别x_14=list(range(len(a)))x_15=[i+0.2 for i in x_14]x_16=[i+0.4 for i in x_14]plt.bar(range(len(a)),b14,width=0.2,color="red",label="九月14")plt.bar(x_15,b15,width=0.2,color="orange",label="九月15")plt.bar(x_16,b16,width=0.2,color="blue",label="九月16")#改成竖图后,wight应该改成hightplt.legend(prop=myfont)plt.xticks(range(len(a)),a,fontProperties=myfont)plt.grid(alpha=0.3)#设置网格plt.show()</code></pre><p>暂时的matplotlib到这,更多用法查询csdn</p><h4 id="其他绘图工具推荐"><a href="#其他绘图工具推荐" class="headerlink" title="其他绘图工具推荐"></a>其他绘图工具推荐</h4><p>echart:一个前端js框架</p><p>plotly:一个github上的项目,比matplotlib好看</p><h2 id="numpy"><a href="#numpy" class="headerlink" title="numpy"></a>numpy</h2><h3 id="创建numpy数组"><a href="#创建numpy数组" class="headerlink" title="创建numpy数组"></a>创建numpy数组</h3><pre><code class="python">import numpy as npt1=np.array([1,2,3])print(t1)print(type(t1))#[1 2 3]#<class 'numpy.ndarray'>t2 = np.array(range(10))print(t2)t3 = np.arange(10)print(t3)#效果一样#[0 1 2 3 4 5 6 7 8 9]print(t3.dtype)#int32t3.dtype=floatprint(t3.dtype)#float64t4=np.array([rd.random() for i in range(10)])print(t4)print(t4.dtype)#[0.06217892 0.51319594 0.84344407 0.14711661 0.03576193 0.48263391#0.79937126 0.49026005 0.43495258 0.8738894 ]#float64print(np.round(t4,2))print(t4.dtype)#取两位#[0.99 0.76 0.46 0.78 0.32 0.33 0. 0.56 0.89 0.66]#float64</code></pre><h3 id="numpy数组操作"><a href="#numpy数组操作" class="headerlink" title="numpy数组操作"></a>numpy数组操作</h3><h4 id="改变形状"><a href="#改变形状" class="headerlink" title="改变形状"></a>改变形状</h4><pre><code class="python">import numpy as npimport random as rdt1=np.arange(12)print(t1.shape)t2=np.array([[1,2,3],[3,4,5]])print(t2.shape)#查看形状#修改形状t3=np.arange(12)t4=t3.reshape((3,4))print(t4)#改变形状,注意这里改变形状不对原数组进行改变,原地操作</code></pre><p>注意这里的shape</p><p>(24,)与(24,1)是不一样的,前者的1个24行向量,后者是24个1列向量</p><p>以下是操作:</p><ul><li>t.shape[0] t.shape[1]分别是行数和列数</li><li>t.flatten()数组降维一维</li></ul><h4 id="计算"><a href="#计算" class="headerlink" title="计算"></a>计算</h4><p>nan:不是一个数字</p><p>INF:无穷</p><ul><li>点加减: t1+2</li><li>点乘除:t1*2</li><li>矩阵相加减:t1+t2(若不符合矩阵运算,某一维度相同时可以计算,效果类似点加减,广播原则)</li><li>矩阵相乘除:t1*t2(以上要符合矩阵运算规律)</li></ul><p>具体查csdn</p><h3 id="numpy读取文件"><a href="#numpy读取文件" class="headerlink" title="numpy读取文件"></a>numpy读取文件</h3><p>现在这里有一个英国和美国各自youtube1000多个视频的点击,喜欢,不喜欢,评论数量([“views”,”likes” , “dislikes”,” comment total”])的csv,运用刚刚所学习的只是,我们尝试来对其进行操作</p><p><a href="https://www.kaggle.com/datasnaek/youtube/data">数据来源</a></p><h3 id="切片索引操作"><a href="#切片索引操作" class="headerlink" title="切片索引操作"></a>切片索引操作</h3><p>见blog</p><p><a href="https://blog.csdn.net/liujian20150808/article/details/81273289?ops_request_misc=%25257B%252522request%25255Fid%252522%25253A%252522160941748916780299054215%252522%25252C%252522scm%252522%25253A%25252220140713.130102334.pc%25255Fall.%252522%25257D&request_id=160941748916780299054215&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_v2~rank_v29-2-81273289.pc_search_result_cache&utm_term=numpy%E5%88%87%E7%89%87%E6%93%8D%E4%BD%9C">numpy切片索引操作</a></p><p>或者bilibili视频</p><h3 id="数据拼接"><a href="#数据拼接" class="headerlink" title="数据拼接"></a>数据拼接</h3><p><a href="https://blog.csdn.net/qq_39516859/article/details/80666070?ops_request_misc=%25257B%252522request%25255Fid%252522%25253A%252522160941769016780277095641%252522%25252C%252522scm%252522%25253A%25252220140713.130102334.pc%25255Fall.%252522%25257D&request_id=160941769016780277095641&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_v2~rank_v29-2-80666070.pc_search_result_cache&utm_term=numpy%E6%95%B0%E6%8D%AE%E6%8B%BC%E6%8E%A5">数组拼接</a></p><h3 id="好的参考blog"><a href="#好的参考blog" class="headerlink" title="好的参考blog"></a>好的参考blog</h3><p><a href="https://blog.csdn.net/weixin_45651336/article/details/111408557?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_utm_term-2&spm=1001.2101.3001.4242">blog1</a></p><p><a href="https://blog.csdn.net/a373595475/article/details/79580734?ops_request_misc=%25257B%252522request%25255Fid%252522%25253A%252522160941798816780310237261%252522%25252C%252522scm%252522%25253A%25252220140713.130102334.pc%25255Fblog.%252522%25257D&request_id=160941798816780310237261&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_v1~hot_rank-1-79580734.pc_v1_rank_blog_v1&utm_term=numpy%E6%93%8D%E4%BD%9C">blog2</a></p><h3 id="小练习"><a href="#小练习" class="headerlink" title="小练习"></a>小练习</h3>]]></content>
<summary type="html"><h1 id="numpy-matplotlib-pandas以及文件批量操作"><a href="#numpy-matplotlib-pandas以及文件批量操作" class="headerlink" title="numpy,matplotlib,pandas以及文件批量操</summary>
<category term="machine learning" scheme="http://sweetheart.nefu.site/categories/machine-learning/"/>
<category term="machine learning" scheme="http://sweetheart.nefu.site/tags/machine-learning/"/>
<category term="numpy" scheme="http://sweetheart.nefu.site/tags/numpy/"/>
<category term="pandas" scheme="http://sweetheart.nefu.site/tags/pandas/"/>
<category term="matplotlib" scheme="http://sweetheart.nefu.site/tags/matplotlib/"/>
<category term="文件批量操作" scheme="http://sweetheart.nefu.site/tags/%E6%96%87%E4%BB%B6%E6%89%B9%E9%87%8F%E6%93%8D%E4%BD%9C/"/>
</entry>
<entry>
<title>matlab基础使用(更新中)</title>
<link href="http://sweetheart.nefu.site/2020/08/15/matlab%E5%9F%BA%E7%A1%80%E4%BD%BF%E7%94%A8/"/>
<id>http://sweetheart.nefu.site/2020/08/15/matlab%E5%9F%BA%E7%A1%80%E4%BD%BF%E7%94%A8/</id>
<published>2020-08-15T14:01:13.000Z</published>
<updated>2021-03-14T10:07:45.340Z</updated>
<content type="html"><![CDATA[<h1 id="Matlab基础使用"><a href="#Matlab基础使用" class="headerlink" title="Matlab基础使用"></a>Matlab基础使用</h1><h2 id="写在前面"><a href="#写在前面" class="headerlink" title="写在前面"></a>写在前面</h2><p>和之前那篇不同的是,这篇文章记录了matlab基础使用的方法,总共也就那么几个部分</p><ul><li>向量运算</li><li>多项式运算</li><li>矩阵运算</li><li>符号运算</li><li>数列求和与函数极限与导数操作</li><li>函数积分</li><li>方程求解</li><li>微分方程//曲线方程</li><li>拟合插值(这个我更倾向于excel)</li><li>程序设计</li><li>二维绘图</li><li>三维绘图</li></ul><p>大概基础就这么多了,之前知识都是散的于是来个汇总。真·边复习高数线代边用matlab解高数线代题。</p><h2 id="向量操作"><a href="#向量操作" class="headerlink" title="向量操作"></a>向量操作</h2><p>向量:行矩阵列矩阵,秩数为1</p><h3 id="向量创建"><a href="#向量创建" class="headerlink" title="向量创建"></a>向量创建</h3><ul><li>直接创建:a=[1,2,3,4]</li><li>步距创建:a=1:4</li><li>函数生成:a=linspace(0,10,6),从0到10共六个数的向量,自动求步距</li><li>对数分割:a=logspace(1,3,3),表示三个数,10的1次到10的3次</li></ul><h4 id="向量运算"><a href="#向量运算" class="headerlink" title="向量运算"></a>向量运算</h4><pre><code>- 加法- 减法- 数乘- 求内积:dot(a,b)- 求外积:cross(a,b)- 混合积:dot(a,cross(b,c))</code></pre><h2 id="特殊变量"><a href="#特殊变量" class="headerlink" title="特殊变量"></a>特殊变量</h2><h3 id="单元型变量"><a href="#单元型变量" class="headerlink" title="单元型变量"></a>单元型变量</h3><ul><li>类似于结构体</li><li>cell来表示,排列方式又类似于矩阵</li></ul><h3 id="结构体变量"><a href="#结构体变量" class="headerlink" title="结构体变量"></a>结构体变量</h3><ul><li>struct创建</li><li>要求键值对对应:struct(‘a’,{A});</li></ul><h2 id="多项式操作"><a href="#多项式操作" class="headerlink" title="多项式操作"></a>多项式操作</h2><h4 id="多项式创建"><a href="#多项式创建" class="headerlink" title="多项式创建"></a>多项式创建</h4><ul><li>直接创建:’ax+bx^n’</li><li>向量加函数创建:ploy2sym(p),p中元素按照顺序分别为n次到0次的系数</li></ul><h4 id="多项式运算"><a href="#多项式运算" class="headerlink" title="多项式运算"></a>多项式运算</h4><ul><li>乘法:conv(a,b),ab分别为向量</li><li>除法:decov(a,b),同上</li></ul><h4 id="多项式求导"><a href="#多项式求导" class="headerlink" title="多项式求导"></a>多项式求导</h4><p> 步骤:</p><pre><code>- 先向量创建成多项式符号函数- 利用polyder()给多项式求导,得出导数的系数向量- 然后在系数向量创建</code></pre><h2 id="矩阵操作"><a href="#矩阵操作" class="headerlink" title="矩阵操作"></a>矩阵操作</h2><p>基础操作:</p><h3 id="矩阵创建:"><a href="#矩阵创建:" class="headerlink" title="矩阵创建:"></a>矩阵创建:</h3><ul><li>rand()</li><li>zeros()</li><li>ones()</li><li>eye()</li></ul><p>主要就是这些</p><h3 id="矩阵运算"><a href="#矩阵运算" class="headerlink" title="矩阵运算"></a>矩阵运算</h3><h4 id="修改"><a href="#修改" class="headerlink" title="修改"></a>修改</h4><ul><li>删除元素:将某一行设置为空列表,例如:a(m;:)=[]</li><li>元素赋值,a(m,n)=b</li><li>组合矩阵</li></ul><h4 id="变维变向抽取"><a href="#变维变向抽取" class="headerlink" title="变维变向抽取"></a>变维变向抽取</h4><ul><li>变维:reshape():根据顺序以列的顺序上下重排元素</li><li>变向:翻转,基本上不用</li><li>抽取元素:<ul><li>diag()</li><li>tril(),下三角</li><li>triu(),上三角</li></ul></li></ul><h3 id="数学运算"><a href="#数学运算" class="headerlink" title="数学运算"></a>数学运算</h3><ul><li>加法</li><li>减法</li><li>数乘</li><li>乘法</li><li>点乘,A.*B</li><li>除法,记得区分左除\和一般除法/(右除)</li><li>幂运算:A^n, A.^n</li><li>求逆:inv(A),pinv(A)</li><li>求秩:rank(A)</li><li>转置:s’</li><li>求行列式det(C)</li></ul><h2 id="符号运算"><a href="#符号运算" class="headerlink" title="符号运算"></a>符号运算</h2><h3 id="符号与数值转换"><a href="#符号与数值转换" class="headerlink" title="符号与数值转换"></a>符号与数值转换</h3><ul><li><p>sym():数值转换成分数</p></li><li><p>eval():分数转化为小数(同时也可以用vpa()对某个表达式求数值解)</p></li><li><p>设置表达式数值精度:digits(D)//d为有效数字个数->vpa(s)或者vpa(s,d)</p></li></ul><h3 id="符号创建"><a href="#符号创建" class="headerlink" title="符号创建"></a>符号创建</h3><ul><li>x=sym(‘x’)创建符号变量</li><li>syms x 进行定义</li><li>矩阵创建sym(‘a’,n);</li></ul><h3 id="数值带入表达式"><a href="#数值带入表达式" class="headerlink" title="数值带入表达式"></a>数值带入表达式</h3><ul><li>sub(f,x,c):f为表达式,x是变量,c是数值</li></ul><h3 id="符号运算-1"><a href="#符号运算-1" class="headerlink" title="符号运算"></a>符号运算</h3><ul><li>因式分解:factor(f):f是表达式,或者用sym()转化的数值,转化为质数乘积表达式</li><li>幂函数展开:expand(f):比如展开x(x+1)</li><li>求通分后的分子分母:[n,m]=numden(F),n是分子,m是分母</li></ul><h2 id="数列求和求积与函数极限与导数操作与级数求和"><a href="#数列求和求积与函数极限与导数操作与级数求和" class="headerlink" title="数列求和求积与函数极限与导数操作与级数求和"></a>数列求和求积与函数极限与导数操作与级数求和</h2><h3 id="数列求和"><a href="#数列求和" class="headerlink" title="数列求和"></a>数列求和</h3><h4 id="sum"><a href="#sum" class="headerlink" title="sum"></a>sum</h4><ul><li>sum(1:n)返回1到n的累加和</li><li>sun(a),a是矩阵,返回各个列的累加和,结果组成行矩阵</li><li>sum(a,1or2),1表示不求和,2表示求和结果等于原来数列的和,若a是矩阵,啧1对列求和2对行求和</li><li>nansum(),忽略累加中的nan</li></ul><h4 id="cumsum"><a href="#cumsum" class="headerlink" title="cumsum"></a>cumsum</h4><ul><li>求该元素前的累积和加上该元素的和</li></ul><h3 id="数列求积-数值求和"><a href="#数列求积-数值求和" class="headerlink" title="数列求积(数值求和)"></a>数列求积(数值求和)</h3><h4 id="prod"><a href="#prod" class="headerlink" title="prod"></a>prod</h4><ul><li>用法同sum,但是是求积</li></ul><h4 id="cumprod"><a href="#cumprod" class="headerlink" title="cumprod"></a>cumprod</h4><ul><li>用法同cumsum,但是求积</li></ul><h3 id="求极限"><a href="#求极限" class="headerlink" title="求极限"></a>求极限</h3><h4 id="limit"><a href="#limit" class="headerlink" title="limit"></a>limit</h4><p>默认求极小值</p><p>使用步骤:</p><p>1.定义变量syms x</p><p>2.带入limit(f,范围),例子:limit((1+1/n)^n,inf)</p><p><strong>多元求极限</strong>:</p><p>syms x y</p><p>f=(exp(x+exp(y))/(cos(x)-sin(y))</p><p>limit(limit(f,x,0),y,0)</p><h3 id="求导"><a href="#求导" class="headerlink" title="求导"></a>求导</h3><h4 id="diff"><a href="#diff" class="headerlink" title="diff"></a>diff</h4><p>diff(f,x,n):求f函数关于x的n阶数导</p><p>diff(f,n):求n阶导数</p><p>可知可以通过这种方式求偏导</p><h3 id="级数求和(符号求和)"><a href="#级数求和(符号求和)" class="headerlink" title="级数求和(符号求和)"></a>级数求和(符号求和)</h3><h4 id="symsum"><a href="#symsum" class="headerlink" title="symsum"></a>symsum</h4><ul><li>symsum(f,x,a,b),f关于x从a到b的所有和</li><li>结果用vpa()转换</li><li>无穷级数symsum(f,0,inf)表示,结果用vpa转换</li></ul><h2 id="函数积分"><a href="#函数积分" class="headerlink" title="函数积分"></a>函数积分</h2><h3 id="定积分和不定积分"><a href="#定积分和不定积分" class="headerlink" title="定积分和不定积分"></a>定积分和不定积分</h3><h4 id="int"><a href="#int" class="headerlink" title="int"></a>int</h4><ul><li>int(f,x,a,b):求f关于x在a到b上的定积分,然后用vpa表示数值</li><li>int(f,x,0,inf):求反常积分</li><li>不定积分就相对于定积分少一个范围参数</li></ul><h3 id="重积分"><a href="#重积分" class="headerlink" title="重积分"></a>重积分</h3><h4 id="dblquad(二重积分求解快捷方式)"><a href="#dblquad(二重积分求解快捷方式)" class="headerlink" title="dblquad(二重积分求解快捷方式)"></a>dblquad(二重积分求解快捷方式)</h4><ul><li><p>dblquad(f,xm,xM,ym,yM)</p><p>或者也可以用int来求解,int()通过调换参数可以实现多元积分</p></li></ul><h3 id="泰勒展开"><a href="#泰勒展开" class="headerlink" title="泰勒展开"></a>泰勒展开</h3><h4 id="taylor"><a href="#taylor" class="headerlink" title="taylor()"></a>taylor()</h4><ul><li>taylor(f,m,a),求f以x0=a,的情况下的m阶泰勒展开,当a舍去的时候,求麦克劳林展开</li><li>taylor(f,’order’,n)求n阶麦克劳林展开</li></ul><h4 id="傅里叶展开"><a href="#傅里叶展开" class="headerlink" title="傅里叶展开"></a>傅里叶展开</h4><h4 id="Fourierzpi"><a href="#Fourierzpi" class="headerlink" title="Fourierzpi()"></a>Fourierzpi()</h4><ul><li>[a0,an,bn]=Fourierzpi(f)直接出表达式</li></ul><h2 id="方程求解"><a href="#方程求解" class="headerlink" title="方程求解"></a>方程求解</h2><h3 id="线性方程求解"><a href="#线性方程求解" class="headerlink" title="线性方程求解"></a>线性方程求解</h3><ul><li><p>除法求解:(当解唯一时)</p><p> X=A\B 注意是左除即左乘上A的逆矩阵</p></li><li><p>求齐次通解:</p><p> 1 判断是否是:唯一解,无穷解,有解</p><p> 2 null函数求通解:X=null(A,’r’),A是齐次方程的系数矩阵,’r’表示有理数形式返回</p></li><li><p>求非齐次通解:</p><p> 1 先用伪逆求特解:x0=pinv(A)*B,不用A满秩</p><p> 2 然后求同届 null(A,’r’);</p></li><li><p>将增广矩阵化为行阶梯型,求行阶梯型矩阵,</p><p> 1x=rref(AB);AB是增广矩阵</p><p> 2解为曾广矩阵最后一列</p></li></ul><h3 id="非线性方程求解"><a href="#非线性方程求解" class="headerlink" title="非线性方程求解"></a>非线性方程求解</h3><ul><li>x=fzero(f,x0)</li></ul><h3 id="非线性方程组求解"><a href="#非线性方程组求解" class="headerlink" title="非线性方程组求解"></a>非线性方程组求解</h3><ul><li>x=fsolve(f,x0)</li></ul><h2 id="微分方程求解"><a href="#微分方程求解" class="headerlink" title="微分方程求解"></a>微分方程求解</h2><ul><li><p>dsolve</p><ul><li><p>示例:</p><p>y=dsolve(‘(Dy)^2-x*Dy+y=0’,’x);</p></li></ul></li></ul><h3 id="微分方程求特解"><a href="#微分方程求特解" class="headerlink" title="微分方程求特解"></a>微分方程求特解</h3><p>示例:y=dsolve(‘(D2y)*x-5Dy=-x^3’,’y(1)=0,y(5)=0’,x)</p><h2 id="线性回归"><a href="#线性回归" class="headerlink" title="线性回归"></a>线性回归</h2><p>建议excel</p><h2 id="曲线拟合"><a href="#曲线拟合" class="headerlink" title="曲线拟合"></a>曲线拟合</h2><h3 id="polyfit"><a href="#polyfit" class="headerlink" title="polyfit"></a>polyfit</h3><p>y=polyfit(x,y,n),用<strong>n阶多项式</strong>来拟合x,y数据</p><p>注意,最后呈现的不是一个曲线形式而是求出一个多项式的系数向量;</p><h3 id="linefit"><a href="#linefit" class="headerlink" title="linefit"></a>linefit</h3><p>顾名思义,直线拟合,基于最小二乘法</p><p>[k,b]=linefit(x,y),求出系数和截距</p><p>然后用y1=polyval([k,b],x);生成多项式函数</p><h2 id="作业1"><a href="#作业1" class="headerlink" title="作业1"></a>作业1</h2><blockquote><p>设A为3行4列的矩阵,B为一个行数大于3的矩阵,写出MATLAB命令。<br>(1)删除A的第1、3两列。<br>(2)删除B的倒数第3行。</p></blockquote><pre><code class="matlab">>> A=zeros(3,4);>> A(:,1)=[];>> A(:,3)=[];>> B=zeros(4,3);>> B(-3,:)=[];位置 1 处的索引无效。数组索引必须为正整数或逻辑值。>> B(end-3,:)=[];</code></pre>]]></content>
<summary type="html"><h1 id="Matlab基础使用"><a href="#Matlab基础使用" class="headerlink" title="Matlab基础使用"></a>Matlab基础使用</h1><h2 id="写在前面"><a href="#写在前面" class="head</summary>
<category term="数学建模" scheme="http://sweetheart.nefu.site/categories/%E6%95%B0%E5%AD%A6%E5%BB%BA%E6%A8%A1/"/>
<category term="matlab" scheme="http://sweetheart.nefu.site/tags/matlab/"/>
</entry>
<entry>
<title>蒟蒻的matlab实战笔记(更新中)</title>
<link href="http://sweetheart.nefu.site/2020/08/15/%E8%92%9F%E8%92%BB%E7%9A%84matlab%E5%AE%9E%E6%88%98%E7%AC%94%E8%AE%B0/"/>
<id>http://sweetheart.nefu.site/2020/08/15/%E8%92%9F%E8%92%BB%E7%9A%84matlab%E5%AE%9E%E6%88%98%E7%AC%94%E8%AE%B0/</id>
<published>2020-08-15T10:05:04.000Z</published>
<updated>2020-08-15T18:09:59.890Z</updated>
<content type="html"><![CDATA[<h1 id="Matlab-实战笔记"><a href="#Matlab-实战笔记" class="headerlink" title="Matlab 实战笔记"></a>Matlab 实战笔记</h1><h2 id="写在前面"><a href="#写在前面" class="headerlink" title="写在前面"></a>写在前面</h2><p>暑假为了参加国赛学习了matlab(白给的可能性比较大毕竟第一次参加比赛还撞上开学考试),看了也快有半月多一点了,之前基本上就是看书,会了点线性规划图论微分方程积分等等,然而实践出真知,具体问题还得具体分析。于是从今天起开始对着那本黄书上的案例(数学建模算法与应用)大致复现一遍,顺便做些课后题目,希望能有所收获(事实证明这玩意突然就实战真的能把人搞自闭,走一步是一步),并且配合excel(用这个画图或者进行曲线拟合)进行。</p><p> 需要:</p><ul><li>Matlab2018b</li><li>《数学建模算法与应用》</li><li>《matlab从入门到精通》</li><li>交流群嫖来的代码</li><li>CSDN解答</li></ul><p> 那么现在就开始叭</p><h2 id="DAY-1-线性规划-整数规划-非线性规划"><a href="#DAY-1-线性规划-整数规划-非线性规划" class="headerlink" title="DAY 1 线性规划/整数规划/非线性规划"></a>DAY 1 线性规划/整数规划/非线性规划</h2><h3 id="线性规划"><a href="#线性规划" class="headerlink" title="线性规划"></a>线性规划</h3><h4 id="linprog函数"><a href="#linprog函数" class="headerlink" title="linprog函数"></a>linprog函数</h4><p>linprog是求解线性规划的重要函数</p><p>求解线性规划的函数:</p><p> <img src="http://pan-yz.chaoxing.com/preview/showpreview_501461499312701440.html?v=1597487340000" alt="求解所用的linprog函数"></p><p>关于lingprog的一些注意事项:</p><ul><li><p>求解结果是线性最小值<strong>当求最大值时一定要把系数为负!!!</strong></p><ul><li><p>f是多元一次线性式的系数(当未知数矩阵是行矩阵,注意是列矩阵)<strong>同时这要求当求max时对应y变为负</strong></p></li><li><p>A是不等式的系数矩阵</p></li><li><p>b是不等式的常数项矩阵</p></li><li><p>要求不等式是小于等于关系<strong>大于等于关系时时对应系数变为负数转换成小于等于</strong>;</p></li><li><p>Aeq和beq是等式约束;</p></li><li><p>lb是各变量下限,要求为列矩阵,ub是上限也是列矩阵;</p></li><li><p>当无某一项约束时,用空矩阵[]代替</p><p>以下为代码案例</p><pre><code>>> clear all>> f=[2;3;1];>> a=[1,4,2;3,2,0];>> a=[-1,-4,-2;-3,-2,0];>> b=[-8;-6];>> [x,y]=linprog(f,a,b,[],[],zeros(3,1));Optimal solution found.//说明运行成功>> x,yx = 2.0000 0 3.0000</code></pre></li></ul></li></ul><p> y =</p><pre><code> 7</code></pre><p> ```</p><h4 id="注意"><a href="#注意" class="headerlink" title="注意"></a>注意</h4><p> 编写函数要:</p><ul><li>文件名要和函数名字一样;</li><li>函数要以end结尾;</li><li>工程文件要和函数文件在同一个文件夹下</li></ul><h3 id="整数规划"><a href="#整数规划" class="headerlink" title="整数规划"></a>整数规划</h3><h4 id="intlinprog"><a href="#intlinprog" class="headerlink" title="intlinprog"></a>intlinprog</h4><p> 这是解整数规划的函数使用方法和linprog一样;</p><p> <img src="http://imageproxy.chaoxing.com/0x0,q15,jpeg,suFgohD7APLCb6Cke59_2e4xL3xgbs2RgrOVhoeo1w18/http://p.ananas.chaoxing.com/star3/origin/ec92e0ecd6278c84a24712d5c0c59365.png" alt="intlinprog"></p><p>不同的是,整数规划多了限制参数;</p><h3 id="非线性整数规划"><a href="#非线性整数规划" class="headerlink" title="非线性整数规划"></a>非线性整数规划</h3><p><img src="http://pan-yz.chaoxing.com/preview/showpreview_501489184993955840.html?v=1597493941000" alt="当你线性规划用多项式的时候"></p><p> 很显然,多了函数入口;</p><p> 使用方法:</p><p> <img src="http://pan-yz.chaoxing.com/preview/showpreview_501490501555433472.html?v=1597494257000" alt="使用示例"></p><p>注意函数名要加单引号;</p><h2 id="day2约束问题-图论"><a href="#day2约束问题-图论" class="headerlink" title="day2约束问题/图论"></a>day2约束问题/图论</h2><p>也就是图论开始,我意识到我作为编程手做的最大也就是嫖到算法和函数后套上模型罢了</p><p>只有离散只考了人均水平的垃圾硬看算法看了半天愣是看不出什么所以然,然而事实证明还是matlab的强大的,有现成的图论工具箱,往上套就可以了。</p><p> </p>]]></content>
<summary type="html"><h1 id="Matlab-实战笔记"><a href="#Matlab-实战笔记" class="headerlink" title="Matlab 实战笔记"></a>Matlab 实战笔记</h1><h2 id="写在前面"><a href="#写在前面" class="</summary>
<category term="数学建模" scheme="http://sweetheart.nefu.site/categories/%E6%95%B0%E5%AD%A6%E5%BB%BA%E6%A8%A1/"/>
<category term="matlab" scheme="http://sweetheart.nefu.site/tags/matlab/"/>
</entry>
<entry>
<title>这是一篇关于创建博客的吐槽(持续更新中)</title>
<link href="http://sweetheart.nefu.site/2020/08/13/something-about-blog/"/>
<id>http://sweetheart.nefu.site/2020/08/13/something-about-blog/</id>
<published>2020-08-13T07:56:42.000Z</published>
<updated>2020-08-25T16:40:06.302Z</updated>
<content type="html"><![CDATA[<h1 id="这是一篇关于创建博客的吐槽"><a href="#这是一篇关于创建博客的吐槽" class="headerlink" title="这是一篇关于创建博客的吐槽"></a>这是一篇关于创建博客的吐槽</h1><p> 搭了自己第一个博客,过程也算顺利,但还是有不少想吐槽的。</p><p> 对了,右下角是音乐设置,嫌吵可以调小或者关掉。</p><h2 id="关于github"><a href="#关于github" class="headerlink" title="关于github"></a>关于github</h2><p> 用github部署的麻烦也不少:</p><h3 id="速度慢"><a href="#速度慢" class="headerlink" title="速度慢"></a>速度慢</h3><p> 首先是速度,真的好慢啊,从第一篇blog上传完成到全部显示出来,隔了很久,毕竟网站架设在国外,个人博客还是建议搭在gitee上。</p><h3 id="域名会被清掉"><a href="#域名会被清掉" class="headerlink" title="域名会被清掉"></a>域名会被清掉</h3><p> 每次我hexo d后,也就是上传一篇文章或者对网站进行改动后重新部署到github上(这个过程也慢),设置的域名都会被清掉,导致访问出现404,需要重新在设置里面输入域名,太繁琐了。</p><p> 如果有好的解决方法欢迎分享鸭</p><h2 id="自己踩过的一些坑"><a href="#自己踩过的一些坑" class="headerlink" title="自己踩过的一些坑"></a>自己踩过的一些坑</h2><h3 id="不要乱改配置文件"><a href="#不要乱改配置文件" class="headerlink" title="不要乱改配置文件"></a>不要乱改配置文件</h3><p> <del>为了追求刺激</del>为了美观实用,把matery的_config.yml文件改得面目全非,结果美观的目的是达到了,但生成的index.html打开是空的,也就是上传的博客文章打开只有空白网页(泪目)。查了下也不是路径的问题,就是不知道乱动了哪里导致生成空白网页(可能是留言板那的设置),估摸着估计是找不到原因了,于是单独重下matery的config.yml文件,然后不乱改了,问题解决。</p><h3 id="部署后404"><a href="#部署后404" class="headerlink" title="部署后404"></a>部署后404</h3><p> 主要原因还是每次更新到github设置的域名都会被清掉,重新设置后就解决了,但是真的好麻烦啊。</p><h3 id="首页图片被覆盖的颜色太浓"><a href="#首页图片被覆盖的颜色太浓" class="headerlink" title="首页图片被覆盖的颜色太浓"></a>首页图片被覆盖的颜色太浓</h3><p> 改matery主题的source文件夹下的matery.css</p><p> 具体是这三个:</p><pre><code class="kotlin"> /* 整体背景颜色,包括导航、移动端的导航、页尾、标签页等的背景颜色. */.bg-color &#123; background-image: linear-gradient(to right, #4cbf30 0%, #0f9d58 100%);&#125;@-webkit-keyframes rainbow &#123; /* 动态切换背景颜色. */&#125;@keyframes rainbow &#123; /* 动态切换背景颜色. */&#125;</code></pre><h3 id="关于markdown笔记无法加载"><a href="#关于markdown笔记无法加载" class="headerlink" title="关于markdown笔记无法加载"></a>关于markdown笔记无法加载</h3><pre><code>title: “something_about_blogdate: 2020-08-13 15:56:42tags: [技术总结, 吐槽, 避雷]categories: 杂谈</code></pre><p>这是这篇文章markdown的设置,注意:</p><ul><li>每个设置之后都与内容有一个空格隔开,不然会报错,</li><li>tag列表里面每个逗号后面都要有空格,不然也会报错</li></ul><h2 id="待实现的功能"><a href="#待实现的功能" class="headerlink" title="待实现的功能"></a>待实现的功能</h2><p>先记下来有时间做下</p><ul><li>首页图片实现轮播</li><li>每个文章的封面都是一样的</li><li>留言板</li><li>字数统计</li></ul><hr><p>大概就这些了</p><h2 id="8月15日更新"><a href="#8月15日更新" class="headerlink" title="8月15日更新"></a>8月15日更新</h2><ul><li><p>通过在sourse文件夹下添加了写入域名的CNAME文件,解决了部署后域名失效的问题</p></li><li><p>通过调整hexo-theme-matery\layout_partial下的bg-cover-content.ejs文件,成功将首页图变成了刷新一次切换一次</p><p>代码如下:</p></li></ul><pre><code><script> // 每天切换 banner 图. Switch banner image every day. var bannerUrl = "<%- theme.jsDelivr.url %><%- url_for('/medias/banner/') %>" + (new Date().getSeconds())%7 + '.jpg'; //把getDay()改成getSecond()并且对7取余数(因为只有七张图片,如果有多张可以对图片数取余) $('.bg-cover').css('background-image', 'url(' + bannerUrl + ')');</script></code></pre><ul><li>添加了点击就推荐奶茶的特效(其实还整了烟花特效但真的太花了还是少点特效好)</li><li>去掉了首页图的滤镜特效,(太难看了www为什么开发者要这么设置,明明审美也不差)</li><li>完善了友链</li><li>超星网盘当图床是真的香啊</li><li>开启了背景动态图</li><li>修改了首页栏的透明度</li><li>去掉了音乐(这玩意太吵了,自己都看不下去了)</li></ul><h2 id="8月25日更新"><a href="#8月25日更新" class="headerlink" title="8月25日更新"></a>8月25日更新</h2><ul><li>实现了留言板功能,然而目前好像不支持markdown格式</li><li>迷上了小林家的龙女仆,修改了首页,(康娜托尔suki!)</li></ul><p> </p>]]></content>
<summary type="html"><h1 id="这是一篇关于创建博客的吐槽"><a href="#这是一篇关于创建博客的吐槽" class="headerlink" title="这是一篇关于创建博客的吐槽"></a>这是一篇关于创建博客的吐槽</h1><p> 搭了自己第一个博客,过程也算顺利,但还是有</summary>
<category term="杂谈" scheme="http://sweetheart.nefu.site/categories/%E6%9D%82%E8%B0%88/"/>
<category term="总结" scheme="http://sweetheart.nefu.site/tags/%E6%80%BB%E7%BB%93/"/>
<category term="避雷" scheme="http://sweetheart.nefu.site/tags/%E9%81%BF%E9%9B%B7/"/>
</entry>
<entry>
<title>我的第一篇blog</title>
<link href="http://sweetheart.nefu.site/2020/08/13/my_first_blog/"/>
<id>http://sweetheart.nefu.site/2020/08/13/my_first_blog/</id>
<published>2020-08-13T03:29:30.000Z</published>
<updated>2020-08-16T18:54:57.907Z</updated>
<content type="html"><![CDATA[<h1 id="我的第一篇blog"><a href="#我的第一篇blog" class="headerlink" title="我的第一篇blog"></a>我的第一篇blog</h1><h2 id="大概是心路历程?"><a href="#大概是心路历程?" class="headerlink" title="大概是心路历程?"></a>大概是心路历程?</h2><p> 大概在期中的时候就想着要不做一个自己的blog叭,里面放些日常,自己画的画,技术总结(或许还有秀恩爱?)然后在B站搜索blog搭建从入门到精通之类的balalabala。emmmmm,白嫖党看见要花钱注册域名买服务器就不想动了,反正也只是想搭着玩没什么大用处,还不如在QQ空间微博CSDN里面BB。后来了解到可以将blog部署在github便有了兴趣,然而由于懒一直没动,下次一定下次一定。</p><p> 恰巧在前几天刷b站正好看见一个搭建的视频(保姆级),挺喜欢这个hexo主题,于是便捣鼓出来了这个基于hexo的matery个人blog。搭建完改了改,换上了自己在推特上收集的各种图片(老二次元了)。域名是ht给的,当然他一开始给的非常屑,不过现在的我很满意。这个主题居然还有打赏的功能,i了i了,但还有一些功能没有实现,比如好友评论,有时间做一下。</p><p> 音乐在右下角,嫌弃吵可以调小点</p><p> 没了没了</p><hr><h2 id="技术支持"><a href="#技术支持" class="headerlink" title="技术支持"></a>技术支持</h2><h3 id="视频和文档"><a href="#视频和文档" class="headerlink" title="视频和文档"></a>视频和文档</h3><p> blog搭建的视频地址:</p><p> <a href="https://www.bilibili.com/video/BV1je41147Ma">bilibili保姆级基于hexo框架的建站视频</a> </p><p> 感谢up的博客提供的支持:</p><p> <a href="https://rika0-0.github.io/">up的技术博客</a></p><h3 id="需要:"><a href="#需要:" class="headerlink" title="需要:"></a>需要:</h3><ul><li><p>一个github账号</p></li><li><p>nodejs环境</p></li><li><p>git环境</p></li><li><p>html css js基础(后期diy需要)</p></li><li><p>markdown语法基础(建议VSCode or Typora编辑器)</p></li><li><p><del>一个提供虐狗域名的npy</del></p></li></ul>]]></content>
<summary type="html"><h1 id="我的第一篇blog"><a href="#我的第一篇blog" class="headerlink" title="我的第一篇blog"></a>我的第一篇blog</h1><h2 id="大概是心路历程?"><a href="#大概是心路历程?" class="</summary>
<category term="web" scheme="http://sweetheart.nefu.site/tags/web/"/>
<category term="html" scheme="http://sweetheart.nefu.site/tags/html/"/>
<category term="css" scheme="http://sweetheart.nefu.site/tags/css/"/>
<category term="markdown" scheme="http://sweetheart.nefu.site/tags/markdown/"/>
</entry>
</feed>