-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcontent.json
1 lines (1 loc) · 255 KB
/
content.json
1
{"meta":{"title":"鑄日","subtitle":"浩蕩長夜 至此而終","description":"计科人笔记","author":"Sunforge","url":"http://blog.sunforge.cn","root":"/"},"pages":[{"title":"关于","date":"2022-10-18T12:44:06.668Z","updated":"2022-10-18T12:44:06.668Z","comments":true,"path":"about/index.html","permalink":"http://blog.sunforge.cn/about/index.html","excerpt":"","text":"# 博客 # 博主"},{"title":"书架","date":"2022-10-18T12:44:06.676Z","updated":"2022-10-18T12:44:06.676Z","comments":true,"path":"books/index.html","permalink":"http://blog.sunforge.cn/books/index.html","excerpt":"","text":"# 书架"},{"title":"友情链接","date":"2022-10-18T12:44:06.676Z","updated":"2022-10-18T12:44:06.676Z","comments":true,"path":"friends/index.html","permalink":"http://blog.sunforge.cn/friends/index.html","excerpt":"","text":"# 本站信息 站名: 鑄日 站长: Sunforge l- site: 鑄日 owner: sunforge url: https://blog.sunforge.cn desc: 浩蕩長夜 至此而終 image: color: \"#0062AD\" 标志: # 申请方法 添加本站后,在本页留言,格式如下 ```yml- site: #网站的名字 owner: #您的名字 url: #您的网址 desc: #简短描述 image: #一张图片 color: #方块颜色```# 小伙伴们 優萌初華 琉璃的医学 & 编程笔记 ReverseSacle-Blog 执着过去的人,无法迈向未来"},{"title":"网址","date":"2022-10-18T12:44:06.676Z","updated":"2022-10-18T12:44:06.676Z","comments":true,"path":"webstack/index.html","permalink":"http://blog.sunforge.cn/webstack/index.html","excerpt":"","text":"# 工具"}],"posts":[{"title":"机器学习:线性回归","slug":"computer-science/machine-learning/linear-regression","date":"2022-10-10T15:20:42.000Z","updated":"2022-10-18T12:44:06.664Z","comments":true,"path":"computer-science/machine-learning/linear-regression/","link":"","permalink":"http://blog.sunforge.cn/computer-science/machine-learning/linear-regression/","excerpt":"","text":"# Linear Regression Overview Regression is a statistical method used in finance, investing, and other disciplines that attempts to determine the strength and character of the relationship between one dependent variable (usually denoted by Y) and a series of other variables (known as independent variables). 回归模型是一种预测性的建模技术。回归模型基于统计方法,尝试研究一个因变量 yyy(目标值)和其他一系列自变量 xxx(预测器)之间关系的强弱与特征。回归广泛应用于金融、投资以及其他相关学科中。 Linear Regression is a machine learning algorithm based on supervised learning. 线性回归是一种有监督的机器学习算法(有监督学习)。 Linear regression performs the task to predict a dependent variable value (yyy) based on a given independent variable (xxx). So, this regression technique finds out a linear relationship between xxx (input) and yyy (output). Hence, the name is Linear Regression. 线性回归基于给定的自变量(输入值) xxx 来预测(输出值) yyy 的值。因此线性回归应当找到 xxx 与 yyy 间的线性关系。 # Assumptions of Linear Regression Before we conduct linear regression, we must first make sure that four assumptions are met: 在使用线性回归的方法前,我们首先给出假设: There should exist a linear relationship between the independent variable (xxx) and dependent variable (yyy). 自变量 xxx 和因变量 yyy 之间,应该存在某种线性关系。 The error terms should be independent, even in time series data. 误差项之间应该是独立的。即使是时间序列的数据,残差之间也相互独立。 The error terms should have constant variance at every level of xxx. This is called homoskedasticity. 不论 x 取值如何,误差项的方差应该是常数。这个性质叫做同方差性。 The error terms of the model should be normally distributed. 这个模型的误差项,应该服从正态分布。 The formula for error terms in linear regression is straightforward: error = observed yyy – predicted yyy 线性回归中误差项的计算公式如下:误差项 = yyy 的观测值(或认为实际值)- yyy 的预测值 If one or more of these assumptions are violated, then the results of our linear regression may be unreliable or even misleading. 如果上述假设不能够全部满足,那么这个回归分析的结果就不可信,甚至有可能产生误导。 If you create a scatter plot of values for xxx and yyy and see that there is not a linear relationship between xxx and yyy, we have the following two choices: 你可以创建一个关于 xxx 和 yyy 的散点图。如果自变量 xxx 和因变量 yyy 之间不存在线性关系,我们可以有以下两种处理办法: Apply a nonlinear transformation to the independent and/or dependent variable. Common examples include taking the log, the square root, or the reciprocal of the independent and/or dependent variable. 对自变量和(或)因变量进行一个非线性变换。通常可以考虑的是取对数,开平方根或者去倒数等等。 Introduce another independent variable to the model. For example, if the plot of xxx vs. yyy has a parabolic shape then it might make sense to add X2X^2X2 as an additional independent variable in the model. 在模型中引入另一个随机变量。例如,如果在散点图中,xxx 与 yyy 呈现一种抛物线形状的关系,那么我们在模型中加入X2X^2X2 这么一个随机变量,就很有可能有奇效。 Ideally, we don’t want there to be a pattern among consecutive errors. For example, errors shouldn’t steadily grow larger as time goes on. 理想情况下,我们不希望连续的误差之间存在关系。比如说,误差项的值不应该随着时间流逝而增大。 If the assumption of independent errors is violated, we can fix it though these methods: 如果误差项的独立性条件没法满足,那么我们可以考虑以下几个方法去改进它: For positive serial correlation, consider adding lags of the dependent and/or independent variable to the model. 如果误差项序列呈正相关性,可以考虑在模型中添加自变量或因变量的滞后变量。 For negative serial correlation, check to make sure that none of your variables are overdifferenced. 如果误差项序列呈负相关性,那么应该确保模型中不存在变量被过度差分。 For seasonal correlation, consider adding seasonal dummy variables to the model. 如果误差项呈现季节性变化,那么应该添加虚拟的季节性变量。 If the varience of the error terms in the linear regression model are nonconstant, the error terms are said to suffer from heteroscedasticity. 如果线性回归模型中的误差项方差不恒定,那么称这些误差项具有异方差性。 You can then create a scatterplot that shows the fitted values of the model and the error terms of those fitted values. his “cone” shape is a classic sign of heteroscedasticity: 我们以拟合值作为横坐标,以对应的误差项的值作为纵坐标,画出散点图。如下图所示的 “锥形” 散点图,就是异方差性的一个典型代表。 How to fix heteroscedasticity? 如何解决异方差性? Transform the dependent variable.One common transformation is to simply take the log of the dependent variable. 转换因变量的形式。一种常用的转换方法是取对数。 Redefine the dependent variable. One common way to redefine the dependent variable is to use a rate, rather than the raw value. 重新定义自变量。常用比例关系来取代绝对数量。 Use weighted regression. This type of regression assigns a weight to each data point based on the variance of its fitted value. 使用加权线性回归。这种回归根据每个数据点的拟合值的方差为其分配权重。 We have to make sure the error terms are normally distributed. 我们应该确保误差项遵循正态分布。 The first method is to use Q-Q plot to check normality. 我们可以画出 Q-Q 图来检验误差项是否遵循正态分布。 The second way to test normality is to use formal statistical tests like Shapiro-Wilk, Kolmogorov-Smironov, Jarque-Barre, or D’Agostino-Pearson. However, these tests are sensitive to large sample sizes – that is, they often conclude that the residuals are not normal when your sample size is large. 我们也可以通过一些统计测试方法,来检验误差项的正态性。但这些方法对样本数量非常敏感,一旦样本数量较大,那么测试的准确性就会越差。 If the assumption of normal distribution is violated, we have two choices: 如果误差项不服从正态分布,那么我们有以下两种应对方式: First, verify that any outliers aren’t having a huge impact on the distribution. If there are outliers present, make sure that they are real values and that they aren’t data entry errors. 首先确保异常值不会对分布产生巨大影响。如果模型中存在异常值,应当保证这些异常值是真实数据,而不是输入错误。 Next, you can apply a nonlinear transformation to the independent and/or dependent variable. Common examples include taking the log, the square root, or the reciprocal of the independent and/or dependent variable. 随后,可以对自变量或因变量进行非线性的变换。常见的变换包括取对数,开平方根,取倒数等等。 # Linear Regression with One Variable # Hypothesis Function y=θ1+θ2xy=\\theta_1+\\theta_2x y=θ1+θ2x While training the model we are given : 我们通过给定的 xxx 和 yyy 来训练模型 x: input training data (univariate – one input variable(parameter)) xxx 是输入的训练数据。(xxx 是单参数,是输入变量) y: labels to data (supervised learning) yyy 是训练数据 xxx 对应的标签(因此属于有监督学习) When training the model – it fits the best line to predict the value of yyy for a given value of xxx. The model gets the best regression fit line by finding the best θ1\\theta_1θ1 and θ2\\theta_2θ2 values. 在模型训练的过程中,我们希望通过寻找 θ1\\theta_1θ1 和 θ2\\theta_2θ2 拟合出一个最佳的线性关系,以给定的 xxx 值来预测变量 yyy 的值。 θ1: intercept θ1\\theta_1θ1 代表截距 θ2: coefficient of x θ2\\theta_2θ2 是 xxx 的系数 Another representation of the linear (affine) hypothesis function is: 线性规划的假说函数还可以表示为: h(⋅;θ):X→Yorh(x;θ)=θ1+θ2xh(\\cdot;\\theta):\\mathscr X\\rightarrow\\mathscr Y {\\rm \\quad or\\quad} h(x;\\theta)=\\theta_1+\\theta_2x h(⋅;θ):X→Yorh(x;θ)=θ1+θ2x where θ=(θ1,θ2)T\\theta = (\\theta_1,\\theta_2)^Tθ=(θ1,θ2)T 其中, θ=(θ1,θ2)T\\theta = (\\theta_1,\\theta_2)^Tθ=(θ1,θ2)T The corresponding hypothesis class can be expressed as: 对应的假说集为: H={θ1+θ2x∣θ1,θ2∈R}\\mathscr H=\\{\\theta_1+\\theta_2x|\\theta_1,\\theta_2\\in\\mathbb R\\} H={θ1+θ2x∣θ1,θ2∈R} How to update θ1\\theta_1θ1 and θ2\\theta_2θ2 values to choose the optimal hhh (to get the best fit line)? 如何通过迭代更新 θ1\\theta_1θ1 和 θ2\\theta_2θ2 的值来选择更优的假说 hhh 以得到更好的拟合曲线? # Loss/Cost Function 损失函数 By achieving the best-fit regression line, the model aims to predict yyy value such that the error difference between predicted value and true value is minimum. 回归模型中,当预测值 predipred_ipredi 与真实值 yiy_iyi 的误差达到最小时,这个回归模型取到了最佳拟合的回归线。 So, it is very important to update the θ1θ_1θ1 and θ2θ_2θ2 values, to reach the best value that minimize the error between predicted yyy value (predpredpred) and true yyy value (yyy). 为了最小化 yyy 的预测值和 yyy 的真实值之间的误差,动态更新 θ1\\theta_1θ1 和 θ2\\theta_2θ2 是十分重要的。 Loss function(JJJ) of Linear Regression is the Mean Squared Error (MSE) between predicted yyy value (predpredpred) and true yyy value (yyy). 线性回归的损失函数是预测值 predipred_ipredi 与真实值 yiy_iyi 的均方误差。 J(h(⋅;θ),D)=12m∑i=1m(predi−yi)2(predi=h(xi;θ))J\\big(h(\\cdot;\\theta),\\mathscr D\\big)=\\frac1{ {\\color{red}2}m}\\sum_{i=1}^m(pred_i-y_i)^2\\quad \\big(pred_i=h(x_i;\\theta)\\big) J(h(⋅;θ),D)=2m1i=1∑m(predi−yi)2(predi=h(xi;θ)) The squaring is necessary to remove any negative signs. It also gives more weight to larger differences. It’s called the mean squared error as you’re finding the average of a set of errors. The lower the MSE, the better the forecast. 我们应该将误差平方,因为平方能够消除正负符号的影响。并且能够给异常值(预测值与真实值偏差较大的情况)较大的权重。我们对误差平方求和,然后取平均数,得到均方误差。均方误差越小,这个线性回归的预测越准。也就是说拟合程度越高。 The MSE effectively panalizes larger errors more severly. 均方误差对于大偏差的惩罚更有效、更严厉。 Most of you must have noticed the red-marked coefficient 12\\frac1221 in the loss function JJJ. It is just for the convenience of derivation and has no effect on the loss function. 上述损失函数中标红的那个系数 12\\frac1221 只是为了方便求导而已,对损失函数没有任何影响。(很多地方并不加这个系数) The hypothesis hhh should minimize the total error J(h(⋅;θ),D)J\\big(h(\\cdot;\\theta),\\mathscr D\\big)J(h(⋅;θ),D) over the training set D\\mathscr DD 假说 hhh 应该使得拟合结果在训练集 D\\mathscr DD 上取到最小的均方误差 J(h(⋅;θ),D)J\\big(h(\\cdot;\\theta),\\mathscr D\\big)J(h(⋅;θ),D) We choose θ=(θ1,θ2)T\\theta=(\\theta_1,\\theta_2)^Tθ=(θ1,θ2)T as the solution of the wighted least-square problem: 我们通过求解下面的加权最小二乘问题,来获得最优参数 θ=(θ1,θ2)T\\theta=(\\theta_1,\\theta_2)^Tθ=(θ1,θ2)T minθJ(θ)=12m∑i=1m(predi−yi)2(predi=h(xi;θ))\\min_\\theta J(\\theta) = \\frac1{2m}\\sum_{i=1}^m(pred_i-y_i)^2\\quad \\big(pred_i=h(x_i;\\theta)\\big) θminJ(θ)=2m1i=1∑m(predi−yi)2(predi=h(xi;θ)) Another commonly used loss function is Root Mean Squared Error (RMSE), because it is measured in the same units as the response variable. 均方根误差是另一个被广泛使用在线性回归中的损失函数。因为它的测量单位与预测值 yyy 相同。 # Linear Regression with Multiple Variable Multiple linear regression (MLR), also known simply as multiple regression, is a statistical technique that uses several explanatory variables to predict the outcome of a response variable. 多元线性回归,也称多元回归。多元回归基于多个自变量去预测因变量的值,是一种统计方法。 # hypothesis function y=θ0+θ1x1+θ2x2+⋯+θnxn+ϵy=\\theta_0+\\theta_1x_1+\\theta_2x_2+\\cdots+\\theta_nx_n+\\epsilon y=θ0+θ1x1+θ2x2+⋯+θnxn+ϵ In this model: 在上述的模型中: yyy is the dependent variable. yyy 是因变量 xix_ixi are the explanatory variables (also independent variables) xix_ixi 是说明变量(自变量) θ0\\theta_0θ0 is yyy - intercept θ0\\theta_0θ0 是 yyy 上的截距 θi\\theta_iθi are the coefficients for each explantory variable. θi\\theta_iθi 是自变量的对应的斜率 ϵ\\epsilonϵ is the model's error term. (also known as the residuals.) ϵ\\epsilonϵ 是模型的误差项(也称为残差) We can also represent the hypothesis function in the following form: 我们可以将假说函数表达成以下的形式: h(x;θ)=θ0+θ1x1+⋯+θnxnh(x;\\theta)=\\theta_0+\\theta_1x_1+\\cdots+\\theta_nx_n h(x;θ)=θ0+θ1x1+⋯+θnxn Example: training set of housing price. We will consider numbers of bedrooms, numbers of floors, age of home, and so on. 例如:假如我们有一个关于房价的训练集。我们通常会关注的指标有:房间数,楼层数,房屋年限等。 Refering to the Muitiply Linear Regression, in our training set: 参考上面的多元线性回归表达式,在我们的训练集中: yyy is the house price yyy 是房价 x1x_1x1 is the number of bedrooms x1x_1x1 是房间数 x2x_2x2 is the number of floor x2x_2x2 是楼层 x3x_3x3 is the age of home x3x_3x3 是房屋年限 For convenience of notation, we define: 为了简化假说函数的表达式,我们定义 x0=1,x=[x0,x1,⋯ ,xn]TX=[x1T,x2T,⋯ ,xmT]Tx_0=1,\\quad {\\rm x}=[x_0,x_1,\\cdots,x_n]^T\\quad {\\rm X}=[{\\rm x}_1^T,{\\rm x}_2^T,\\cdots,{\\rm x}_m^T]^T x0=1,x=[x0,x1,⋯,xn]TX=[x1T,x2T,⋯,xmT]T Then, the hypothesis function can be rewrite as h(x)=θTxh({\\rm x})=\\theta^T{\\rm x}h(x)=θTx 那么,假说函数可以改写成: h(x)=θTh({\\rm x})=\\theta^Th(x)=θT So, the hpyothesis class is: 因此,假说集是: H={h(x)∣θ∈Rn+1}\\mathscr H=\\{h({\\rm x})|\\theta\\in\\mathbb R^{n+1}\\} H={h(x)∣θ∈Rn+1} # Loss/Cost Function 损失函数 the cost function of multiple linear regression is: 多元回归的损失函数是: J(θ)=12∥Xθ−y∥22J(\\theta)=\\frac1{2}\\Vert{\\rm X}\\theta-y\\Vert_2^2 J(θ)=21∥Xθ−y∥22 where θx−y\\theta{\\rm x} - yθx−y is the error term (residential). 其中 θx−y\\theta{\\rm x} - yθx−y 是误差项(残差)。 Gradient of Loss/Cost Function 损失函数的梯度 The gradient of the cost function is: (we prefer this representation) 损失函数的梯度为:(我们一般使用这种表示法) ∇J(θ)=XT(Xθ−y)\\nabla J(\\theta)={\\rm X}^T({\\rm X}\\theta-y) ∇J(θ)=XT(Xθ−y) Another representation of gradient is: 梯度的另一种表示法是: ∇J(θ)=(∂∂θ0J(θ)∂∂θ1J(θ)⋮∂∂θnJ(θ))\\nabla J(\\theta)=\\begin{pmatrix} \\dfrac{\\partial}{\\partial \\theta_0}J(\\theta)\\\\ \\dfrac{\\partial}{\\partial \\theta_1}J(\\theta)\\\\ \\vdots \\\\ \\dfrac{\\partial}{\\partial \\theta_n}J(\\theta)\\\\ \\end{pmatrix} ∇J(θ)=⎝⎜⎜⎜⎜⎜⎜⎜⎜⎜⎛∂θ0∂J(θ)∂θ1∂J(θ)⋮∂θn∂J(θ)⎠⎟⎟⎟⎟⎟⎟⎟⎟⎟⎞ # Gradient Descent Method 梯度下降方法 We find the optimal parameters by Gradient Descent Methods. 我们通常使用梯度下降算法寻找最优参数 # Batch Gradient Descent 批梯度下降方法 We find the optimal parameters by Batch Gradient Descent method. 我们可以通过批梯度下降算法寻找最优参数 Batch Gradient of Multiply Linear Regression can be expressed as: 多元线性回归的批梯度可以表达为: ∇J(θ)=∑i=1m(xiTθ−yi)xi\\nabla J(\\theta)=\\sum\\limits_{i=1}^m({\\rm x}_i^T\\theta-y_i){\\rm x}_i ∇J(θ)=i=1∑m(xiTθ−yi)xi Where, mmm is the number of data. 其中, mmm 是训练样本数。 Update θ\\thetaθ until convergence. (the model finds optimum values for the weights θ\\thetaθ that give a minimum error in a prediction) 不断迭代 θ\\thetaθ 直到 θ\\thetaθ 收敛(经过训练,模型找到了一个能使预测的误差达到最小的权重向量 θ\\thetaθ) θk+1←θk−αk∇J(θk)\\theta^{k+1}\\leftarrow\\theta^k-\\alpha^k\\nabla J(\\theta^k) θk+1←θk−αk∇J(θk) where αk\\alpha^kαk is the step size (learning rate) in kkk-th iteration. 其中,αk\\alpha^kαk 是第 kkk 次迭代中的步长(学习率)。 More specifically, we have: 更具体地说,我们有: \\begin{align*} \\theta^{k+1}_j &= \\theta_j^k-\\alpha^k\\cdot{\\color{red} \\frac{\\partial}{\\partial\\theta^k_j}J(\\theta^k)}\\\\ &= \\theta_j^k-\\alpha^k\\cdot{\\color{red} \\frac{\\partial}{\\partial\\theta^k_j}\\frac12\\left(h(x;\\theta^k)-y\\right)^2}\\\\ &= \\theta_j^k-\\alpha^k\\cdot{\\color{red} 2\\cdot\\frac12\\left(h(x;\\theta^k)-y\\right)\\cdot \\frac{\\partial}{\\partial\\theta^k_j} \\left(h(x;\\theta^k)-y\\right)}\\\\ &= \\theta_j^k-\\alpha^k\\cdot{\\color{red} \\left(h(x;\\theta^k)-y\\right)\\cdot\\frac{\\partial}{\\partial\\theta^k_j} \\left(\\sum_{i=0}^n\\theta^k_ix_i-y\\right)}\\\\ &= \\theta_j^k-\\alpha^k\\cdot{\\color{red} \\left(h(x;\\theta^k)-y\\right)x_j} \\end{align*} The step size (learning rate) decides the magnitude of a change in weights, if it is large then weights will be updated by a large margin and vice versa. So it has to be chosen properly by experimentation and evaluation. 步长(学习率)决定了权重值 θ\\thetaθ 变化的幅度。如果步长很大,那么权重值将会大幅更新。反之亦然。所以,应当反复试验和评估,以正确选择步长(学习率)。 Larger step size (learning rate) will make this algorithm take more time to reach the bottom as it may skip the minimum value at the bottom and move to another side then wriggle back . 较大的步长(学习率)将会使得这个算法更难收敛(更难到达底部最小值)。因为它可能会跳过损失函数底部的最小值并移动到另一侧,然后再往回迭代,直到达到底部。 Local Minima and Global Minima Local minima is a state in a gradient descent where a model considers that it reached the minimum error and stop going further. 局部最小值是梯度下降法中的一种状态,在这种状态下,模型认为它达到了最小误差,并停止继续前进。 Global minima is an actual state where error goes to a minimum and ideally, a model should identify that. 全局最小值是一个实际的状态,在这个状态下,误差会达到最小。理想情况下,模型应该能够识别这个最小值。 However, by using a batch gradient descent we are calculating gradient for all records at once and if the cost function is irregular then we will have one or more local minima and one global minima. 然而,在使用批梯度下降算法分析损失函数时,如果损失函数起伏波动,那么我们很可能会得到多个局部最小值和一个全局最小值。 In that case, a batch gradient descent will take a long time to reach the global minima or may never reach if the learning rate is not suited and an input data is not scaled properly. 这样一来,批梯度下降算法就可能需要很长的时间才能收敛到全局最小值。如果步长(学习率)不合适或者输入数据的比例不合适,也可能永远也无法将损失函数收敛到全局最小值(而只能收敛到局部最小值)。 # Stochastic Gradient Descent 随机梯度下降算法 Algorithm Outline 算法大纲 Initialize random feature weights θ\\thetaθ 随机初始化特征权重 θ\\thetaθ Calculate the gradient for randomly selected records from the training data. To be continued. Stochastic Gradient Descent - Terminologies - Arjun Mota's Blog (arjun-mota.github.io) # Mini-Batch Gradient Descent 小批梯度下降算法 To be continued. Mini-Batch Gradient Descent - Terminologies - Arjun Mota's Blog (arjun-mota.github.io) # Normal Equation 正规方程 Normal Equation is an analytical approach to Linear Regression with a Least Square Cost Function. We can directly find out the value of θ\\thetaθ without using Gradient Descent. 我们通过正规方程,能够直接找到最优参数 θ\\thetaθ 而不必使用梯度下降方法。 Normal Equation method is based on the mathematical concept of Maxima & Minima in which the derivative and partial derivative of any function would be zero at the minima and maxima point. 正规方程法的关键在于:当函数取到最大值或最小值时,函数的导数和偏导数均为零。 So, in Normal Equation method, we get the minimum value of the Cost function by finding its partial derivative w.r.t to each weight and equating it to zero. 因此,在使用正规方程法求解线性规划问题时,我们会令损失函数的偏导为零。 The normal Equation is as follows: 我们给出正规方程如下: θ=(XTX)+XTy\\theta = ({\\rm X}^T {\\rm X})^+{\\rm X}^Ty θ=(XTX)+XTy where (XTX)+({\\rm X}^T{\\rm X})^+(XTX)+ is called the pseudo-inverse of XTX{\\rm X}^T{\\rm X}XTX 其中 (XTX)+({\\rm X}^T{\\rm X})^+(XTX)+ 是矩阵 XTX{\\rm X}^T{\\rm X}XTX 的伪逆矩阵 pseudo-inverse 伪逆矩阵 A+A^+A+ is called the pseudo-inverse of AAA if and only if it satisfies: 矩阵 A+A^+A+ 被称为矩阵 AAA 的伪逆矩阵,当且仅当: AA+A=AA+AA+=A+(AA+)T=AA+(A+A)T=A+A\\begin{aligned} &AA^+A=A& &A^+AA^+=A^+ \\\\ &(AA^+)^T=AA^+& &(A^+A)^T=A^+A \\end{aligned} AA+A=A(AA+)T=AA+A+AA+=A+(A+A)T=A+A Note that, matrix multiplied by its pseudo-inverse doesn't give the identity matrix. 注意,一个矩阵和它的伪逆矩阵相乘,结果不为单位矩阵。 We have A+=A−1A^+=A^{-1}A+=A−1 if and only if the matrix AAA has full rank. 当且仅当矩阵 AAA 满秩时,伪逆矩阵与逆矩阵相等,即 A+=A−1A^+=A^{-1}A+=A−1 。 Methematics Behind The Equation 正规方程背后的数学原理 cost function of Linear Regression: 线性回归的损失函数: J(θ)=12∥Xθ−y∥22=12(Xθ−y)T(Xθ−y)J(\\theta)=\\frac12\\Vert{\\rm X}\\theta-y\\Vert_2^2 = \\frac1{2}({\\rm X}\\theta-y)^T({\\rm X}\\theta-y) J(θ)=21∥Xθ−y∥22=21(Xθ−y)T(Xθ−y) then we have: 我们有: ∂∂θJ(θ)=12∂∂θ(θTXT−yT)(Xθ−y)=12∂∂θ(θTXTXθ−θTXTy−yTXθ+yTy)=XTXθ−XTy\\begin{aligned} \\frac{\\partial}{\\partial\\theta}J(\\theta) &=\\frac12\\frac{\\partial}{\\partial\\theta}(\\theta^T{\\rm X}^T-y^T)({\\rm X}\\theta-y)\\\\ &=\\frac12\\frac{\\partial}{\\partial\\theta}(\\theta^T{\\rm X}^T{\\rm X}\\theta-\\theta^T{\\rm X}^Ty-y^T{\\rm X}\\theta+y^Ty)\\\\ &={\\rm X}^T{\\rm X}\\theta-{\\rm X}^Ty \\end{aligned} ∂θ∂J(θ)=21∂θ∂(θTXT−yT)(Xθ−y)=21∂θ∂(θTXTXθ−θTXTy−yTXθ+yTy)=XTXθ−XTy Let ∂∂θJ(θ)=0\\dfrac{\\partial}{\\partial\\theta}J(\\theta) = 0∂θ∂J(θ)=0, we have θ=(XTX)+XTy\\theta = ({\\rm X}^T {\\rm X})^+{\\rm X}^Tyθ=(XTX)+XTy. 令损失函数的偏导为 0,我们可以计算出 θ\\thetaθ 值 Matrix Derivatives 矩阵求导法则 ∂∂θθTAθ=(A+AT)θ\\frac{\\partial}{\\partial\\theta}\\theta^TA\\theta=(A+A^T)\\theta ∂θ∂θTAθ=(A+AT)θ ∂∂θθTA=A\\frac{\\partial}{\\partial\\theta}\\theta^TA=A ∂θ∂θTA=A ∂∂θAθ=AT\\frac{\\partial}{\\partial\\theta}A\\theta=A^T ∂θ∂Aθ=AT ∂∂θA=0∂∂θθ=I∂∂θθTθ=2θ\\frac{\\partial}{\\partial\\theta}A=0\\qquad \\frac{\\partial}{\\partial\\theta}\\theta=I \\qquad \\frac{\\partial}{\\partial\\theta}\\theta^T\\theta=2\\theta ∂θ∂A=0∂θ∂θ=I∂θ∂θTθ=2θ Intepretaion 说明 Xθ−y{\\rm X}\\theta-yXθ−y is the vector of errors in each example 向量 Xθ−y{\\rm X}\\theta-yXθ−y 代表了每一项训练数据的误差。 X{\\rm X}X are the features we have to work with for each example. 矩阵 X{\\rm X}X 代表我们需要分析的特征。 Inner product = 0, orthogonal 向量内积为 0,两向量垂直 # Maximum Likelihood Estimate 最大似然估计 # References 参考资料 The Four Assumptions of Linear Regression - Statology Q-Q 图和 P-P 图傻傻整不明白?_fff2zrx 的博客 - CSDN 博客_q-q 图 假设检验、显著性水平、P 值、Z 值的理解_longwilll 的博客 - CSDN 博客_z 值怎么看显著性 [ML | Linear Regression - GeeksforGeeks](https://www.geeksforgeeks.org/ml-linear-regression/#:~:text=Linear Regression is a machine learning algorithm based,finding out the relationship between variables and forecasting.) Multiple Linear Regression (MLR) Definition, Formula, and Example (investopedia.com) What Are Residuals? (thoughtco.com) Batch Gradient Descent - Terminologies - Arjun Mota's Blog (arjun-mota.github.io) Stochastic Gradient Descent - Terminologies - Arjun Mota's Blog (arjun-mota.github.io) 详解正规方程(Normal Equation) - 知乎 (zhihu.com) ML | Normal Equation in Linear Regression - GeeksforGeeks Linear regression - Maximum likelihood estimation (statlect.com)","categories":[{"name":"计算机科学","slug":"computer-science","permalink":"http://blog.sunforge.cn/categories/computer-science/"},{"name":"机器学习","slug":"computer-science/机器学习","permalink":"http://blog.sunforge.cn/categories/computer-science/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0/"},{"name":"回归模型","slug":"computer-science/机器学习/回归模型","permalink":"http://blog.sunforge.cn/categories/computer-science/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0/%E5%9B%9E%E5%BD%92%E6%A8%A1%E5%9E%8B/"}],"tags":[{"name":"笔记","slug":"笔记","permalink":"http://blog.sunforge.cn/tags/%E7%AC%94%E8%AE%B0/"}]},{"title":"机器学习:索引","slug":"computer-science/machine-learning/index","date":"2022-10-10T15:08:41.000Z","updated":"2022-10-18T12:44:06.660Z","comments":true,"path":"computer-science/machine-learning/index/","link":"","permalink":"http://blog.sunforge.cn/computer-science/machine-learning/index/","excerpt":"","text":"# [CS 282] Machine Learning @ Shanghai Tech University This set of lecture notes includes not only what the teacher taught, but also some additional information from the Internet.","categories":[{"name":"计算机科学","slug":"computer-science","permalink":"http://blog.sunforge.cn/categories/computer-science/"},{"name":"机器学习","slug":"computer-science/机器学习","permalink":"http://blog.sunforge.cn/categories/computer-science/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0/"}],"tags":[{"name":"索引","slug":"索引","permalink":"http://blog.sunforge.cn/tags/%E7%B4%A2%E5%BC%95/"}]},{"title":"凸优化第二章:凸集","slug":"fundamental/math/convex-optimization/Chapter-2-Convex-sets","date":"2022-10-03T07:05:27.000Z","updated":"2022-10-18T12:44:06.668Z","comments":true,"path":"fundamental/math/convex-optimization/Chapter-2-Convex-sets/","link":"","permalink":"http://blog.sunforge.cn/fundamental/math/convex-optimization/Chapter-2-Convex-sets/","excerpt":"","text":"# Affine and Convex Set 仿射集和凸集 # Line and Line Segments 直线和线段 Suppose x1≠x2x_1\\ne x_2x1=x2 are two points in Rn\\mathbb R^nRn. Points of the form y=θx1+(1−θ)x2,θ∈Ry = \\theta x_1 + (1-\\theta)x_2, \\quad\\theta\\in\\mathbb R y=θx1+(1−θ)x2,θ∈R form the line passing through x1x_1x1 and x2x_2x2. 假设 x1x_1x1 和 x2x_2x2 是 nnn 维空间 Rn\\mathbb R^nRn 中不重合的两个点,当 θ∈R\\theta\\in\\mathbb Rθ∈R 时,空间中符合表达式 y=θx1+(1−θ)x2y = \\theta x_1 + (1-\\theta)x_2y=θx1+(1−θ)x2 的所有点,构成了穿过点 x1x_1x1 和 x2x_2x2 的直线。 The parameter value θ=0\\theta = 0θ=0 corresponds to y=x2y = x_2y=x2, and the parameter value θ=1\\theta = 1θ=1 corresponds to y=x1y = x_1y=x1 . Values of the parameter θ\\thetaθ between 000 and 111 correspond to the (closed) line segment between x1x_1x1 and x2x_2x2 当参数 θ=0\\theta = 0θ=0 时 y=x2y = x_2y=x2 ,当 θ=1\\theta = 1θ=1 时 y=x1y = x_1y=x1 ,当 θ\\thetaθ 在 000 到 111 的范围内变化时,符合表达式 y=θx1+(1−θ)x2y = \\theta x_1 + (1-\\theta)x_2y=θx1+(1−θ)x2 的所有点构成了 x1x_1x1 和 x2x_2x2 之间的(封闭)线段。 Expressing yyy in the form y=x2+θ(x1−x2),θ∈Ry = x_2 + \\theta(x_1 − x_2),\\quad\\theta\\in\\mathbb R y=x2+θ(x1−x2),θ∈R gives another interpretation: yyy is the sum of the base point x2x_2x2 (corresponding to θ=0\\theta = 0θ=0) and the direction x1−x2x_1-x_2x1−x2 (which points from x2x_2x2 to x1x_1x1) scaled by the parameter θ\\thetaθ. 我们对等式做一下变形,可以从另一个角度理解直线。yyy 是基点 x2x_2x2 (对应着 θ=0\\theta = 0θ=0) 和方向 x1−x2x_1-x_2x1−x2 (从 x2x_2x2 指向 x1x_1x1) 乘以参数 θ\\thetaθ 的和。 # Affine Sets 仿射集 A set C⊆RnC \\subseteq\\mathbb R^nC⊆Rn is affine if the line through any two distinct points in CCC lies in CCC, i.e., if for any x1,x2∈Cx_1, x_2 \\in Cx1,x2∈C and θ∈Rθ \\in\\mathbb Rθ∈R, we have θx1+(1−θ)x2∈C\\theta x_1 + (1-\\theta)x_2 \\in Cθx1+(1−θ)x2∈C. In other words, CCC contains the linear combination of any two points in CCC, provided the coefficients in the linear combination sum to one. 如果通过集合 CCC 中的任意两个不同的点,构成的直线仍然在集合 CCC 中,那么这个集合 CCC 是仿射的。也就是说,仿射集对于任意的 x1,x2∈Cx_1, x_2 \\in Cx1,x2∈C 以及 θ∈Rθ \\in\\mathbb Rθ∈R 恒满足 θx1+(1−θ)x2∈C\\theta x_1 + (1-\\theta)x_2 \\in Cθx1+(1−θ)x2∈C。 更进一步,集合 CCC 中包含了集合 CCC 中任意两点系数和为 111 的线性组合。 This idea can be generalized to more than two points. We refer to a point of the form θ1x1 + · · · + θkxk, where θ1 + · · · + θk = 1, as an affine combination of the points x1, . . . , xk. 这个定义可以推广到多个点的情况。如果 θ1+θ2+⋯+θk=1\\theta_1+\\theta_2+\\cdots+\\theta_k =1θ1+θ2+⋯+θk=1 那么我们称 θ1x1+θ2x2+⋯+θkxk\\theta_1x_1+\\theta_2x_2+\\cdots+\\theta_kx_kθ1x1+θ2x2+⋯+θkxk 是 x1,x2,⋯ ,xkx_1,x_2,\\cdots,x_kx1,x2,⋯,xk 的仿射组合 Using induction from the definition of affine set (i.e., that it contains every affine combination of two points in it), it can be shown that an affine set contains every affine combination of its points: If CCC is an affine set, x1,⋯ ,xk∈Cx_1,\\cdots, x_k\\in Cx1,⋯,xk∈C, and θ1+⋯+θk\\theta_1+ \\cdots+\\theta_kθ1+⋯+θk = 1, then the point θ1x1+θ2x2+⋯+θkxk\\theta_1x_1+\\theta_2x_2+\\cdots+\\theta_kx_kθ1x1+θ2x2+⋯+θkxk also belongs to CCC. 根据仿射集的定义(仿射集中任意两点的仿射组合仍然在仿射集中)我们可以归纳出以下结论:一个仿射集合包含其中任意个点的仿射组合。即如果 CCC 是一个仿射集合, x1,⋯ ,xk∈Cx_1,\\cdots, x_k\\in Cx1,⋯,xk∈C 并且 θ1+⋯+θk\\theta_1+ \\cdots+\\theta_kθ1+⋯+θk = 1, 那么 θ1x1+θ2x2+⋯+θkxk\\theta_1x_1+\\theta_2x_2+\\cdots+\\theta_kx_kθ1x1+θ2x2+⋯+θkxk 仍然在 CCC 中. Proof 证明 Suppose that we have three points x1,x2,x3∈Cx_1,x_2,x_3\\in Cx1,x2,x3∈C Since x1,x2∈Cx_1,x_2\\in Cx1,x2∈C, we know that mm+nx1+nm+nx2∈C\\frac{m}{m+n}x_1+\\frac{n}{m+n}x_2\\in Cm+nmx1+m+nnx2∈C Similarly, because x3∈Cx_3\\in Cx3∈C, for any point on the affine combination mm+nx1+nm+nx2∈C\\frac{m}{m+n}x_1+\\frac{n}{m+n}x_2\\in Cm+nmx1+m+nnx2∈C we have such an affine combination: (m+n)(mm+nx1+nm+nx2)+(1−m−n)x3∈C(m+n)\\left(\\frac{m}{m+n}x_1+\\frac{n}{m+n}x_2\\right)+(1-m-n)x_3 \\in C(m+n)(m+nmx1+m+nnx2)+(1−m−n)x3∈C We set θ1\\theta_1θ1 to be mmm, θ2\\theta_2θ2 to be nnn and θ3\\theta_3θ3 to be 1−m−n1-m-n1−m−n, we have θ1x1+θ2x2+θ3x3∈C\\theta_1x_1+\\theta_2x_2+\\theta_3x_3\\in Cθ1x1+θ2x2+θ3x3∈C while θ1+θ2+θ3=1\\theta_1+\\theta_2+\\theta_3=1θ1+θ2+θ3=1 Q.E.D. If CCC is an affine set and ∀x0∈C\\forall x_0\\in C∀x0∈C, then the set 如果 CCC 是一个仿射集,对于任意一个 ∀x0∈C\\forall x_0\\in C∀x0∈C V=C−x0={x−x0∣x∈C}V=C-x_0=\\left\\{x-x_0|x\\in C\\right\\} V=C−x0={x−x0∣x∈C} is a subspace, i.e., closed under sums and scalar multiplication. 集合 VVV 是一个子空间(关于加法和数乘封闭) Proof 证明 Suppose that v1,v2∈Vv_1,v_2\\in Vv1,v2∈V and α,β∈R\\alpha,\\beta\\in \\mathbb Rα,β∈R Then, we have v1+x0∈Cv_1+x_0\\in Cv1+x0∈C and v2+x0∈Cv_2+x_0\\in Cv2+x0∈C. So, αv1+βv2+x0=α(v1+x0)+β(v2+x0)+x0=αv1+βv2+(1−α−β)x0\\alpha v_1+\\beta v_2+x_0=\\alpha(v_1+x_0)+\\beta(v_2+x_0)+x_0=\\alpha v_1+\\beta v_2+(1-\\alpha-\\beta) x_0αv1+βv2+x0=α(v1+x0)+β(v2+x0)+x0=αv1+βv2+(1−α−β)x0 Since, CCC is affine, and α+β+(1−α−β)=1\\alpha+\\beta+(1-\\alpha-\\beta)=1α+β+(1−α−β)=1 We conclude that αv1+βv2∈V\\alpha v_1+\\beta v_2\\in Vαv1+βv2∈V, since αv1+βv2+x0∈C\\alpha v_1+\\beta v_2+x_0\\in Cαv1+βv2+x0∈C Q.E.D. Thus, the affine set C can be expressed as 因此,我们可以将仿射集 CCC 改写成: C=V+x0={v+x0∣v∈V}C=V+x_0=\\left\\{v+x_0|v\\in V\\right\\} C=V+x0={v+x0∣v∈V} i.e., as a subspace plus an offset. 即一个子空间加上一个偏移 The subspace VVV associated with the affine set CCC does not depend on the choice of x0x_0x0, so x0x_0x0 can be chosen as any point in CCC. 与仿射集 CCC 相关联的子空间 VVV 不受 x0x_0x0 的影响。所以 x0x_0x0 可以在仿射集 CCC 中任意选取。 We define the dimension of an affine set CCC as the dimension of the subspace V=C−x0V = C-x_0V=C−x0, where x0x_0x0 is any element of CCC. 仿射集 CCC 的维数 = 子空间 V=C−x0V=C-x_0V=C−x0 的维数,其中 x0x_0x0 是 CCC 中的任意元素。 Example: The solution set of a system of linear equations, C={x∣Ax=b}C = \\left\\{x|Ax = b\\right\\}C={x∣Ax=b}, where A∈Rm×nA\\in\\mathbb R^{m\\times n}A∈Rm×n and b∈Rmb\\in\\mathbb R^mb∈Rm, is an affine set. 实例:线性方程组 C={x∣Ax=b}C = \\left\\{x|Ax = b\\right\\}C={x∣Ax=b} (其中 A∈Rm×nA\\in\\mathbb R^{m\\times n}A∈Rm×n , b∈Rmb\\in\\mathbb R^mb∈Rm )的解集是一个仿射集。 Proof 证明 Suppose x1,x2∈Cx_1, x_2\\in Cx1,x2∈C, i.e., Ax1=b, Ax2=bAx_1=b,~Ax_2=bAx1=b, Ax2=b. Then, for any θ\\thetaθ, we have A(θx1+(1−θ)x2)=θAx1+(1−θ)Ax2=θb+(1−θ)b=b\\begin{aligned} A(\\theta x_1+(1-\\theta)x_2) & = \\theta Ax_1+(1-\\theta)Ax_2\\\\ & = \\theta b+(1-\\theta)b\\\\ & = b \\end{aligned} A(θx1+(1−θ)x2)=θAx1+(1−θ)Ax2=θb+(1−θ)b=b Therefore, the affine combination θx1+(1−θ)x2\\theta x_1+(1-\\theta)x_2θx1+(1−θ)x2 is also in CCC. We can conclude that CCC is an affine set. Q.E.D Notice: the subspace associated with the affine set CCC is the nullspace of AAA. 注意:与仿射集 CCC 相关联的子空间,就是矩阵 AAA 的零空间。 converse: every affine set can be expressed as the solution set of a system of linear equations 线性方程组的解集是一个仿射集。与之相反,任意一个仿射集也可以表示为一个线性方程组的解集。 # Affine Hall, Affine Dimension and Relative Interior 仿射包,仿射维数和相对内部 The set of all affine combinations of points in some set C⊆RnC \\subseteq \\mathbb R^nC⊆Rn is called the affine hull of CCC, and denoted aff C\\bold{aff}~Caff C : 集合 CCC 的仿射包是由集合 C⊆RnC\\subseteq\\mathbb R^nC⊆Rn 中的点的所有仿射组合构成的集合: aff C={θ1x1+⋯+θkxk∣x1,⋯ ,xk∈C, θ1+⋯+θk=1}\\bold{aff}~C = \\{\\theta_1x_1+\\cdots+\\theta_kx_k|x_1,\\cdots,x_k\\in C,~\\theta_1+\\cdots+\\theta_k=1\\} aff C={θ1x1+⋯+θkxk∣x1,⋯,xk∈C, θ1+⋯+θk=1} The affine hull is the smallest affine set that contains CCC, i.e., C⊆aff CC\\subseteq\\bold{aff}~CC⊆aff C 集合 CCC 的仿射包 aff C\\bold{aff}~Caff C 是包含集合 CCC 的最小仿射集,即满足 C⊆aff CC\\subseteq\\bold{aff}~CC⊆aff C 。 Proof 证明 Suppose that there exists an affine set SSS smaller than aff C\\bold{aff}~Caff C, s.t., C⊆S⊆aff CC\\subseteq S\\subseteq\\bold{aff}~CC⊆S⊆aff C. Since the affine set SSS is an smaller affine set, there must be at least one element ppp in affine hull aff C\\bold{aff}~Caff C but not in affine set SSS We set p=θp1x1+⋯+θpkxkp=\\theta_{p1}x_1+\\cdots+\\theta_{pk}x_kp=θp1x1+⋯+θpkxk where θp1+θp2+⋯+θpk=1\\theta_{p1}+\\theta{p2}+\\cdots+\\theta_{pk} = 1θp1+θp2+⋯+θpk=1 However, because x1,⋯ ,xn∈Sx_1,\\cdots,x_n\\in Sx1,⋯,xn∈S , we have p∈Sp\\in Sp∈S which leads to contradiction. So, the affine hull aff C\\bold{aff}~Caff C is the smallest affine set that contains CCC Q.E.D. if SSS is any affine set with C⊆SC\\subseteq SC⊆S, then aff C⊆S\\bold{aff}~C\\subseteq Saff C⊆S. 对于任何包含 CCC 的仿射集 SSS, 均有 aff C⊆S\\bold{aff}~C\\subseteq Saff C⊆S 。 包含 CCC 的仿射包是所有包含 CCC 的仿射集的交集! We define the affine dimension of a set C as the dimension of its affine hull. 我们定义集合 CCC 的仿射维数为其仿射包的位数。 As an example consider the unit circle in R2\\mathbb R^2R2, i.e., {x∈R2∣x12+x22=1}\\{x\\in\\mathbb R^2 | x^2_1 + x^2_2 = 1\\}{x∈R2∣x12+x22=1}. Its affine hull is all of R2\\mathbb R^2R2, so its affine dimension is two. 以 R2\\mathbb R^2R2 上的单位圆环为例,它的仿射包是全空间 R2\\mathbb R^2R2,所以它的放射维度是 2 If the affine dimension of a set C⊆RnC\\subseteq\\mathbb R^nC⊆Rn is less than nnn, then the set lies in the affine set aff C≠Rn\\bold{aff}~C \\neq\\mathbb R^naff C=Rn. 如果集合 C⊆RnC\\subseteq\\mathbb R^nC⊆Rn 的仿射维数小于 nnn 那么这个集合在仿射集 aff C≠Rn\\bold{aff}~C \\neq\\mathbb R^naff C=Rn 中。 We define the relative interior of the set CCC, denoted relint C\\bold{relint}~Crelint C, as its interior relative to aff C\\bold{aff}~Caff C: 我们定义集合 CCC 的相对内部为 aff C\\bold{aff}~Caff C 的内部 relint C\\bold{relint}~Crelint C : relint C={x∈C∣B(x,r)∩aff C⊆C, for some r>0}\\bold{relint}~C=\\{x\\in C|B(x,r)\\cap\\bold{aff}~C\\subseteq C\\text{, for some }r\\gt0\\} relint C={x∈C∣B(x,r)∩aff C⊆C, for some r>0} where B(x,r)={y∣ ∥y−x∥≤r}B(x,r)=\\{y|~\\Vert y-x\\Vert\\le r\\}B(x,r)={y∣ ∥y−x∥≤r} the ball of radius rrr and center xxx in the norm ∥⋅∥\\Vert\\cdot\\Vert∥⋅∥ ( Here ∥⋅∥\\Vert\\cdot\\Vert∥⋅∥ is any norm; all norms define the same relative interior). 其中,B(x,r)={y∣ ∥y−x∥≤r}B(x,r)=\\{y|~\\Vert y-x\\Vert\\le r\\}B(x,r)={y∣ ∥y−x∥≤r} 是以 xxx 为圆心, rrr 为半径的球。这个球是以范数 ∥⋅∥\\Vert\\cdot\\Vert∥⋅∥ 定义的(无论 ∥⋅∥\\Vert\\cdot\\Vert∥⋅∥ 是什么范数,所对应的相对内部是相同的) We can then define the relative boundary of a set CCC as cl C\\relint C\\bold{cl}~C \\backslash \\bold{relint}~Ccl C\\relint C, where cl C\\bold{cl}~Ccl C is the closure of CCC 我们随后可以定义集合 CCC 的相对边界为 cl C\\relint C\\bold{cl}~C \\backslash \\bold{relint}~Ccl C\\relint C, 此处 cl C\\bold{cl}~Ccl C 是集合 CCC 的闭包。 Example: Consider a square in the (x1,x2)(x_1, x_2)(x1,x2)-plane in R3\\mathbb R^3R3 defined as 例:考虑定义在 R3\\mathbb R^3R3 中的 (x1,x2)(x_1,x_2)(x1,x2) 平面 C={x∈R3∣−1<x1<1, −1<x2<1, x3=0}C=\\{x\\in\\mathbb R^3|-1\\lt x_1\\lt 1,~-1\\lt x_2\\lt1,~x_3=0\\} C={x∈R3∣−1<x1<1, −1<x2<1, x3=0} Its affine hull is the (x1,x2)(x_1, x_2)(x1,x2)-plane, i.e., aff C={x∈R3∣x3=0}\\bold{aff}~C =\\{x\\in\\mathbb R^3|x_3=0\\}aff C={x∈R3∣x3=0} 集合 CCC 的仿射包是整个 (x1,x2)(x_1, x_2)(x1,x2) 平面。也就是说 \\bold{aff}~C =\\ A point is in the interior of a set if you can draw a small open ball around it which is itself contained in the set. But for any point in our set CCC , any open ball around any point in it will contain points outside the (x1,x2)(x_1,x_2)(x1,x2)-plane, and so set CCC has empty interior. 如果通过集合中的某点,可以画出一个包含在这个集合内部的小开放球,那么我们认为这个点在集合的内部。但是,对于集合 CCC 而言,以集合 CCC 中的任意一点为中心的开放球必定包含 (x1,x2)(x_1,x_2)(x1,x2) 平面以外的点。所以集合 CCC 的内部为空。 The relative interior of a set is obtained by looking at the affine hull of the set, which in this case is R2\\mathbb R^2R2, and using the appropriate metric there. 集合的相对内部是通过查看集合的仿射包(在本例中是 R2\\mathbb R^2R2),并在那里使用适当的度量来获得的。 注:依然是通过集合 CCC 内一点画开放小球。这一次先和集合 CCC 的仿射包取交集,然后再判断是否包含在 CCC 内部。如果包含,则是相对内部 the relative interior of CCC is: 集合 CCC 的相对内部是: relint C={x∈R3∣−1<x1<1, −1<x2<1, x3=0}\\bold{relint}~C = \\{x\\in\\mathbb R^3 | −1 \\lt x_1 \\lt 1,~−1 \\lt x_2 \\lt 1,~x3 = 0\\} relint C={x∈R3∣−1<x1<1, −1<x2<1, x3=0} The boundary of a subset SSS of a topological space XXX is the set of points in the closure of SSS not belonging to the interior of SSS. Since, the interior of CCC is ∅\\varnothing∅, the boundary of CCC is CCC itself. 拓扑空间 XXX 的子集 SSS 的边界是集合 SSS 的闭包中不属于 SSS 内部的点的集合。集合 CCC 的内部为空,所以集合 CCC 的边界就是集合 CCC 本身。 Similarly, the relative boundary of CCC is the wire-frame outline {x∈R3∣max{∣x1∣,∣x2∣}=1, x3=0}\\{x\\in\\mathbb R^3 | \\max\\{|x_1|,|x_2|\\}=1,~x_3=0\\}{x∈R3∣max{∣x1∣,∣x2∣}=1, x3=0} 类似地,集合 CCC 的相对边界是集合 CCC 的边框。 # Convex Set 凸集 A set CCC is convex if the line segment between any two points in CCC lies in CCC, i.e., if for any x1,x2∈Cx_1, x_2\\in Cx1,x2∈C and any θ\\thetaθ with 0≤θ≤10\\le\\theta\\le10≤θ≤1, we have: 如果集合 CCC 中的任意两点连成的线段仍然在集合 CCC 中。那么我们称这个集合 CCC 是凸集。也就是说,对于任意 x1,x2∈Cx_1, x_2\\in Cx1,x2∈C 和 0≤θ≤10\\le\\theta\\le10≤θ≤1 下式成立: θx1+(1−θ)x2∈C\\theta x_1+(1-\\theta)x_2\\in C θx1+(1−θ)x2∈C We call a point of the form θ1x1+⋯+θkxk\\theta_1x_1 +\\cdots+ \\theta_kx_kθ1x1+⋯+θkxk, where θ1+⋯+θk=1\\theta_1 + \\cdots+ \\theta_k = 1θ1+⋯+θk=1 and θi≥0, i=1,⋯ ,k\\theta_i\\ge0,~i = 1,\\cdots , kθi≥0, i=1,⋯,k, a convex combination of the points x1,⋯ ,xkx_1,\\cdots, x_kx1,⋯,xk. 我们称 θ1x1+⋯+θkxk\\theta_1x_1 +\\cdots+ \\theta_kx_kθ1x1+⋯+θkxk 是点 x1,⋯ ,xkx_1,\\cdots, x_kx1,⋯,xk 的一个凸组合,其中 θ1+⋯+θk=1\\theta_1 + \\cdots+ \\theta_k = 1θ1+⋯+θk=1 并且 θi≥0, i=1,⋯ ,k\\theta_i\\ge0,~i = 1,\\cdots , kθi≥0, i=1,⋯,k As with affine sets, it can be shown that a set is convex if and only if it contains every convex combination of its points. 和仿射集类似,一个集合是凸集当且仅当这个集合包含其中任意点的所有凸组合。 A convex combination of points can be thought of as a mixture or weighted average of the points, with θi\\theta_iθi the fraction of xix_ixi in the mixture. 点的凸组合可以看做是点的混合或加权平均。θi\\theta_iθi 代表 xix_ixi 在混合中所占的权重。 The convex hull of a set CCC , denoted conv C\\bold{conv}~Cconv C , is the set of all convex combinations of points in CCC : 集合 CCC 的凸包 conv C\\bold{conv}~Cconv C 是由集合 CCC 内所有点的凸组合构成的: conv C={θ1x1+⋯+θkxk∣xi∈C, θi≥0, θ1+⋯+θk=1}\\bold{conv}~C=\\{\\theta_1x_1+\\cdots+\\theta_kx_k|x_i\\in C,~\\theta_i\\ge 0,~ \\theta_1+\\cdots+\\theta_k=1\\} conv C={θ1x1+⋯+θkxk∣xi∈C, θi≥0, θ1+⋯+θk=1} As the name suggests, the convex hull conv C\\bold{conv}~Cconv C is always convex. It is the smallest convex set that contains CCC: If BBB is any convex set that contains CCC, then conv C⊆B\\bold{conv}~C\\subseteq Bconv C⊆B. 顾名思义,凸包一定是凸的。凸包是包含集合CCC 的最小凸集。也就是说,如果集合 BBB 是包含集合 CCC 的凸集,那么一定有conv C⊆B\\bold{conv}~C\\subseteq Bconv C⊆B The idea of a convex combination can be generalized to include infinite sums, integrals, and, in the most general form, probability distributions. 凸组合的概念可以扩展到无穷级数、积分以及大多数形式的概率分布。 Suppose θ1,θ2,⋯\\theta_1,\\theta_2,\\cdotsθ1,θ2,⋯ satisfy θi≥0, i=1,2,⋯∑i=1∞θi=1\\theta_i\\ge0,~i=1,2,\\cdots\\quad\\sum\\limits^\\infty_{i=1}\\theta_i=1θi≥0, i=1,2,⋯i=1∑∞θi=1 and x1,x2,⋯∈Cx_1,x_2,\\cdots\\in Cx1,x2,⋯∈C , where C⊆RnC\\subseteq\\mathbb R^nC⊆Rn is convex. Then ∑i=1∞θixi∈C\\sum\\limits_{i=1}^\\infty\\theta_ix_i\\in Ci=1∑∞θixi∈C if the series converges. 假设 θ1,θ2,⋯\\theta_1,\\theta_2,\\cdotsθ1,θ2,⋯ 满足 θi≥0, i=1,2,⋯∑i=1∞θi=1\\theta_i\\ge0,~i=1,2,\\cdots\\quad\\sum\\limits^\\infty_{i=1}\\theta_i=1θi≥0, i=1,2,⋯i=1∑∞θi=1 并且 x1,x2,⋯∈Cx_1,x_2,\\cdots\\in Cx1,x2,⋯∈C ,其中 C⊆RnC\\subseteq\\mathbb R^nC⊆Rn 是凸集。如果级数 ∑i=1∞θixi\\sum\\limits_{i=1}^\\infty\\theta_ix_ii=1∑∞θixi 收敛,那么 ∑i=1∞θixi∈C\\sum\\limits_{i=1}^\\infty\\theta_ix_i\\in Ci=1∑∞θixi∈C More generally, suppose p:Rn→Rp:\\R^n\\rightarrow \\Rp:Rn→R satisfies p(x)≥0p(x) \\ge 0p(x)≥0 for all x∈Cx\\in Cx∈C and ∫Cp(x) dx=1\\int_Cp(x)~{\\rm d}x = 1∫Cp(x) dx=1, where C⊆RnC\\subseteq\\R^nC⊆Rn is convex. Then ∫Cp(x)x dx∈C\\int_C p(x)x~{\\rm d}x\\in C∫Cp(x)x dx∈C, if the integral exists. 更一般地说,假设 p:Rn→Rp:\\R^n\\rightarrow \\Rp:Rn→R 对所有 x∈Cx\\in Cx∈C 满足 p(x)≥0p(x) \\ge 0p(x)≥0 ,并且 ∫Cp(x) dx=1\\int_Cp(x)~{\\rm d}x = 1∫Cp(x) dx=1 ,其中 C⊆RnC\\subseteq\\R^nC⊆Rn 是凸集。如果积分 ∫Cp(x)x dx\\int_C p(x)x~{\\rm d}x∫Cp(x)x dx 存在,那么 ∫Cp(x)x dx∈C\\int_C p(x)x~{\\rm d}x\\in C∫Cp(x)x dx∈C In the most general form, suppose C⊆RnC\\subseteq\\R^nC⊆Rn is convex and xxx is a random vector with x∈Cx\\in Cx∈C with probability one. Then Ex∈C\\bold{E}x\\in CEx∈C. 最一般的情况是,假设 C⊆RnC\\subseteq\\R^nC⊆Rn 是凸集,xxx 是随机变量。并且 x∈Cx\\in Cx∈C 的概率是 1,那么 Ex∈C\\bold{E}x\\in CEx∈C. For example, suppose the random variable xxx only takes on the two values x1x_1x1 and x2x_2x2, with prob (x=x1)=θ\\bold{prob}~(x = x_1) = \\thetaprob (x=x1)=θ and prob (x=x2)=1−θ\\bold{prob}~(x = x_2) = 1 - \\thetaprob (x=x2)=1−θ, where 0≤θ≤10\\le\\theta\\le10≤θ≤1. Then Ex=θx1+(1−θ)x2\\bold{E}x = \\theta x_1 + (1 -\\theta)x_2Ex=θx1+(1−θ)x2, and we are back to a simple convex combination of two points. # Cones 锥 A set CCC is called a cone, or nonnegative homogeneous, if for every x∈Cx\\in Cx∈C and θ≥0\\theta\\ge0θ≥0 we have θx∈C\\theta x\\in Cθx∈C. 如果对于任意的 x∈Cx\\in Cx∈C 和 θ≥0\\theta\\ge0θ≥0 都有 θx∈C\\theta x\\in Cθx∈C 那么我们称集合 CCC 是一个锥(或也称非负齐次)。 A set CCC is a convex cone if it is convex and a cone, which means that for any x1,x2∈Cx_1, x_2\\in Cx1,x2∈C and θ1,θ2≥0\\theta_1, \\theta_2\\ge0θ1,θ2≥0, we have: 如果集合 CCC 是一个锥,并且是凸集,那么集合 CCC 是一个凸锥。即对于任何的 x1,x2∈Cx_1, x_2\\in Cx1,x2∈C 和 θ1,θ2≥0\\theta_1, \\theta_2\\ge0θ1,θ2≥0 都有: θ1x1+θ2x2∈C\\theta_1x_1+\\theta_2x_2\\in C θ1x1+θ2x2∈C Points of this form can be described geometrically as forming the two-dimensional pie slice with apex 000 and edges passing through x1x_1x1 and x2x_2x2. 在几何上,具有此类形式的点,构成了二维的扇形。这个扇形以 000 为顶点(θ1=θ2=0\\theta_1=\\theta_2=0θ1=θ2=0 时),边通过点 x1x_1x1 和 x2x_2x2 A point of the form θ1x1+⋯+θkxk\\theta_1x_1+\\cdots+\\theta_kx_kθ1x1+⋯+θkxk with θ1,⋯ ,θk≥0\\theta_1,\\cdots, \\theta_k\\ge0θ1,⋯,θk≥0 is called a conic combination (or a nonnegative linear combination) of x1,⋯ ,xkx_1,\\cdots, x_kx1,⋯,xk . 具有 θ1x1+⋯+θkxk\\theta_1x_1+\\cdots+\\theta_kx_kθ1x1+⋯+θkxk , θ1,⋯ ,θk≥0\\theta_1,\\cdots, \\theta_k\\ge0θ1,⋯,θk≥0 形式的点称为 x1,⋯ ,xkx_1,\\cdots, x_kx1,⋯,xk 的锥组合(或非负线性组合)。 If xix_ixi (i=1,2,⋯i=1,2,\\cdotsi=1,2,⋯) are in a convex cone CCC, then every conic combination of xix_ixi is in CCC. Conversely, a set CCC is a convex cone if and only if it contains all conic combinations of its elements. 如果 xix_ixi (i=1,2,⋯i=1,2,\\cdotsi=1,2,⋯) 均属于凸锥 CCC 中,那么 xix_ixi 的每一个锥组合也在 CCC 中。反言之,集合 CCC 是凸锥的充要条件是它包含其元素的所有锥组合。 Like convex (or affine) combinations, the idea of conic combination can be generalized to infinite sums and integrals. 与凸组合(或仿射组合)类似,锥组合的概念可以扩展到无穷级数和积分中。 The conic hull of a set CCC is the set of all conic combinations of points in CCC, i.e., 集合 CCC 的锥包是 CCC 中元素的所有锥组合的集合。即 {θ1x1+⋯+θkxk∣xi∈C, θi≥0, i=1,⋯ ,k}\\{\\theta_1x_1 +\\cdots+ \\theta_kx_k|x_i\\in C,~\\theta_i\\ge0,~i = 1,\\cdots, k\\} {θ1x1+⋯+θkxk∣xi∈C, θi≥0, i=1,⋯,k} which is also the smallest convex cone that contains CCC. 它是包含 CCC 的最小凸锥。 # Some Important Examples 重要的例子 some simple and important examples of convex sets: 一些简单且重要的凸集: the empty set ∅\\varnothing∅, any single point (i.e., singleton) {x0}\\{x_0\\}{x0} and the whole space Rn\\R^nRn are affine (hence, convex) subsets of Rn\\R_nRn 空集 ∅\\varnothing∅ ,任意单点集 {x0}\\{x_0\\}{x0} 和全空间 Rn\\R^nRn 都是 Rn\\R^nRn 的仿射(当然也是凸的)子集 Any line is affine. If it passes through zero, it is a subspace, hence also a convex cone. 直线是仿射的。如果直线经过原点 000 , 那么这条直线就是子空间,因此,也是凸锥。 A line segment is convex, but not affine (unless it reduces to a point). 线段是凸集,但不是仿射集。除非退化成单点集。 A ray, which has the form {x0+θv∣θ≥0}\\{x_0 +\\theta_v | \\theta\\ge0\\}{x0+θv∣θ≥0}, where v≠0v\\ne0v=0, is convex, but not affine. It is a convex cone if its base x0x_0x0 is 000. 一条射线 {x0+θv∣θ≥0}, (θ>0)\\{x_0 +\\theta_v | \\theta\\ge0\\},~(\\theta\\gt0){x0+θv∣θ≥0}, (θ>0) 是凸的。但不是仿射的。如果基点 x0=0x_0 = 0x0=0 则它是凸锥。 Any subspace is affine, and a convex cone (hence convex) 任意子空间是仿射的。是凸锥(当然也是凸的)。 # Hyperplanes and halfspaces 超平面和半空间 A hyperplane is a set of the form: 超平面是具有以下形式的集合 {x∣aTx=b}\\{x|a^Tx=b\\} {x∣aTx=b} where a∈Rn, a≠0a\\in\\R^n,~a\\ne0a∈Rn, a=0, and b∈Rb\\in\\Rb∈R. 其中 a∈Rn, a≠0a\\in\\R^n,~a\\ne0a∈Rn, a=0 并且 b∈Rb\\in\\Rb∈R. Analytically it is the solution set of a nontrivial linear equation among the components of xxx (and hence an affine set). 解析上,超平面是关于 xxx 的线性方程组的非平凡解空间(因此一定是一个仿射集)。 Geometrically, the hyperplane {x∣aTx=b}\\{x|a^Tx=b\\}{x∣aTx=b} can be interpreted as the set of points with a constant inner product to a given vector aaa, or as a hyperplane with normal vector aaa; the constant b∈Rb\\in\\Rb∈R determines the offset of the hyperplane from the origin. 几何上,超平面可以解释为:与给定向量 aaa 的内积为常数的点的集合。另一种解释是:可以看做法线方向为 aaa 的超平面,其中,常数 b∈Rb\\in\\Rb∈R 决定了这个平面从原点的偏移。 This geometric interpretation can be understood by expressing the hyperplane in the form: 为了更好地在几何上理解超平面,我们将超平面表示为下面的形式: {x∣aT(x−x0)=0}\\{x|a^T(x-x_0)=0\\} {x∣aT(x−x0)=0} where x0x_0x0 is any point in the hyperplane (i.e., any point that satisfies aTx0=ba^T x_0 = baTx0=b). This representation can in turn be expressed as: 其中 x0x_0x0 是超平面中满足 aTx0=ba^T x_0 = baTx0=b 的任意一点。这样一来,超平面的表达式可以改写成: {x∣aT(x−x0)=0}=x0+a⊥\\{x|a^T(x-x_0)=0\\}=x_0+a^\\perp {x∣aT(x−x0)=0}=x0+a⊥ where a⊥a^\\perpa⊥ denotes the orthogonal complement of aaa, i.e., the set of all vectors orthogonal to it: 其中,a⊥a^\\perpa⊥ 是 aaa 的正交补。即与向量 aaa 正交的向量的集合: a⊥={v∣aTv=0}a^\\perp=\\{v|a^Tv=0\\} a⊥={v∣aTv=0} This shows that the hyperplane consists of an offset x0x_0x0, plus all vectors orthogonal to the (normal) vector aaa. 由此可见,超平面由偏移 x0x_0x0 加上所有正交于向量 aaa 的向量构成。(实际上向量 aaa 就是超平面的法向量) A hyperplane divides Rn\\R^nRn into two halfspaces. A (closed) halfspace is a set of the form: 一个超平面将 Rn\\R^nRn 分成两个半空间。(闭的)半空间是具有以下形式的集合: \\begin{equation}\\tag{2.1}\\label{eq2.1} \\{x|a^Tx\\le b\\} \\end{equation} where a≠0a\\ne0a=0, i.e., the solution set of one (nontrivial) linear inequality. 即,线性不等式的(非平凡的)解空间。其中 a≠0a\\ne0a=0 Halfspaces are convex, but not affine. 半空间是凸的,但不是仿射的。 The halfspace \\eqref{eq2.1} can also be expressed as: 半空间 \\eqref{eq2.1} 还可以表示为 \\begin{equation}\\tag{2.2}\\label{eq2.2} \\{x|a^T(x-x_0)\\le 0\\} \\end{equation} where x0x_0x0 is any point on the associated hyperplane, i.e., satisfies aTx0=ba^T x_0 = baTx0=b. 其中, x0x_0x0 是超平面上的任意一点。即 x0x_0x0 满足 aTx0=ba^T x_0 = baTx0=b. The representation \\eqref{eq2.2} suggests a simple geometric interpretation: the halfspace consists of x0x_0x0 plus any vector that makes an obtuse (or right) angle with the (outward normal) vector aaa. 表达式 \\eqref{eq2.2} 有一个简单的几何解释:半空间由 x0x_0x0 加上任意一个与(向外的)法向量 aaa 呈钝角(或直角)的向量组成。 The boundary of the halfspace {x∣aTx≤b}\\{x | a^T x\\le b\\}{x∣aTx≤b} is the hyperplane {x∣aTx=b}\\{x | a^T x = b\\}{x∣aTx=b}. 半空间 {x∣aTx≤b}\\{x | a^T x\\le b\\}{x∣aTx≤b} 的边界是超平面 {x∣aTx=b}\\{x | a^T x = b\\}{x∣aTx=b}. The set {x∣aTx<b}\\{x | a^T x\\lt b\\}{x∣aTx<b}, which is the interior of the halfspace {x∣aTx≤b}\\{x | a^T x\\le b\\}{x∣aTx≤b}, is called an open halfspace. 集合 {x∣aTx<b}\\{x | a^T x\\lt b\\}{x∣aTx<b} 是半空间 {x∣aTx≤b}\\{x | a^T x\\le b\\}{x∣aTx≤b} 的内部,也称为半开空间。 # Euclidean balls and ellipsoids 欧几里得球和椭球 A (Euclidean) ball (or just ball) in Rn\\R^nRn has the form: Rn\\R^nRn 空间里的欧几里得球(或简称球)具有下面的形式: B(xc,r)={x∣ ∥x−xc∥2≤r}={x∣ (x−xc)T(x−xc)≤r2}B(x_c,r)=\\{x|~\\Vert x-x_c\\Vert_2\\le r\\}=\\{x|~(x-x_c)^T(x-x_c)\\le r^2\\} B(xc,r)={x∣ ∥x−xc∥2≤r}={x∣ (x−xc)T(x−xc)≤r2} where r>0r\\gt0r>0, and ∥⋅∥2\\Vert\\cdot\\Vert_2∥⋅∥2 denotes the Euclidean norm, i.e., ∥u∥2=(uTu)1/2\\Vert u\\Vert_2=(u^Tu)^{1/2}∥u∥2=(uTu)1/2 其中 r>0r\\gt0r>0, ∥⋅∥2\\Vert\\cdot\\Vert_2∥⋅∥2 表示欧几里得范数(也就是二范数)即 \\Vert u\\Vert_2=(u^Tu)^ The vector xcx_cxc is the center of the ball and the scalar rrr is its radius; B(xc,r)B(x_c, r)B(xc,r) consists of all points within a distance rrr of the center xcx_cxc. 向量 xcx_cxc 是球心,标量 rrr 是半径。B(xc,r)B(x_c, r)B(xc,r) 由距离球心 xcx_cxc 不超过 rrr 的所有点构成。 Another common representation for the Euclidean ball is: 欧几里得球的另一个常见的表达式是: B(xc,r)={xc+ru∣ ∥u∥2≤1}.B(x_c, r)=\\{x_c+ru|~\\Vert u\\Vert2\\le1\\}. B(xc,r)={xc+ru∣ ∥u∥2≤1}. A Euclidean ball is a convex set: if ∥x1−xc∥2\\Vert x_1-x_c\\Vert_2∥x1−xc∥2 , ∥x2−xc∥2\\Vert x_2-x_c\\Vert_2∥x2−xc∥2 and 0≤θ≤10\\le\\theta\\le10≤θ≤1, then 欧几里得球是凸集。即如果 ∥x1−xc∥2\\Vert x_1-x_c\\Vert_2∥x1−xc∥2 , ∥x2−xc∥2\\Vert x_2-x_c\\Vert_2∥x2−xc∥2 并且 0≤θ≤10\\le\\theta\\le10≤θ≤1, 那么 ∥θx1+(1−θ)x2−xc∥2=∥θ(x1−xc)+(1−θ)(x2−xc)∥2≤θ∥x1−xc∥2+(1−θ)∥x2−xc∥2≤r\\begin{aligned} \\Vert\\theta x_1+(1-\\theta)x_2-x_c\\Vert_2 & = \\Vert\\theta(x_1-x_c)+(1-\\theta)(x_2-x_c)\\Vert_2 \\\\ & \\le\\theta\\Vert x_1-x_c\\Vert_2+(1-\\theta)\\Vert x_2-x_c\\Vert_2 \\\\ & \\le r \\end{aligned} ∥θx1+(1−θ)x2−xc∥2=∥θ(x1−xc)+(1−θ)(x2−xc)∥2≤θ∥x1−xc∥2+(1−θ)∥x2−xc∥2≤r Here we use the homogeneity property and triangle inequality for ∥⋅∥2\\Vert\\cdot\\Vert_2∥⋅∥2 此处使用到了欧几里得范数(二范数)的齐次性,以及三角不等式。 A related family of convex sets is the ellipsoids, which have the form: 一类相关的凸集是是椭球。它们具有以下的形式: \\begin{equation} \\tag{2.3} \\label{eq2.3} \\varepsilon=\\{x|(x-x_c)^TP^{-1}(x-x_c)\\le1\\} \\end{equation} where P=PT≻0P=P^T\\succ 0P=PT≻0, i.e., PPP is symmetric and positive definite. 其中 P=PT≻0P=P^T\\succ 0P=PT≻0 即 PPP 是对称的正定矩阵。 Definiteness of Matrix 矩阵的正定性 Real Quadratic Forms 二次型 Let AAA be a k×kk\\times kk×k real matrix. A quadratic form in AAA is a transformation: 假设矩阵 AAA 是一个 k×kk\\times kk×k 的实方阵。它的二次型是这样一个变换: xTAxx^TAx xTAx where xxx is a k×1k\\times1k×1 vector and xTx^TxT is its transpose. 其中,向量 xxx 是 kkk 行 111 列的向量,向量 xTx^TxT 是向量 xxx 的转置向量。 The transformation xTAxx^{T}AxxTAx is a scalar. For example, we define: 二次型变换,会得到一个标量。例如: A=[243−5]A=\\begin{bmatrix}2&4\\\\3&-5\\end{bmatrix} A=[234−5] Given a 2×12\\times 12×1 vector xxx, the quadratic form defined by the matrix AAA is 给定一个 222 行 111 列的向量 xxx,那么矩阵 AAA 的二次型就是: xTAx=[x1x2][243−5][x1x2]=[x1x2][2x1+4x23x1−5x2]=2x12+7x1x2−5x22\\begin{aligned} x^TAx &= \\begin{bmatrix}x_1&x_2\\end{bmatrix} \\begin{bmatrix}2&4\\\\3&-5\\end{bmatrix} \\begin{bmatrix}x_1\\\\x_2\\end{bmatrix} \\\\ &= \\begin{bmatrix}x_1&x_2\\end{bmatrix} \\begin{bmatrix}2x_1+4x_2\\\\3x_1-5x_2\\end{bmatrix}\\\\ &= 2x_1^2+7x_1x_2-5x_2^2 \\end{aligned} xTAx=[x1x2][234−5][x1x2]=[x1x2][2x1+4x23x1−5x2]=2x12+7x1x2−5x22 Restricting attention to symmetric matrices 让我们着眼于对称矩阵 a matrix BBB is symmetric if and only if 矩阵 BBB 是对称矩阵,当且仅当 B=BTB=B^T B=BT Any quadratic form can be written as 任意一个二次型可以被改写成以下形式: xTAx=12xTAx+12xTAx=12xTAx+12(xTAx)T=12xTAx+12xTATx=xT(12A+12AT)x\\begin{aligned} x^TAx &= \\frac12x^TAx+\\frac12x^TAx\\\\ &= \\textcolor{red}{\\frac12x^TAx+\\frac12(x^TAx)^T}\\\\ &= \\frac12x^TAx+\\frac12x^TA^Tx\\\\ &= x^T(\\frac12A+\\frac12A^T)x \\end{aligned} xTAx=21xTAx+21xTAx=21xTAx+21(xTAx)T=21xTAx+21xTATx=xT(21A+21AT)x since xTAxx^{T}AxxTAx is a scalar, the transpose of a scalar is equal to the scalar itself. 由于二次型 xTAxx^{T}AxxTAx 是标量。标量的转置等于自身。、 The matrix B=12A+12ATB=\\frac12A+\\frac12A^TB=21A+21AT is symmetric because BT=BB^T=BBT=B. 矩阵 BBB 是对称矩阵,因为矩阵 BTB^TBT 和矩阵 BBB 相等。 Thus, we have proved that we can always write a quadratic form as xTAx=xTBxx^TAx=x^TBxxTAx=xTBx where BBB is symmetric. 因此,我们总能将二次型 xTAxx^{T}AxxTAx 改写成 xTBxx^{T}BxxTBx,其中 BBB 是一个实对称矩阵。 Definiteness 正定性 Square matrices can be classified based on the sign of the quadratic forms that they define. 方阵可以根据其对应的二次型的符号来分类。 Let matrix AAA be a k×kk\\times kk×k real symmetric matrix. 令矩阵 AAA 为 k×kk\\times kk×k 的实对称方阵。 the matrix, denoted A≻0A\\succ0A≻0, is positive definite if and only if xTAx>0x^{T}Ax\\gt0xTAx>0 for any non-zero k×1k\\times1k×1 vector xxx having real entries; 矩阵 AAA 是正定矩阵,记作 A≻0A\\succ0A≻0,当且仅当对于任意的非零实向量 xxx 而言, xTAx>0x^TAx\\gt0xTAx>0 恒成立 the matrix, denoted A⪰0A\\succeq0A⪰0, is positive semi-definite if and only if xTAx≥0x^{T}Ax\\ge0xTAx≥0 for any non-zero k×1k\\times1k×1 vector xxx having real entries; 矩阵 AAA 是半正定矩阵,记作 A⪰0A\\succeq0A⪰0,当且仅当对于任意的非零实向量 xxx 而言, xTAx≥0x^TAx\\ge0xTAx≥0 恒成立 the matrix, denoted A≺0A\\prec0A≺0, is negative definite if and only if xTAx<0x^{T}Ax\\lt0xTAx<0 for any non-zero k×1k\\times1k×1 vector xxx having real entries; 矩阵 AAA 是负定矩阵,记作 A≺0A\\prec0A≺0,当且仅当对于任意的非零实向量 xxx 而言, xTAx<0x^TAx\\lt0xTAx<0 恒成立 the matrix, denoted A⪯0A\\preceq0A⪯0, is negative semi-definite if and only if xTAx≤0x^{T}Ax\\le0xTAx≤0 for any non-zero k×1k\\times1k×1 vector xxx having real entries; 矩阵 AAA 是半负定矩阵,记作 A⪯0A\\preceq0A⪯0,当且仅当对于任意的非零实向量 xxx 而言, xTAx≤0x^TAx\\le0xTAx≤0 恒成立 the matrix is indefinite if and only if there exist two non-zero k×1k\\times1k×1 vector xxx and yyy (having real entries) such that xTAx>0x^{T}Ax>0xTAx>0 and yTAy<0y^{T}Ay<0yTAy<0. 假若存在两个非零的 k×1k\\times1k×1 实向量 xxx 和 yyy 满足 xTAx>0x^{T}Ax>0xTAx>0 并且 yTAy<0y^{T}Ay<0yTAy<0,那么矩阵 AAA 是不定矩阵。 The vector xc∈Rnx_c\\in\\R^nxc∈Rn is the center of the ellipsoid. The matrix PPP determines how far the ellipsoid extends in every direction from xcx_cxc; the lengths of the semi-axes of ε\\varepsilonε are given by λi\\sqrt{\\lambda_i}λi, where λi\\lambda_iλi are the eigenvalues of PPP. 向量 xc∈Rnx_c\\in\\R^nxc∈Rn 为椭球的中心。矩阵 PPP 确定了椭球从中心 xcx_cxc 向各个方向的扩展的幅度。椭球 ε\\varepsilonε 的半长轴长度由 λi\\sqrt{\\lambda_i}λi 给出( λi\\lambda_iλi 是矩阵 PPP 的特征值。) A ball is an ellipsoid with P=r2IP=r^2IP=r2I 球是满足 P=r2IP=r^2IP=r2I 的椭球。 Another common representation of an ellipsoid is : 椭球的另一种常见的表达式是: \\begin{equation} \\tag{2.4} \\label{eq2.4} \\varepsilon=\\{x_c+Au|~\\Vert u\\Vert_2\\le1\\} \\end{equation} where AAA is square and nonsingular. 其中方阵 AAA 是非奇异的。 In this representation we can assume without loss of generality that AAA is symmetric and positive definite. 在这种表现形式中,我们不失一般性地假设 AAA 对称,且正定。 By taking A=P1/2A = P ^{1/2}A=P1/2, this representation gives the ellipsoid defined in \\eqref{eq2.3}. 取 A=P1/2A = P ^{1/2}A=P1/2 ,这个表达式给出了由 \\eqref{eq2.3} 式定义的椭球。 When the matrix AAA in \\eqref{eq2.4} is symmetric positive semidefinite but singular, the set in (2.4) is called a degenerate ellipsoid; its affine dimension is equal to the rank of AAA. 当 \\eqref{eq2.4} 中的矩阵 AAA 为对称半正定的奇异矩阵时,集合 \\eqref{eq2.4} 是退化的椭球,其仿射维数等于 AAA 的秩。 Degenerate ellipsoids are also convex. 退化的椭球也是凸的。 # Norm Balls and Norm Cones 范数球和范数锥 Suppose ∥⋅∥\\Vert\\cdot\\Vert∥⋅∥ is any norm on Rn\\R^nRn. 假设 ∥⋅∥\\Vert\\cdot\\Vert∥⋅∥ 是 Rn\\R^nRn 上的任意范数 From the general properties of norms it can be shown that a norm ball of radius rrr and center xcx_cxc, given by {x∣ ∥x−xc∥≤r}\\{x|~\\Vert x-x_c\\Vert \\le r\\}{x∣ ∥x−xc∥≤r}, is convex. 根据范数的基本性质可知,以 xcx_cxc 为中心,以 rrr 为半径的范数球 {x∣ ∥x−xc∥≤r}\\{x|~\\Vert x-x_c\\Vert \\le r\\}{x∣ ∥x−xc∥≤r} 是一个凸集。 The norm cone associated with the norm ∥⋅∥\\Vert\\cdot\\Vert∥⋅∥ is the set: 关于集合的范数锥是集合 C={(x,t)∣ ∥x∥≤t}⊆Rn+1C=\\{(x,t)|~\\Vert x\\Vert\\le t\\}\\subseteq\\R^{n+1} C={(x,t)∣ ∥x∥≤t}⊆Rn+1 It is (as the name suggests) a convex cone. 顾名思义,范数锥是一个凸锥。 Example: The second-order cone is the norm cone for the Euclidean norm, i.e., 例:二阶锥是由欧几里得范数定义的范数锥。 C={(x,t)∈Rn+1∣ ∥x∥2≤t}={[xt]∣[xt]T[I00−1][xt]≤0, t≥0}\\begin{aligned} C & =\\{(x,t)\\in\\R^{n+1}|~\\Vert x\\Vert_2\\le t\\}\\\\ & = \\left\\{ \\begin{bmatrix}x\\\\t\\end{bmatrix} \\bigg|\\begin{bmatrix}x\\\\t\\end{bmatrix}^T \\begin{bmatrix}I&0\\\\0 &-1 \\end{bmatrix} \\begin{bmatrix}x\\\\t\\end{bmatrix}\\le 0,~t\\ge0 \\right\\} \\end{aligned} C={(x,t)∈Rn+1∣ ∥x∥2≤t}={[xt]∣∣∣∣∣[xt]T[I00−1][xt]≤0, t≥0} The second-order cone is also known by several other names. It is called the quadratic cone, since it is defined by a quadratic inequality. It is also called the Lorentz cone or ice-cream cone. 二阶锥还有许多别名。因为它由二次不等式定义,所以它也叫二次锥。也叫做 Lorentz\\bold{Lorentz}Lorentz 锥或冰淇淋锥。 # Polyhedra 多面体 A polyhedron is defined as the solution set of a finite number of linear equalities and inequalities: 多面体是有限个线性等式和不等式的解集, \\begin{equation} \\tag{2.5}\\label{eq2.5} \\mathcal P = \\{x|a_j^Tx\\le b_j,~j=1,\\cdots,m;\\quad c_j^Tx=d_j,~j=1,\\cdots,p\\} \\end{equation} A polyhedron is thus the intersection of a finite number of halfspaces and hyperplanes. 因此,多面体是有限个超平面和半空间的交集。 Affine sets (e.g., subspaces, hyperplanes, lines), rays, line segments, and halfspaces are all polyhedra. 仿射集合(比如子空间,超平面,直线等)、射线、线段和半空间都是多面体。 It is easily shown that polyhedra are convex sets. 容易证明:多面体是凸集。","categories":[{"name":"基本法则","slug":"基本法则","permalink":"http://blog.sunforge.cn/categories/%E5%9F%BA%E6%9C%AC%E6%B3%95%E5%88%99/"},{"name":"数学","slug":"基本法则/数学","permalink":"http://blog.sunforge.cn/categories/%E5%9F%BA%E6%9C%AC%E6%B3%95%E5%88%99/%E6%95%B0%E5%AD%A6/"},{"name":"凸优化","slug":"基本法则/数学/凸优化","permalink":"http://blog.sunforge.cn/categories/%E5%9F%BA%E6%9C%AC%E6%B3%95%E5%88%99/%E6%95%B0%E5%AD%A6/%E5%87%B8%E4%BC%98%E5%8C%96/"}],"tags":[{"name":"笔记","slug":"笔记","permalink":"http://blog.sunforge.cn/tags/%E7%AC%94%E8%AE%B0/"}]},{"title":"二分图","slug":"computer-science/data-structures-and-algorithms/bipartite-graph","date":"2022-09-26T15:29:35.000Z","updated":"2022-10-18T12:44:06.632Z","comments":true,"path":"computer-science/data-structures-and-algorithms/bipartite-graph/","link":"","permalink":"http://blog.sunforge.cn/computer-science/data-structures-and-algorithms/bipartite-graph/","excerpt":"","text":"# Bipartite Graph 二分图 # Definition 定义 A bipartite graph (bigraph) G=(U,V,E)G=(U,V,E)G=(U,V,E) is a graph whose vertices can be divided into two disjoint and independent sets UUU and VVV, that is every edge in EEE connects a vertex in UUU to one in VVV (i.e. no two graph vertices within the same set are adjacent. ). 二分图,也称二部图。二分图 G=(U,V,E)G=(U,V,E)G=(U,V,E) 的顶点集被分成两个独立且互不相交的顶点集 UUU 和 VVV。二分图的每一条边,都连接了结点集 UUU 和结点集 VVV (换句话说,在同一个点集里的两个结点不邻接)。 a bipartite graph is a graph that does not contain any odd-length cycles. 二分图不含奇数环(边数为奇数的环) # Types of Bipartite Graph 二分图的种类 If ∣U∣=∣V∣|U|=|V|∣U∣=∣V∣, that is, if the two subsets have equal cardinality, then GGG is called a balanced bipartite graph. 如果点集 UUU 与点集 VVV 大小相同,那么这个二分图 GGG 是一个平衡二分图。 If all vertices on the same side of the bipartition have the same degree, then GGG is called semiregular bipartite graph (biregular). 如果二分图中同一侧的所有顶点有相同的度,那么这个二分图 GGG 是半正则二分图 If all vertices of the bipartite graph, then GGG is called regular bipartite graph 如果二分图的所有顶点都有相同的度,那么这个二分图 GGG 是正则二分图 If every possible edge that could connect vertices in different subset UUU and VVV is part of the graph, the bipartite graph is call complete bipartite graph 结点集合 UUU 中的任意一个结点与结点集合 VVV 中任意一个结点均相连的图,叫做完全二分图。 ⋯\\cdots⋯ # Testing Bipartiteness by Graph Coloring 染色法判定二分图 A bipartite graph is possible if it is possible to assign a color to each vertex such that no two neighbor vertices are assigned the same color. Only two colors can be used in this process. 只用两种颜色将图中的每一个结点进行染色。如果任意两个相邻结点的颜色不同(等价地说,每条边的两个端点颜色都不同),则这个图是二分图。 The algorithm is an application of BFS (Breadth-First Search). Setps: 该算法是广度优先搜索的应用。算法步骤如下: Assign a colour(say red) to the source vertex. 首先,为源点分配一种颜色(假设为红色) Assign all the neighbours of the above vertex another colour(say blue). 其次,为源点的所有邻接节点分配与源点不同的颜色(假设为蓝色) Taking one neighbour at a time, assign all the neighbour's neighbours the colour red. 再次,挑选源点的一个邻接节点,将这个邻接节点的所有邻接节点都染为红色。 Continue in this manner till all the vertices have been assigned a colour. 重复上述的步骤,交替染色,直到所有节点都染上颜色。 If at any stage, we find a neighbour which has been assigned the same colour as that of the current vertex, stop the process. The graph cannot be coloured using two colours. Thus the graph is not bipartite. 任何时候,只要我们发现某个节点和它的邻接节点同色,就停止程序运行。这意味着这个图不可能是二部图。 How to choose a source vertex? 如何选择源点? If it is a connected graph, any vertex can be the source point, because all vertices can be traversed throught any starting point. 对于连通图而言,选择任何一个顶点作为源点都是可以的,因为不管是哪一个点作为源点,连通图的所有点都是可达的。 If it is a disconnected graph, we need to find a source point for each connected subgraph. 对于非连通图而言,我们要为这个图的每一个连通子图找到一个源点。 为了方便起见,每个点都作为起点,当以该点为起点开始染色时,先判断这个点是否已经染过色了,如果没有染色,再开始进行染色。 Also, we can use DFS (Depth-First Search) to test bipartiteness. 当然,我们也可以使用深度优先搜索进行二分图判定。 # Bipartite Matching 二分图匹配算法 A matching in a Bipartite Graph is a set of the edges chosen in such a way that no two edges share an endpoint. 二分图的匹配是一个边集。在这个边集中,任意两个边之间没有共同的顶点。(只能一对一,也就是说一个顶点最多只能和一条边有联系) A maximal matching is a matching M of a graph G that is not a subset of any other matching. In a maximal matching, if any edge is added to it, it is no longer a matching. 图 GGG 的极大匹配 MMM 不是任何其他匹配的子集。极大匹配不能再添加边,否则就不是匹配了。 A maximum matching is a matching of maximum size (maximum number of edges) among all the maximal matching. There can be more than one maximum matchings for a given Bipartite Graph. 最大匹配是所有极大匹配中边数最多的匹配。一个二分图,可以有多个最大匹配。 A complete matching of a graph is a matching in which every vertex in the smaller vertex set is matched against some vertex in another set. 完全匹配中,较小的顶点集合中的每一个顶点都和另一个顶点集合中的某一个顶点匹配。 note that: 注意: Every complete matching is maximum matching. Maximum matching may not necessary to be complete matching 完全匹配必为最大匹配。最大匹配不一定是完美匹配。 complete matching equals to maximum matching in complete bipartite graph 在完全二部图中,完全匹配等价于最大匹配 A complete matching becomes a perfect matching ** if the two vertex sets are the same size. Perfect matchings are only possible on graphs with an even number of vertices. 如果两个顶点集合大小相同,那么完全匹配就变成了完美匹配 **。完美匹配只可能出现在具有偶数个顶点的图中。 # Hungary Algorithm 匈牙利算法 Hungarian algorithm is a method for maximum matching in graph theory. The Hungarian method is a combinatorial optimization algorithm that solves the assignment problem in polynomial time. 匈牙利算法是图论中的一种最大匹配算法。匈牙利算法是一种组合优化算法,能够在多项式时间内解决分配问题。 The core of the Hungarian algorithm is to find an augmented path, which is an algorithm that uses an augmented path to find the maximum matching of a bipartite graph. 匈牙利算法的核心是寻找增广路径以得到二分图的最大匹配。 # basic terminologies 基本术语 Alternating path: Given a matching M, an alternating path is a path that begins with an unmatched vertex and whose edges belong alternatively to the matching and not to the matching. 交替路:给定一个匹配 M,从任意一个未匹配点出发,未匹配边与匹配边交替出现的路径是交替路。(交替路一定是以未匹配边开始的) Augmented path: Given a matching M, an augmenting path is an alternating path that starts from and ends on free (unmatched) vertices. 增广路:增广路是终点为未匹配点的交替路。(增广路的起点和终点都是未匹配点) Given a matching M, Berge's lemma states that a matching M is maximum if and only if there is no augmenting path with respect to M. Berge 引理(增广路定理)指出,当且仅当不存在增广路径时,图 G 的匹配 M 是最大匹配。 # algorithm outline 算法思想 set MMM to be empty. 记 MMM 为空匹配 find an augmented path PPP, and obtain a larger matching M′M^\\primeM′ instead of MMM through Exclusive-OR (XOR) operation. 找到一条增广路径 PPP,并与原匹配 MMM 进行异或操作,得到新匹配 M′M^\\primeM′ (效果是,增广路上的未匹配边变成了匹配边,原匹配边变成了未匹配边) repeat the operation until no augmented path can be found. 重复上述过程直到图中不存在增广路。 # pseudo code 算法伪代码 p// assume x in set U, y in set V. G = (U,V,E). p is the augmented pathbool find_augumented_path(x){ // 寻找以 x 为开始节点的增广路径 for(y in adjcency_lists(x)){ // 对 x 的邻接节点集合进行循环,y 作为循环变量。 if(y is not in the augmented path p){ // 如果节点 y 不在增广路径 p 内 add y into p; // 将节点 y 加入增广路 if(y is an unmatched vertex or find_augumented_path(x)){ //y 分为两种情况,第一种,y 是未匹配节点,那么直接把 y 加入增广路径 p。 // 第二种情况是 y 已经与某个 x' 匹配。这时候如果经过 x' 能够找到一条增广路径,那么就可以把 y 加入增广路径 p。 // 这里使用的是递归的思想 match(x,y); // 将 x 和 y 匹配。 return true; // 存在以 x 为起点的增广路径 } } } return false; // 不存在以 x 为起点的增广路径}int Hungary(){ int cnt = 0; for(x in set U){ if(find_augumented_path(x)) cnt++; // 注意,为了避免套娃情况,应当控制每个点每次循环只访问一次。可以使用状态数组记录访问状态。 } return cnt; // 返回最大匹配的边数}# KM (Kuhn–Munkres) Algorithm, KM 算法 The Hungarian maximum matching algorithm, also called the Kuhn-Munkres algorithm, is a O(V3)O(V^3)O(V3) algorithm that can be used to find maximum-weight matchings in bipartite graphs, which is sometimes called the assignment problem. KM 算法是匈牙利算法的扩展,可以在 O(V3)O(V^3)O(V3) 的复杂度内实现带权二分图的最大权值匹配(最优匹配)。一些分配问题也会被建模成带权二分图的最优匹配问题,以获得最大收益付出最小代价。 # prerequisite 前置知识 # vertex labeling 顶点标号 For each vertex we assign some number called a label lll , a feasible labeling satisfies the following condition: 我们为二分图的每一个顶点分配一个标号。当一个标号方案满足以下条件时,我们说,这个标号方案是可行的 l(x)+l(y)≥weight(x,y)l(x)+l(y)\\geq{\\rm weight}(x,y) l(x)+l(y)≥weight(x,y) In other words, the sum of the labels of the vertices on both sides of a given edge are greater than or equal to the weight of that edge. 换句话说,任意一边的权重小于等于其两侧顶点的标号之和。 # equality subgraph 相等子图 Let assume G′=(V,E′)G^\\prime=(V,E^\\prime)G′=(V,E′) is a spanning subgraph of GGG, where G′G^\\primeG′ includes all vertices from GGG. 记 G′G^\\primeG′ 是图 GGG 的生成子图(图 G′G^\\primeG′ 拥有图 GGG 的全部顶点和部分边) If in G′G^\\primeG′ , all of the edges E′E^\\primeE′ satisfy the following condition: l(x)+l(y)=weight(x,y)l(x)+l(y)={\\rm weight}(x,y) l(x)+l(y)=weight(x,y) Then we call G′G^\\primeG′ as an equality subgraph of GGG. 相等子图包含原图中所有的点,但只包含满足 l(x)+l(y)=weight(x,y)l(x)+l(y)={\\rm weight}(x,y)l(x)+l(y)=weight(x,y) 的所有弧 eee # algorithm outline 算法思想 initialize feasible vertex labeling: 初始化可行顶点标号: assume that x∈U,y∈V,{l(x)=max{w(x,y)},(x,y)∈El(y)=0\\text{assume that }x\\in U, y\\in V, \\begin{cases} \\begin{aligned} & l(x)=\\max\\{w(x,y)\\},(x,y)\\in E \\\\ & l(y)=0 \\end{aligned} \\end{cases} assume that x∈U,y∈V,{l(x)=max{w(x,y)},(x,y)∈El(y)=0 Try to find complete(maximum) matching MMM by using Hungarian algorithm in the equality subgraph. If there exists a complete matching in the equality subgraph, this complete matching must be the maximum perfect match. 尝试使用匈牙利算法寻找相等子图 G′G^\\primeG′ 的完全匹配 MMM。(如果相等子图存在完全匹配,那么这个完全匹配必定是最大权值匹配) If MMM does not exist, then update the vertex labeling to include others edges. The idea is to iterate alternating path and add all visited vertices on each side into sets SSS and TTT, then update the vertex labeling: 如果相等子图 G′G^\\primeG′ 不存在完全匹配 MMM(那么必定存在未匹配点)则更新顶点标号,以求包含更多的边。算法的核心思想是从某个未匹配点 uuu 开始,寻找交替路径。我们把 UUU 集合中属于交替路径的点叫做 SSS 集合, UUU 集合中不属于交替路径的点叫做 S′S^\\primeS′ 集合,把 VVV 集合中属于交替路径的点叫做 TTT 集合, VVV 集合中不属于交替路径的点叫做 T′T^\\primeT′ 集合。随后,根据以下规则更新结点标号: Δ=minx∈S,y∈T′{l(x)+l(y)−w(x,y)}l(v)={l(v)−Δ,if v∈Sl(v)+Δ,if v∈Tl(v),otherwise\\Delta = \\min_{x\\in S,y\\in T^\\prime}\\{l(x)+l(y)-w(x,y)\\} \\\\ l(v)= \\begin{cases} l(v)-\\Delta, & \\text{if }v\\in S\\\\ l(v)+\\Delta, & \\text{if }v\\in T\\\\ l(v), & \\text{otherwise} \\end{cases} Δ=x∈S,y∈T′min{l(x)+l(y)−w(x,y)}l(v)=⎩⎪⎪⎨⎪⎪⎧l(v)−Δ,l(v)+Δ,l(v),if v∈Sif v∈Totherwise update the equality subgraph. 更新相等子图 repeat step 2 and step 3, until we find complete matching. 重复步骤二和步骤三,直到我们找到完全匹配为止。所得的完全匹配就是所求的最优匹配(最大权值匹配)。 # TO DO 最小点覆盖问题 # References 参考资料 Bipartite checking using Graph Colouring and Breadth First Search (BFS) O(V+E) time (opengenus.org) Hungarian algorithm - Wikipedia Hungary algorithm learning - Programmer All Perfect Matching -- from Wolfram MathWorld [Hungarian Algorithm II - KM(Kuhn–Munkres) Algorithm| Yasen Hu](https://yasenh.github.io/post/hungarian-algorithm-2/#:~:text=KM(Kuhn–Munkres) algorithm provides the connection between equality subgraphs,then %24M^*%24 is a maximum-weighted matching in %24G%24.) (1 条消息) 图论(16)匈牙利算法与最优匹配算法_罗古洞的女婿的博客 - CSDN 博客_最优匹配算法 lecture6f.pdf (ethz.ch) Kuhn-Munkres 算法详细解析 | Sengxian's Blog","categories":[{"name":"计算机科学","slug":"computer-science","permalink":"http://blog.sunforge.cn/categories/computer-science/"},{"name":"数据结构与算法","slug":"computer-science/数据结构与算法","permalink":"http://blog.sunforge.cn/categories/computer-science/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E4%B8%8E%E7%AE%97%E6%B3%95/"},{"name":"图论","slug":"computer-science/数据结构与算法/图论","permalink":"http://blog.sunforge.cn/categories/computer-science/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E4%B8%8E%E7%AE%97%E6%B3%95/%E5%9B%BE%E8%AE%BA/"}],"tags":[{"name":"笔记","slug":"笔记","permalink":"http://blog.sunforge.cn/tags/%E7%AC%94%E8%AE%B0/"}]},{"title":"数据结构与算法:索引","slug":"computer-science/data-structures-and-algorithms/index","date":"2022-09-26T14:44:27.000Z","updated":"2022-10-18T12:44:06.632Z","comments":true,"path":"computer-science/data-structures-and-algorithms/index/","link":"","permalink":"http://blog.sunforge.cn/computer-science/data-structures-and-algorithms/index/","excerpt":"","text":"# Data Structures and Algorithms 数据结构与算法 # References 参考资料 # Contents 目录 图论 二分图及相关算法 # Tips 提示","categories":[],"tags":[]},{"title":"强化学习:索引","slug":"computer-science/reinforcement-learning/index","date":"2022-09-22T16:09:02.000Z","updated":"2022-10-18T12:44:06.664Z","comments":true,"path":"computer-science/reinforcement-learning/index/","link":"","permalink":"http://blog.sunforge.cn/computer-science/reinforcement-learning/index/","excerpt":"","text":"# References 参考资料 参考书下载可以访问 z-library 下载","categories":[{"name":"计算机科学","slug":"computer-science","permalink":"http://blog.sunforge.cn/categories/computer-science/"},{"name":"强化学习","slug":"computer-science/强化学习","permalink":"http://blog.sunforge.cn/categories/computer-science/%E5%BC%BA%E5%8C%96%E5%AD%A6%E4%B9%A0/"}],"tags":[{"name":"笔记","slug":"笔记","permalink":"http://blog.sunforge.cn/tags/%E7%AC%94%E8%AE%B0/"}]},{"title":"凸优化第一章:导论","slug":"fundamental/math/convex-optimization/Chapter-1-introduction","date":"2022-09-15T08:21:58.000Z","updated":"2022-10-18T12:44:06.664Z","comments":true,"path":"fundamental/math/convex-optimization/Chapter-1-introduction/","link":"","permalink":"http://blog.sunforge.cn/fundamental/math/convex-optimization/Chapter-1-introduction/","excerpt":"","text":"# Mathematical Optimization 数学优化问题 # Definition 定义 A mathematical optimization problem, or just optimization problem, has the form: 数学优化问题,也称最优化问题,有如下的形式: \\begin{equation}\\tag{1.1} \\label{eq1.1} \\begin{aligned} & {\\rm minimize}\\quad f_0(x) \\\\ & {\\rm subject~to}\\quad f_i(x) \\le b_i~(i = 1,\\cdots, m) \\end{aligned} \\end{equation} the vector x=(x1,⋯ ,xn)∈Rnx = (x_1,\\cdots, x_n)\\in \\mathbb R^nx=(x1,⋯,xn)∈Rn is the optimization variable of the problem. 向量 xxx 是优化变量。 the function f0:Rn→Rf_0:\\mathbb R^n\\rightarrow\\mathbb Rf0:Rn→R is the objective function. 函数 f0f_0f0 是目标函数。 the functions fi:Rn→R,i=1,2,⋯ ,mf_i:\\mathbb R^n\\rightarrow\\mathbb R,\\quad i=1,2,\\cdots, mfi:Rn→R,i=1,2,⋯,m , are the inequality constraint functions. 函数 fif_ifi 是不等式约束。 the constants b1,b2,⋯ ,bmb_1, b_2, \\cdots, b_mb1,b2,⋯,bm are the limits, or bounds, of the constraints. 常量 b1,b2,⋯ ,bmb_1, b_2, \\cdots, b_mb1,b2,⋯,bm 是上述不等式约束的边界。 A vector x⋆x^\\starx⋆ is called optimal or a solution of the problem, if it has the smallest objective value among all vectors satisfy the constraints: for any zzz with f1(z)≤b1,⋯fm(z)≤bmf_1(z)\\le b_1,\\cdots f_m(z)\\le b_mf1(z)≤b1,⋯fm(z)≤bm , we have f0(z)≥f0(x⋆)f_0(z)\\ge f_0(x^\\star)f0(z)≥f0(x⋆). 如果向量 x⋆x^\\starx⋆ 满足,对于任意一个符合约束条件 f1(z)≤b1,⋯fm(z)≤bmf_1(z)\\le b_1,\\cdots f_m(z)\\le b_mf1(z)≤b1,⋯fm(z)≤bm 的向量 zzz 而言,不等式f0(z)≥f0(x⋆)f_0(z)\\ge f_0(x^\\star)f0(z)≥f0(x⋆) 始终成立,那么我们将 x⋆x^\\starx⋆ 称作该优化问题的一个最优解。 # Classification 分类 the optimization problem \\eqref{eq1.1} is called a linear program if the objective and constraint functions f0,⋯ ,fmf_0, \\cdots, f_mf0,⋯,fm are linear, i.e., satisfy \\begin{equation} \\tag{1.2} \\label{eq1.2} f_i(\\alpha x+\\beta y) = \\alpha f_i(x)+ \\beta f_i(y) \\end{equation} for all x,y∈Rnx, y\\in\\mathbb R^nx,y∈Rn and all α,β∈R\\alpha,\\beta\\in\\mathbb Rα,β∈R. If the optimization problem is not linear, it is called a nonlinear program. 如果目标函数 f0f_0f0 和不等式约束 f1,⋯ ,fmf_1,\\cdots,f_mf1,⋯,fm 都是线性的,即对任意的 x,y∈Rn and α,β∈Rx,y\\in\\mathbb R^n {\\rm ~and~} ~\\alpha,\\beta\\in\\mathbb Rx,y∈Rn and α,β∈R 满足公式 \\eqref{eq1.2},那么公式 \\eqref{eq1.1} 代表的优化问题,就是一个线性优化问题(线性规划)。 如果这个优化问题不是线性的,那么就称作非线性优化问题(非线性规划)。 # Applications 应用 The optimization problem \\eqref{eq1.1} is an abstraction of the problem of making the best possible choice of a vector in Rn\\mathbb R^nRn from a set of candidate choices. 优化问题可以看做在向量空间 Rn\\mathbb R^nRn 中的一组备选解中选择最优解。 The variable xxx represents the choice made. 变量 xxx 代表备选解。 the constraints fi(x)≤bif_i(x) \\le b_ifi(x)≤bi represent firm requirements or specifications that limit the possible choices. 不等式约束 fi(x)≤bif_i(x) \\le b_ifi(x)≤bi 是变量 xxx 必须满足的约束条件。 the objective value f0(x)f_0(x)f0(x) represents the cost of choosing xxx. (We can also think of −f0(x)-f_0(x)−f0(x) as representing the value, or utility, of choosing xxx.) 目标函数 f0(x)f_0(x)f0(x) 表示选择 xxx 的成本(代价)。同理,我们也可以认为 −f0(x)-f_0(x)−f0(x) 是选择 xxx 所获得的收益。 A solution of the optimization problem \\eqref{eq1.1} corresponds to a choice that has minimum cost (or maximum utility), among all choices that meet the firm requirements. 优化问题 \\eqref{eq1.1} 的解,就是满足约束条件的备选解中,代价最小(或者说收益最大)的那一个。 # portfolio optimization 投资组合优化 # device sizing in electronic design 电子设计中的器件尺寸问题 # data fitting 数据拟合 # Convex Optimization 凸优化 # background 背景阐述 Convex Optimization is just a subfiled of mathematical optimization problem. A convex optimization problem is one in which the objective function and constraint functions are convex, which means they satisfy the inequality: \\begin{equation}\\tag{1.3}\\label{eq1.3} f_i(\\alpha x+\\beta y) \\le \\alpha f_i(x)+ \\beta f_i(y) \\end{equation} for all x,y∈Rnx, y\\in\\mathbb R^nx,y∈Rn and all α,β∈R\\alpha,\\beta\\in\\mathbb Rα,β∈R with α+β=1, α≥0, β≥0\\alpha+\\beta=1,~\\alpha\\ge0,~\\beta\\ge0α+β=1, α≥0, β≥0 凸优化问题是数学优化问题的一个子领域。在凸优化问题中,目标函数和不等式约束条件都是凸函数。也就是说,对于任意的 x,y∈Rnx, y\\in\\mathbb R^nx,y∈Rn 和任意的 α,β∈R\\alpha,\\beta\\in\\mathbb Rα,β∈R 且满足 α+β=1, α≥0, β≥0\\alpha+\\beta=1,~\\alpha\\ge0,~\\beta\\ge0α+β=1, α≥0, β≥0 时,不等式 \\eqref{eq1.3} 成立。 Comparing \\eqref{eq1.2} and \\eqref{eq1.3} , we see that convexity is more general than linearity: inequality replaces the more restrictive equality, and the inequality must hold only for certain values of α\\alphaα and β\\betaβ. 比较 \\eqref{eq1.2} 和 \\eqref{eq1.3} 两式,我们可以看出,凸性是比线性更加普遍、更加一般的性质。线性函数需要严格满足等式,而凸函数仅仅需要在 α\\alphaα 和 β\\betaβ 取特定值的情况下满足不等式就可以。 Since any linear program is therefore a convex optimization problem, we can consider convex optimization to be a generalization of linear programming. 因此线性规划问题也是凸优化问题,我们可以将凸优化看成是线性规划的推广。 Since the late 1940s, a large effort has gone into developing algorithms for solving various classes of optimization problems, analyzing their properties, and developing good software implementations. 从 20 世纪 40 年代后期开始,学者们致力千设计算法求解多类优化问题,分析这些算法的性质以及进行软件实现。 Even when the objective and constraint functions are smooth (for example, polynomials) the general optimization problem \\eqref{eq1.1} is surprisingly difficult to solve. Approaches to the general problem therefore involve some kind of compromise, sucha s very long computation time, or the possibility of not finding the solution. 即使目标函数和约束函数是光滑的 (如多项式),优化问题 \\eqref{eq1.1} 仍然很难求解。我们在解优化问题时,需要付出一些代价,例如可能会耗费很多的时间,甚至可能会找不到解。 There are, however, some important exceptions to the general rule that most optimization problems are difficult to solve. For a few problem classes we have effective algorithms that can reliably solve even large problems, with hundreds or thousands of variables and constraints. Two important and well known examples are least-squares problems and linear programs. 也并不是所有的优化问题都很难解。对于一些特殊的优化问题,存在一些十分有效的算法。这些算法甚至能够解决含有上千个变量或约束的优化问题。最小二乘问题和线性规划问题是其中两类最重要也最广为人知的算法。 Like least-squares or linear programming, there are very effective algorithms that can reliably and efficiently solve even large convex problems. 正如最小二乘法和线性规划法一样,存在有效的算法可靠求解大规模凸优化问题。 # least-squaers problem 最小二乘问题 A least-squares problem is an optimization problem with no constraints (i.e., m=0m = 0m=0) and an objective which is a sum of squares of terms of the form aiTx−bia^T_i x - b_iaiTx−bi: 最小二乘问题是一类没有约束条件的优化问题(公式 \\eqref{eq1.1} 中,mmm 的取值为 000),它的目标函数是若干项的平方和 ,每一项具有形式aiTx−bia^T_i x - b_iaiTx−bi, 具体形式如下: \\begin{equation} \\tag{1.4}\\label{eq1.4} {\\rm minimize\\quad}f_0(x)=||Ax-b||_2^2=\\sum_{i=1}^k(a^T_ix-b_i) \\end{equation} Here A∈Rk×mA\\in\\mathbb R^{k\\times m}A∈Rk×m (with k≥mk\\geq mk≥m), aiTa^T_iaiT are the rows of AAA, and the vector x∈Rnx \\in \\mathbb R^nx∈Rn is the optimization variable. 其中,aiTa^T_iaiT 是矩阵 Ak×m,(k≥m)A_{k\\times m},(k\\ge m)Ak×m,(k≥m) 的行向量 ,向量 x∈Rnx\\in\\mathbb R^nx∈Rn 是优化变量。 # solving least-squares problems 求解最小二乘问题 The solution of a least-squares problem \\eqref{eq1.4} can be reduced to solving a set of linear equations, 最小二乘的求解可以化为以下问题 (ATA)x=ATb(A^TA)x=A^Tb (ATA)x=ATb so we have the analytical solution x=(ATA)−1ATbx = (A^T A)^{-1}A^T bx=(ATA)−1ATb 由此,我们得到 xxx 的一个解析解 x=(ATA)−1ATbx = (A^T A)^{-1}A^T bx=(ATA)−1ATb。 we have good algorithms (with software applications) for solving the least-squares problems to high accuracy, with very high reliablity in a time approximately proportional to kn2kn^2kn2, with a known constant. Algorithms and software for solving least-squares problems are reliable enough for embedded optimization. 我们有不少出色的算法能够精确可靠地在 kn2kn^2kn2 的时间复杂度内求解最小二乘问题(其中,kkk 是已知的常数),能应用到嵌入式优化领域。 A current desktop computer can solve a least-squares problem with hundreds of variables, and thousands of terms, in a few seconds. 现有的台式机可以在几秒内解决具有成百上千个变量或求和项的最小二乘问题。 In many cases we can solve even larger least-squares problems, by exploiting some special structure in the coefficient matrix A, for example a sparse matrix. 如果矩阵 AAA 具有某些特殊的结构(比如矩阵 AAA 是稀疏矩阵),那么我们甚至可以解决更大规模的最小二乘问题。 For extremely large problems (say, with millions of variables), or for problems with exacting real-time computing requirements, solving a least-squares problem can be a challenge. But in the vast majority of cases, we can say that existing methods are very effective, and extremely reliable. 求解超大规模最小二乘问题和那些需要实时求解的最小二乘问题有一定的难度。但在大部分应用中,最小二乘问题依然可以被有效、可靠地求解。 # using large-squares 最小二乘问题应用 The least-squares problem is the basis for regression analysis, optimal control, and many parameter estimation and data fitting methods. It has a number of statistical interpretations, e.g., as maximum likelihood estimation of a vector xxx, given linear measurements corrupted by Gaussian measurement errors. 最小二乘问题是回归分析、最优控制和多参数估计与数据拟合的基础。最小二乘问题有很多统计意义,例如,给定包含高斯噪声的线性测量值时,向量 xxx 的最大似然估计即等价于最小二乘问题的解。 Recognizing an optimization problem as a least-squares problem is straightforward; we only need to verify that the objective is a quadratic function (and then test whether the associated quadratic form is positive semidefinite). 判断一个优化问题是否是最小二乘问题非常简单;只需要检验目标函数是否是二次函数(然后检验此二次函数是否半正定)即可。 In weighted least-squares, the weighted least-squares cost 在加权最小二乘中,最小化的加权二乘成本是 ∑i=1kwi(aiTx−bi)2\\sum_{i=1}^k w_i(a_i^Tx-b_i)^2 i=1∑kwi(aiTx−bi)2 where w1,⋯ ,wkw1,\\cdots,w_kw1,⋯,wk are positive, is minimized. (This problem is readily cast and solved as a standard least-squares problem.) 其中,加权系数 w1,⋯ ,wkw1,\\cdots,w_kw1,⋯,wk 均大于 000 (加权最小二权问题可以很方便转化为普通的最小二乘问题进行求解) Here the weights wiw_iwi are chosen to reflect differing levels of concern about the sizes of the terms aiTx−bia^T_i x - b_iaiTx−bi, or simply to influence the solution. 在加权最小二乘问题中,权重 wiw_iwi 代表求和项 aiTx−bia^T_i x - b_iaiTx−bi 的重要程度,或这个求和项对于解的影响程度。 # to be continued 未完待续","categories":[{"name":"基本法则","slug":"基本法则","permalink":"http://blog.sunforge.cn/categories/%E5%9F%BA%E6%9C%AC%E6%B3%95%E5%88%99/"},{"name":"数学","slug":"基本法则/数学","permalink":"http://blog.sunforge.cn/categories/%E5%9F%BA%E6%9C%AC%E6%B3%95%E5%88%99/%E6%95%B0%E5%AD%A6/"},{"name":"凸优化","slug":"基本法则/数学/凸优化","permalink":"http://blog.sunforge.cn/categories/%E5%9F%BA%E6%9C%AC%E6%B3%95%E5%88%99/%E6%95%B0%E5%AD%A6/%E5%87%B8%E4%BC%98%E5%8C%96/"}],"tags":[{"name":"笔记","slug":"笔记","permalink":"http://blog.sunforge.cn/tags/%E7%AC%94%E8%AE%B0/"}]},{"title":"凸优化:索引","slug":"fundamental/math/convex-optimization/index","date":"2022-09-12T08:10:19.000Z","updated":"2022-10-18T12:44:06.668Z","comments":true,"path":"fundamental/math/convex-optimization/index/","link":"","permalink":"http://blog.sunforge.cn/fundamental/math/convex-optimization/index/","excerpt":"","text":"# Convex Optimization 凸优化 # References 参考资料 由于研究需要,学习凸优化,做些笔记作为记录,方便复习和查阅。参考书如下。 Convex Optimization 凸优化 Author 作者:Boyd and Vandenberghe (Stanford University) 参考书下载可以访问 z-library 下载 # Contents 目录 Chapter 1: Introduction 第一章:引言 # Tips 提示 本系列博客为书本笔记","categories":[{"name":"基本法则","slug":"基本法则","permalink":"http://blog.sunforge.cn/categories/%E5%9F%BA%E6%9C%AC%E6%B3%95%E5%88%99/"},{"name":"数学","slug":"基本法则/数学","permalink":"http://blog.sunforge.cn/categories/%E5%9F%BA%E6%9C%AC%E6%B3%95%E5%88%99/%E6%95%B0%E5%AD%A6/"},{"name":"凸优化","slug":"基本法则/数学/凸优化","permalink":"http://blog.sunforge.cn/categories/%E5%9F%BA%E6%9C%AC%E6%B3%95%E5%88%99/%E6%95%B0%E5%AD%A6/%E5%87%B8%E4%BC%98%E5%8C%96/"}],"tags":[{"name":"笔记","slug":"笔记","permalink":"http://blog.sunforge.cn/tags/%E7%AC%94%E8%AE%B0/"}]},{"title":"Chapter 5 The Network Layer: Control Plane","slug":"computer-science/computer-networks/Chapter-5-The-Network-Layer-Control-Plane","date":"2022-09-11T05:06:32.000Z","updated":"2022-10-18T12:44:06.632Z","comments":true,"path":"computer-science/computer-networks/Chapter-5-The-Network-Layer-Control-Plane/","link":"","permalink":"http://blog.sunforge.cn/computer-science/computer-networks/Chapter-5-The-Network-Layer-Control-Plane/","excerpt":"","text":"# 网络层:控制平面 # 路由协议 路由协议的目标:确定发送主机到接收主机之间,通过路由器的网络 “较好” 的路径(路径,即经过的路由器序列)。 路由问题是网络中十大关键问题之一。 路由:按照某种指标(譬如传输延迟、经过的跳数等),找到一条从源结点到目标结点的较好的路径。 衡量的指标还可以是:费用、队列长度等。 通常是源子网到目标子网,如果是源主机到目标主机,这个代价太大了。 路由器与路由器之间的最优路径 = 主机对之间的最优路径 (子网内,主机到路由器之间只需要一跳,通常都不需要路由器) 网络的图抽象:图论算法 路由器结点集合 链路边集合 每一边有代价 最优化原则:最终目是为所有路由器找到并使用汇集树(汇集树是此节点到所有其他节点最优路径形成的树。类似 dijkstra 算法的树) 路由选择的原则: 正确性:算法必须是正确、完整的。分组要通过路由器一站一站接力,然后发送到目标主机。所有的目标地址,都能在路由表中找到对应表项,没有处理不了的目标站地址。 简单性:算法在计算机上应该简单。最优但是复杂的算法,会产生很大延时,不实用。不应该为了获取路由信息,增加很多通信量。 健壮性:算法能适应通信量和网络拓扑的变化,通信量变化,网络拓扑算法的变化算法可以很快适应。不向很拥挤的链路发展。不向断了的链路发送数据。 路由选择算法的原则: 稳定性:产生的路由不应该摇摆 公平性:对每一个站点都公平 最优性:我们追求某一个指标上的最优。但实际上达到最优的代价较高,可以是次优的。 路由选择算法的分类: 全局路由:所有路由器都有完整的拓扑和边的代价信息。 link state 算法。 分布式路由:路由器只知道与它有物理连接关系的邻居路由器,以及到相应邻居路由器的代价值。迭代地与邻居交换路由信息,计算路由信息。 distance vector 算法。 静态路由:路由随着时间变化慢(几乎不变) 动态路由:路由变化快。周期性变化,根据链路代价变化而变化。 LS 路由的工作过程:链路状态算法(其实是迪杰斯特拉算法) 通过各种渠道获得整个网络拓扑和网络的整个代价信息。(这部分是泛洪的方法,和路由算法无关) 发现相邻结点,获知对方的网络地址 测量到相邻结点的代价(延迟,开销) 组装一个 LS 分组,描述它到相邻接点的代价情况。 将分组通过扩散的方式发送到所有路由器。 然后运行链路状态算法(迪杰斯特拉算法),找出最短路径,形成路由表。 泛洪可能出现广播风暴问题。这种泛洪是有确认的泛洪,收到了必须给一个确认回传。 链路状态路由选择的符号标记 c(i,j) 从节点 i 到节点 j 的链路代价。初始状态下,所有非相邻结点的代价都是 ∞ D(v) 从源节点到节点 V 的当前路径代价(节点的代价) P(v) 从源节点到节点 V 的路径前序节点 N' 当前已经知道最优路径的节点的集合(永久节点的集合) 链路状态路由选择算法的工作过程(迪杰斯特拉算法工作过程) 然后产生了汇集树。即路由表。可以采用最小堆优化算法,得到 n·logn 的复杂度。 可能会造成路径的震荡情况。(可能路径会发生拥塞) DV 路由算法: 每个节点维护一张路由表(可到目标的列表) destination next hop cost A Z 14 目的地址和下一跳地址都用网络号和子网掩码代表,并记录代价 cost 相邻的两个节点,要定期或根据某事件触发,交换所谓的距离矢量。动态规划算法。 ** 如何获取代价以及相邻节点间的代价?** 通过实测和其他路由节点的通告获得 距离矢量算法,遵循 Bellman-Ford 方程(属动态规划) 设dx(y)d_{x}(y)dx(y) 是从 x 到 y 的最小路径代价 取 v 是 x 的邻居节点,那么dx(y)=min∀v{c(x,v)+dv(y)}d_{x}(y)=\\min\\limits_{\\forall v}\\{c(x,v)+d_{v}(y)\\}dx(y)=∀vmin{c(x,v)+dv(y)} 异步式:迭代。每次本地迭代被以下事件触发(本地链路代价变化,从邻居发来了更新消息) 分布式:每个结点只是在自己的 DV 改变后,向邻居通告(然后邻居在有必要的时候,通知自己的邻居) **DV 算法的特点:** 好消息传的快,坏消息传的慢(无穷计算问题) A 与 B 相连,B 与 C 相连,C 与其他相连。 A 与 B 的连接,会被 B 传递给 C。当 A 与 B 断掉的时候。B 测 A 时,发现不可达,但 B 经过 C 发现,C 与 A 可达。(由于信息更新的滞后,所以 C 还认为 A 可达)如果 AB 断掉,这时 C 又传可达,就把 B 给骗了 这样就形成了局部的环路。这时候只能通过 TTL 的机制(每过一个路由器 - 1)才能说明不可达。 如何规避这种无穷计算的问题?采用水平分裂(split horizon)算法 比如有 A-B-C-D 这一条链。当 AB 断裂时。C 对于 B 保持谦虚,声称不可达。但 C 对 D 说实话,告诉真实的代价。 这里的逻辑是: 向 A 传输信息时,B 是 C 的权威,C 要经过 B 才能达到 A,而 C 是 D 的权威,D 要经过 C 才能到 A。 C 对 B 保持谦虚(C 传给 B 无穷大,说到不了)实际上,就是告诉 B,我 C 这边只有通过你 B 才能到达 A。 这时候,如果 B 发现,我到不了 A(因为 AB 断了),B 就能立马清醒,而不至于陷入局部环路的无穷计算。 这样一来,坏消息就能很快传递过去。水平分裂在环装拓扑中不好用,水平分裂算法不能避免,只能减缓 LS 算法和 DV 算法比较 性能 LS 算法 DV 算法 消息复杂度 有 n 个节点,E 条链路,发送报文On(E)O_{n}(E)On(E) 个,局部的路由信息,全局传播 只和邻居交换路由信息,全局的路由信息,局部传播。胜出,能传输的消息比较多 收敛时间 O(n2)O(n^{2})O(n2) 的复杂度,有可能有震荡。胜出,收敛较快 收敛较慢,可能存在路由环路。存在 count-to-infinity 问题。 健壮性 节点可能通告不正确的链路代价。但每个节点只计算自己的路由表,错误信息影响较小。胜出,比较健壮 路由器可能通告对全网所有节点的不正确路由代价。每个节点的路由表可能被其他节点使用(错误可以扩散到全网) 各有优缺点,在互联网上都有应用。 # 自治系统内部的路由选择 1. RIP (Routing Information Protocol) 基于距离矢量算法 1982 年在 BSD-UNIX 上实现,所关注的代价就是跳数。 跳数最大是 15,如果超出(比如 16)就是不可达 DV 每 30 秒与邻居交换路由矢量。称作通告。每个通告,最多包括 25 个目标子网。当然,如果主机请求 DV 信息,会直接通告。 只适合小网络。代价小,简单,易维护。 以守护进程的形式来实现;传输采用 UDP 报文。周期性重复。 RIP 进程实现了网络功能(以进程的方式,实现了网络层的功能,为了实现网络层的功能,借助了传输层的协议来发路由通告) 2. OSPF (Open Shortest Path First) 协议 基于链路状态算法 标准公开。链路状态分组在全网泛洪。每个节点拿到全网拓扑,然后计算汇集树,装载路由表。 路由通告携带,源 IP,版本号,TTL,以及我的邻居和到这些邻居的代价等。 OSPF 的高级特性: 安全:所有报文经过认证,防止恶意攻击 允许多个代价相同的路径存在,可以负载均衡(RIP 中只允许一个) 对于每一个链路,允许多重代价(按照跳数、延迟等)有一个多重代价矩阵。支持按照多种指标,计算最优路径。方便网络管理员使用。 对单播和多播的继承支持。使用相同的拓扑数据库,就像在 OSPF 中一样。 大型网络中支持层次化的 OSPF(分为骨干区域和普通区域) 未完待续 ......","categories":[{"name":"计算机科学","slug":"computer-science","permalink":"http://blog.sunforge.cn/categories/computer-science/"},{"name":"计算机网络","slug":"computer-science/计算机网络","permalink":"http://blog.sunforge.cn/categories/computer-science/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/"}],"tags":[{"name":"笔记","slug":"笔记","permalink":"http://blog.sunforge.cn/tags/%E7%AC%94%E8%AE%B0/"}]},{"title":"Chapter 4 The Network Layer: Data Plane","slug":"computer-science/computer-networks/Chapter-4-The-Network-Layer-Data-Plane","date":"2022-09-11T05:06:14.000Z","updated":"2022-10-18T12:44:06.632Z","comments":true,"path":"computer-science/computer-networks/Chapter-4-The-Network-Layer-Data-Plane/","link":"","permalink":"http://blog.sunforge.cn/computer-science/computer-networks/Chapter-4-The-Network-Layer-Data-Plane/","excerpt":"","text":"# 网络层:数据平面 网络层服务: 在发送主机和接收主机对之间传送段 Segment 在发送端,将段封装到数据报中 在接收端,将段交给上层传输层实体 网络层协议存在于每一个主机和路由器 路由器检查每一个经过它的 IP 数据报的头部 网络层包含: 路由协议,IP 协议,ICMP 协议(属于信令协议,可以报告错误) 网络层的关键功能: 转发(局部功能,数据平面):分组从路由器的输入接口转发到合适的输出接口。 路由(全局功能,控制平面):源主机到目标主机的路径。 1. 数据平面和控制平面: 数据平面: 是本地的,路由器的功能。 决定从路由器的输入端口到达的分组,如何转发到输出端口。 转发功能: 传统方式:基于目标地址 + 转发表 SDN 方式:基于多个字段 + 流表 控制平面: 网络范围内的逻辑 决定数据如何在路由器之间路由。决定源主机到目标主机之间的端到端路径。 2 个控制平面方法 传统的路由算法:在路由器中被实现 software-defined networking (SDN) 在远程的服务器中被实现 传统方式:每一路由器控制平面(紧耦合,既实现控制平面功能,又实现数据平面的功能,分布式算路由表,交给 IP 路由实体,然后匹配交换转发)在一种设备上实现,但这种紧耦合,全球那么多设备,改不了。有僵化的问题。 SDN 方式:逻辑集中的控制平面(可编程)。一个不同的(通常是远程的)控制器与本地控制代理(CAs)交互。控制代理向控制器上报设备状况,由控制器计算流表,然后下发给控制代理。各设备对流表进行装载后,对到来的分组作多字段匹配,然后进行操作。 2. 网络服务模型: 思考一个问题:从发送方主机到接收方主机传输数据报的通道 “通道”,网络提供什么样的服务模型? 对于单个数据报的服务: 可靠传输 延迟保证(如少于 40ms 的延迟) 对于数据报流的服务: 保序数据报传输 保证流的最小带宽 分组之间的延迟差(jitter) 网络架构 服务模型 带宽保证 能否不丢失 是否保序 能否低延迟 拥塞反馈 Internet (IP) best effort 不保证 不保证 不保证 不保证 no (inferred via loss) ATM CBR 恒定速率 constant rate 保证 保证 保证 no congestion ATM VBR 变化速率 guaranteed rate 保证 保证 保证 no congestion ATM ABR 可用比特率 guaranteed minimum 不保证 保证 不保证 yes ATM UBR 不指名比特率 不保证 不保证 保证 不保证 no 尽力而为是委婉的称谓。看起来声势很大,但是啥都不保证。 3. 连接建立: 是第三个重要功能。 如 ATM 网络、 在分组传输之前,在两个主机之间,在通过一些路由器构成的路径上面,建立一个网络层连接 涉及到的路由器 网络层和传输层连接服务的区别: 网络层:在 2 个主机之间,涉及到路径上的一些路由器 传输层:在 2 个进程之间,很可能只体现在端系统上(TCP 连接) # 路由器的组成 路由器结构概况: 高层面的(非常简化的)通用路由器体系架构: 路由:运行路由选择算法 / 协议(RIP, OSPF, BGP)生成路由表 转发:从输入到输出链路交换数据报,根据路由表进行分组的转发 SDN 的路由器,根据流表与分组的头部进行匹配,然后按照表项的 action 对分组做动作。可以编程,控制流表的内容 输入端口功能: 物理层:bit 级的接收 数据链路层:链路层协议动作、解封装 网络层:有一个队列(输入端口缓存) 分布式交换: 根据数据报头部信息,如目的地址,在输入端内存中的转发表中查找合适的输出端口(匹配 + 行动) 基于目标的转发:仅仅依赖于 IP 数据报的目标 IP 地址(传统方法) 通用转发:基于头部字段的任意集合进行转发 输入端口缓存: 当交换机构的速率小于输入端口的汇聚速率时,在输入端口可能需要排队。 会产生排队延迟 若输入缓存溢出也可能造成丢失 Head-of-the-Line (HOL) blocking: 排在对头的数据报阻止了队列中其他数据报向前移动。 交换结构: 将分组从输入缓冲区传输到合适的输出端口 交换速率:分组可以按照该速率从输入传输到输出 运行速度经常是输入 / 输出链路速率的若干倍 N 个输入端口,交换机构的交换速率是输入线路速度的 N 倍,比较理想,这样才不会成为瓶颈。 三种典型的交换机构 基于 memory(内存)第一代路由器 在 CPU 控制下的直接交换,采用传统的计算机。 分组被拷贝到系统内存,CPU 从分组的头部提取目标地址,查找转发表,找到对应输出端口,拷贝到输出端口。 转发速率被内存的带宽限制(数据报会通过 BUS 两次) 一次只能转发一个分组 基于 bus(总线)第二代路由器 数据报通过共享总线,从输入端口转发到输出端口, 总线竞争:交换速度受限于总线带宽 一次处理一个分组 1 Gbps bus, Cisco 1900; 32 Gbps bus, Cisco 5600 对于接入或企业级路由器,速度足够,但不适合区域或骨干网络。 基于 crossbar(纵横互联网路) 可以同时并发发送多个分组,克服了总线带宽的限制。 Banyan(榕树)网路,crossbar(纵横)和其他的互联网络被开发,将多个处理器连接成多处理器。 当分组从端口 A 到达,转给端口 Y,则控制器短接两个相应的总线。 高级设计:将数据报分片为固定长度的信元,通过交换网络交换 Cisco12000:以 60Gbps 的交换速率通过互联网络 输出端口: 当数据从交换机构到达的速率比传输速率快,就需要输出端口缓存。(数据报或分组可能会被丢弃,由于拥塞,缓冲区可能没有空间) 由调度规则,选择排队的数据报进行传输(优先权调度,谁会获得最优性能,网络中立?) 输出端口排队: 可能有多打一的情况发生,所以要排队。 需要有一个队列,来平衡速度。 排队会带来延迟。输出端口缓存溢出,则会丢失数据。 调度机制: 1. 先来先服务策略:按照分组道来的次序服务 队列满时,分组的丢弃策略: tail drop 丢弃刚刚到达的分组 priority 根据优先权丢失 / 移动分组 random 随机地丢弃 / 移除 2. 优先权调度:发送最高优先权的分组。多种类型,不同类型,有不同的优先权。 3. 其他调度类型: round robin(RR),循环扫描不同类型的队列,发送完一类的一个分组,再发送下一类的一个分组。 Waited Fair Queue(WFQ),加权平均队列,在一段时间内,每个队列得到的服务时间和权重成正比。每个类在每一个循环中,获得不同权重的服务量。 # IP Protocol 数据报格式: 20 字节的头部。 4 字节: ver (4 bits) 版本号(这里讨论的是 IPv4 的数据报格式)0100 就是 4 head len (4 bits) 头部的长度(以四个字节为单位,其中固定头部 20 字节,可能携带 options 部分)最少是 0011,即 5 * 4 = 20 字节 type of service (16 bits) 基本废弃不用了,表示载荷的类型,作为分组调度的依据。 length (32 bits) 数据报总长 4 字节:分片和重组时使用 identifier (16 bits) 标识 grag flag (4 bits) 标志位 fragment offset (12 bits) 段的偏移量 4 字节: time to live (TTL) (8 bits) 每过一个路由器减 1,减为 0 的时候,丢弃分组。然后向源主机发送一个 ICMP 的错误报告。 upper layer (8 bits) 指定上层协议,交给 TCP / UDP / ICMP / 其他 internet checksum (16 bits) 头部校验和,和 UDP 的校验和计算类似。判断分组的头部有没有出问题。 8 字节: source IP address (32 bits) destination IP address (32bits) Options (if any) 可变长。 著名的 options 有交换节点 ip 列表 一般没有 option IP 分片和重组: 网络链路层存在 MTU(最大传输单元)限制,MTU 是链路层的帧所携带的最大数据长度。 不同的链路类型,有不同的 MTU 大的 IP 数据报,在网络上被分片 (fragmented)。 一个大数据报,被分片成若干个小的数据报:头部复制,body 拆分 相同的 ID 不同的偏移量(偏移量,以 8 字节,即 8B 为单位) 最后一个分片,frag flag 标志位为 0,否则为 1 重组只在目标主机进行。若在路由器重组,会存在几个问题: 路由表变化,可能不经过某个路由器了 等待所有分组到达路由器,会耽误该分组和其他分组的传输(会耽误正常工作) IP 头部的信息用来标识、排序相关分片。 如果超时定时器内,分片有一些没到,那么已到的也要全部丢弃。 IP 编址:IP 地址,标识设备的网络接口(是设备和网络交互的那个点) IPv4: 用 32 bits 表示 接口:主机 / 路由器和物理链路的连接处 路由器有多个接口(必有多个接口) 主机也可能有多个接口(一般一个,可以多个) 一个 IP 地址,和一个接口关联。 ** 接口是如何连接的?** 后续学习,目前无需担心一个接口是如何转接到另一个接口的。 子网:IP 地址:子网部分(高位 bits),主机部分(低位 bits) ** 什么是子网?** 一个子网内的节点(主机或者路由器)他们的 IP 地址高位部分相同。这些地址构成的网络的一部分叫做子网。无需路由器接入,子网内的各个主机可以在物理上相互直接到达(IP 分组一跳可达)。 ** 子网如何判断?** 要判断一个子网,将每一个接口从主机或者路由器上分开,构成一个个网络 “孤岛”,每一个孤岛都称为子网 subnet 可能发生子网聚集,对外可以宣称我们属于一个子网。我可以对外宣称在同一个子网,但是我们不关心这个子网内部有没有再细分为更小的子网(纯子网,非正式术语),这是我内部的事情。 纯子网传递分组不需要经过路由器,但是可能借助交换设备 如果发生子网的聚集,那么有可能子网中传递数据需要借助路由器了 路由器之间连接的网络也是子网。 IP 地址分类: A 类:地址的最高位为 0,第一个字节的其他 7 个 bit 代表网络号。后面三个字节的 24 bits 代表主机号。早就分完了 A 类地址总共有27−2=1262^7-2=12627−2=126 个网络(全 0 和全 1 的网络号不用,这是约定。) A 类地址的每个网络中都有224−22^{24}-2224−2 个,约 1600 万个主机 B 类:地址最高两位为 10,然后前面两个字节中剩下的 14 bits 代表网络号。后面两个字节的 16 bits 代表主机号。早就分完了 B 类地址共有214−2=163822^{14}-2=16382214−2=16382 个网络 每个 B 类网络中,有216−2=655342^{16}-2=65534216−2=65534 个主机 C 类:地址最高三位是 110,然后前面三个字节中剩下的 21 bits 代表网络号,最后的一个字节的 8 bits 代表主机号。 一般我们获得的地址都是 C 类地址 C 类地址一共有221−22^{21}-2221−2 个网络(两百多万个) 每个 C 类网络中,有28−2=2542^8-2=25428−2=254 个主机 ABC 类地址都是单播地址,D 类地址是组播地址 D 类:地址的最高 4 位是 1110,后面是组播地址。这个组是依照一定的协议维护的。信息在这个组里面传播。 E 类:预留的,以后再想办法分配 特殊的 IP 地址: 子网部分全 0:本网络 主机部分全 0:本主机 主机部分全 1:广播地址,这个网络内的所有主机 32 位全 0:代表所有主机 32 位全 1:代表本地网络广播 127.x.x.x 地址:代表回路地址(测试地址)分组在网络层会直接网上提交,不会再往下。 内网(专用)地址: 地址空间的一部分,供专用地址使用 永远不会被当做共用地址分配,不会与共用地址重复。 只在局部网络中有意义,用以区分不同的设备。 路由器不对目标地址是专用地址的分组进行转发 专用地址的范围: A 类地址: 10.0.0.0 ~ 10.255.255.255 子网掩码 255.0.0.0 B 类地址: 172.16.0.0 ~ 172.31.255.255 子网掩码 255.255.0.0 C 类地址: 192.168.0.0 ~ 196.168.255.255 子网掩码 255.255.255.0 由于 B 类地址太大,可能用不完,但是 C 类地址太小,可能不够用。为了解决这个问题就需要推出一种按需分配的机制。 IP 编址:所以我们对一部分的 B 类地址,进行更细致的划分,产生 **CIDR(无类域间路由)**classless inter-domain routing。这让子网部分可以在任意位置,此时就需要子网掩码。 子网掩码:也是是 32 位的。携带子网掩码的 IP 地址格式为 a.b.c.d/x 其中, x 是子网号的长度。 譬如,IP 地址 200.23.16.0/23 使用了 9 位的主机号 23 位的网络号 子网掩码为 11111111 11111111 11111110 00000000 来了一个 IP 分组,如何找网络号?就与子网掩码做一个与。这样就实现了网络号提取(后面变成 0 了,因为主机号在路由表查询的时候是没有意义的。) 互联网做路由,并不是对每个地址做路由,而是按照子网,做路由表。 互联网的路由是以网络为单位,进行路由信息的发布和计算,而不是以单个的 IP 地址来计算。 转发表和转发算法: destination subnet num mask next hop interface 202.38.73.0 255.255.255.192 IP-x Lan1 202.38.64.0 255.255.255.192 IP-y Lan2 ... default - IP-z Lan0 首先获取 IP 数据报的目标 IP 地址,然后与子网掩码进行与操作。 对得到的网络号,在转发表中 destination subnet num 比对,如果找到匹配的对应表项,就转发到对应的 IP。 转发时,需要通过 interface 交给下层的物理网络。 只有最后到达路由器的那一跳主机号有用。其他时候不关注主机号。 如果目标 IP 和所有的表项都没有匹配上,那么一定会和最后一个默认表项匹配上。则通过默认的端口(通常是网络的出口路由器对应的 IP,是网络的默认网关 ) 如何获得一个 IP 地址? 系统管理员会给主机分配 IP 地址,配置在一个文件中。麻烦 Wintel 模式:控制面板 --- 网络 --- 配置 --- tcp/ip --- 属性 unix 模式:修改 /etc/rc.config 文件。 使用 DHCP 协议 dynamic host configuration protocol 从服务器中动态获得一个 IP 地址。(plug and play 模式,最大好处是自动) 上网需要四个信息: IP 地址、子网掩码、Local Name Server 以及 default gateway(默认网关) DHCP 协议(UDP): 主机上线的时候广播一下 [ DHCP discover ] 。目标 ip 地址选用 255.255.255.255 广播地址(32 位全 1)同时,因为自己没有地址,只好用 0.0.0.0 地址(32 位全 0)。 DHCP server 收到后,向主机提供报文相应 [ DHCP offer ] (携带预分配的 IP 地址等信息)即:给你这个行不行? 主机向 DHCP 确认请求 IP 地址 [ DHCP request ] 。即:行,我就要这个。 DHCP 服务器向主机发送地址,然后给出租用期 [ DHCP ack ] 。 如何获得一个网络的子网部分? 从 ISP 获得的地址中,进行划分。大机构可以按照部门再划分子网。网络号 + 子网号 + 主机号 ICANN 分配 IP 地址。分配地址,管理 DNS,分配域名,解决冲突。 路由机构的计算和路由的通告(层次编址)和快递的模式有点像: 大机构(子网掩码 20 位),分为 8 个部门(子网掩码 23 位)每个部门的子网,要向大机构的子网发路由通告。 譬如,一个小部门的 IP 子网前缀为 200.23.16.0/23 ,向机构发送路由通告的时候,会向机构在发送一个 IP 地址,这个地址最后会变成大机构路由器的路由表上,对应子网前缀 200.23.16.0/23 的路由下一跳的 IP。 可以直接通告,也可以路由聚集(前提是子网的子网)后再通告。 如果收购了另外的公司,可以在路由表上把新公司的 IP 地址也引导过来一起处理。 路由聚集采用最长前缀匹配 路由聚集可以很大程度上减少路由的计算和通告数量。 但路由聚集会有空洞的现象(比如 8 个子网里面我只能处理 7 个,但为了聚集,我会 “吹牛”,声称我都能处理) 实际上,我们有另外一个 IP 负责处理多出来的那个子网。这时候路由表里面就会产生多个表项的匹配。这时候就采用最长前缀的匹配结果。 NAT: Network Address Translation 网络地址转换 有时,本地网络只有一个有效的 IP 地址(由于很多原因,可能一些机构只有一个有效的 IP) 由于不需要从 ISP 分配一块地址,只用一个地址就可以管理所有的设备。这样可以省钱。 可以在局域网内改变设备地址,无需通知外界。 可以更换外界 ISP 服务商,而不需要改动内网的设备地址。 局域网内的设备没有明确的地址,对外不可见。比较安全。 如何实现? 需要支持 NAT 的路由器。 1. 以内网主机作为源主机,连接外网的主机:数据包进出都要替换 IP 和端口(需要构建 NAT 转换表,记住这个替换关系) 用外网 IP 上的某个端口,替代内网某个 IP 的某个端口。 总共有 65535 个端口,基本上能够支持内网机器的映射。 NAT 的争议点在于:路由器是第三层的设备,但是端口号是第四层的东西。NAT 机制使得路由器对端口号作处理,违反了分层原则以及 end-to-end 的原则。 端到端原则:网络复杂性放到网络边缘,无需借助中转和变换,网络分组就可以直接传输到目标主机。(但 NAT 使得分组改变了,所以违反了端到端原则) 但由于地址短缺(ABC 类地址早就分完了),我们不得不采用 NAT 的方式。现在一方面也在往 IPV6 转移。 NAT 地址还带来了一个问题:NAT 穿越的问题 2. 以外网主机作为源主机,连接内网的某个主机:内网穿透 方案 1:静态配置 NAT,然后转发外网服务器对特定端口的请求。 方案 2:采用 UPnP 协议(IGD 协议)该协议允许内网的设备去查询 / 增加 / 删除 NAT 的表项。是自动化的静态 NAT 配置。 方案 3:中继法 used in Skype。内网设备主动向中继注册,建立连接。外部服务器也与中继进行连接。中继将两个连接进行桥接。 IPv6 的产生: 32-bits 的 IPv4 地址已经用完。添加一些新特性,可以提高 IP 协议的运行效率 定义 IPv6 地址为 128-bits,规定 IPv6 的头部固定为 40 字节。数据报传输过程中,不允许分片。 如果分组太大,超过链路的 MTU,会被丢弃,然后通过 ICMP 协议返回错误报告给源主机。 IPv6 的数据报头部格式(共 40 字节): 4 字节: ver (4 bits) 版本号 pri (4 bits) 优先级 flow label (24 bits) 表示数据在一个 flow。(同一个会话的所有数据可以看做一个流,然后可以对这些数据做统一的处理。这个 flow 没有严格的定义) 4 字节 payload len (16 bits) 载荷长度 next header (8 bits) 标识上层协议,指明数据交给哪个上层协议处理。如果是一个选项,那么标识了一个 TLV 数据,指示后面一个数据是什么类型的数据。(time length value) hop limit (8 bits) 32 字节: source IP address (128 bits) destination IP address (128bits) 随后就是 data 的载荷部分。 相比 IPv4 协议: CheckSum 字段被移除。降低在每一段中的处理速度 Options 字段允许。但是放在头部之外,被 Next Header 字段标识 ICMPv6:是 ICMP 协议的升级版本,增加了报文类型(如 packet too big)。支持多播组管理功能。 协议互通和过渡:隧道技术 IPv4 是汪洋大海,IPv6 是小岛。在一个岛上构建 IPv6 分组,如果要到其他岛上,就在 IPv4 的分组内携带这个完整的 IPv6 分组,然后上岛的时候再解析出来 需要相当长的时间过渡共存。 # 通用转发和 SDN 每个路由器上,都有实现路由的算法元件,交给 IP 协议实体。 数量众多,功能各异的中间盒:交换机、防火墙、NAT、IDS、负载均衡设备等。需要不同的设备去实现不同的功能,并且会不断增加新的设备。 传统的 IP 网络的行为模式比较僵化(毕竟路由器生产后,规则就固化了,改变工作方式就很困难了) 传统的方式是通过分布式,每台设备各自实现数据平面和控制平面。 但设备常常呈现垂直集成的特点: 硬件、私有的操作系统 互联网标准协议的私有实现。 从上到下都是一个厂商提供(代价大,被设备绑架,要使用一套服务) 垂直集成不利于创新的生态,并且昂贵,而且管理困难。 05 年左右提出了 SDN 方式: 采用集中化的网络控制器,来实现控制平面的功能。 通过所谓的南向接口(当前有一个标准叫 OpenFlow),把算出来的流表,发给每个设备当中的控制代理。控制代理负责把这个流表装载下来。 分组交换机依据流表,对到来的分组匹配出来的表项,做出相应的动作。 如何匹配?可以匹配 IP,端口,头部字段等。 做出什么动作?可以转发,可以屏蔽丢弃,也可以泛洪等。 ** 网络可以编程。统一化设备功能:通过 SDN 的分组交换机,统一控制。** 运营商可以只部署一种设备,通过下发不同流表,那么 SDN 分组交换机就能表现为路由器,防火墙等。然后还可以部署网络应用。 1. 转垂直集成为了水平集成:控制平面开放实现,创造出了好的生产业态,促进发展。(分组交换机、控制器和各种控制逻辑网络应用 app 可以由不同的厂商生产,专业化,然后也能引入良好的竞争) 2. 集中式实现了控制逻辑,网络管理容易,集中式控制器了解网络状况,编程简单,传统方式困难。也避免了路由器的错误配置。 3. 基于流表的” 匹配 + 行动 “工作模式允许 “可编程的” 分组交换机,能够实现流量工程的高级特性。 SDN 架构数据平面交换机: 快速、简单、商业化交换设备。采用硬件实现通用转发功能。 流表被控制器计算和安装。 基于南向 API(如 OpenFlow),SDN 控制器访问基于流的交换机 定义了哪些可以被控制,哪些不能。同时也定义了和控制器的协议。 SDN 控制器(网络操作系统): 维护网络的状态信息 通过上面的北向 API,和网络控制应用交互 通过下面的南向 API,和网络交换机交互 逻辑上集中,但在实现上通常由于性能、可扩展性、容错性以及鲁棒性采用分布式方法。 SDN 架构:网络控制应用 控制的大脑:采用下层(SDN 控制器)提供的服务,实现网络功能(路由器、交换机、防火墙、负载均衡、其他功能) 非绑定。可以被第三方提供,与控制器厂商通常不同。与分组交换机厂商也可以不同。 通用转发和 SDN:每个路由器包含一个流表(被逻辑上集中的控制器计算和分发) OpenFlow 数据平面抽象: 流:由分组(帧)头部字段所定义。 通用转发:简单的分组处理规则。 模式:将分组头部字段和流表进行匹配 行动:对于匹配上的分组,可以丢弃、转发、修改。将匹配上的分组转发给控制器。 优先权:几个模式匹配了,优先采用哪个,消除歧义。 计数器:可以对字节计数,或者对分组计数。 例 转发表匹配: src: 1.2.*.* dest: 3.4.5.* drop 【防火墙规则】 src: *.*.*.* dest: 3.4.*.* forward (2) 【转发 2 端口】 src: 10.1.2.3 dest: *.*.*.* send to controller 【转发给控制器】 OpenFlow 的表项结构: rule + action + stars rule 流表匹配规则(对应字段不匹配就用 * 表示): switch port Link layer:VLAN ID / MAC src / MAC dest / Eth type Network layer:IP src / IP dest / IP port Transport layer:TCP sport / TCP dport action 行为: 向特定(可能多个)端口转发 分装分组转发给控制器 丢弃分组 发送分组给处理管道(上报控制器) 修改字段 stars:packet + byte counters 计数器 目前,几乎所有网络设备的工作(如路由器、交换机、防火墙、NAT 等),都可以在 SDN 上统合。 设备 match action 路由器 最长前缀匹配 通过一条链路转发 交换机 目标 MAC 地址 转发或者泛洪 防火墙 IP 地址以及 TCP/UDP 端口号 允许或者禁止 NAT IP 地址和端口号 重写地址和端口号 可以精确编程控制网络的路径以及每个设备的流表。","categories":[{"name":"计算机科学","slug":"computer-science","permalink":"http://blog.sunforge.cn/categories/computer-science/"},{"name":"计算机网络","slug":"computer-science/计算机网络","permalink":"http://blog.sunforge.cn/categories/computer-science/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/"}],"tags":[{"name":"笔记","slug":"笔记","permalink":"http://blog.sunforge.cn/tags/%E7%AC%94%E8%AE%B0/"}]},{"title":"Chapter 3 Transport Layer","slug":"computer-science/computer-networks/Chapter-3-Transport-Layer","date":"2022-09-11T05:05:52.000Z","updated":"2022-10-18T12:44:06.628Z","comments":true,"path":"computer-science/computer-networks/Chapter-3-Transport-Layer/","link":"","permalink":"http://blog.sunforge.cn/computer-science/computer-networks/Chapter-3-Transport-Layer/","excerpt":"","text":"# 传输层原理 传输层,不管是 TCP 还是 UDP,会同时支撑很多应用进程。源端如何复用,目标端如何解复用还给相应的进程? 可靠数据传输原理 RDT:非常经典、重要。下层 IP 是不可靠的,但 TCP 如何向上层提供可靠服务?为什么会不可靠,要引入什么机制保证可靠? 流量控制:TCP 和对等的 TCP 实体怎么协作,实现流量控制,以至于不会发送太快,从而超出接收方的处理能力。 拥塞控制:如果发送方和接受方的处理速度都足够快,但是网络路径上有拥塞,那么就需要有一个拥塞的感知,然后恢复出来。如果没有拥塞控制的机制,那么网络几乎无法使用。学习:原因、表现、检测、控制 # 概述和传输层服务 传输层向上层提供的是进程与进程之间的,以 message 报文为单位的,逻辑的通信。 报文的传输:应用层交给传输层的报文,如果比较长,会被分成若干个报文段。以段为单位,形成本层的 PDU(协议数据单元)。到对方,对方把头部去掉,然后把段的内容取出来,以字节流的形式交给上面的应用进程。(借助网络层的服务) ** 可靠性、安全性可以在传输层加强。延迟、带宽不可以在传输层优化。** 瓶颈式的链路制约了网络的性能。 多路复用和解复用(功能上非常重要): ip 是从主机到主机的。传输层引入 port 端口号区分为进程到进程。 TCP 源端:传输层从应用层拿下 message,然后添加 TCP 头部(包含源端口和目标端口),形成 TCP 的段 TCP 段同源 ip 目标 ip 再往下交,然后在 TCP 段前面加上 IP 头部(包括源 ip 和目标 ip),形成 IP 数据报。 借助网卡打出去。 目标端:收到了以后,把 ip 的载荷部分(报文体)拿出来,然后得到 TCP 段。 根据 TCP 段的 TCP 头携带的端口信息,然后查表找到 socket,将 message 发送给应用进程 UDP 源端:传输层从应用层拿下 message,socket 以及 & cad 结构体(包含目标端的 ip+port),复用方法与上面类似。 目标端:解复用与上面类似。 # 无连接传输:UDP (用户数据报协议) 在 IP 协议提供的服务上,没有增加额外的服务,只是增加了复用解复用。 同 IP 协议一样,是尽力而为的,不可靠:有可能收到的是乱序的,也有可能丢失。 无连接的,没有握手。经常被用于流媒体,DNS,SNMP 协议。适合实时多媒体应用和事务型应用。 因为是无连接的,所以叫数据报。所以有 UDP 数据报,IP 也叫数据报 ** 如何改进 UDP,使其安全?** 应用层上增加可靠性,或应用特定的差错恢复。 UDP 数据报的格式: 8 个字节的头部。头部包含源端口号(2 字节),目标端口号(2 字节),长度(2 字节,包含头部后的长度),校验和(2 字节,就是我们之前说的 EDC 差错控制编码) 载荷部分。载荷部分比较大。 校验和:检验被传输的报文段的差错(如比特反转等) 发送方计算校验和,然后接收方独立另外计算校验和,并与发送方发来的校验和进行比对。 如果没有通过校验,那么报文一定错误。如果通过了校验,那么报文一定是对的嘛?不一定。也有可能虽然变了,D 和 EDC 但恰好仍然符合差错控制编码关系。(这种传输错误,通过 EDC 无法检验) 注:这个 D 不仅仅是指 UDP 的数据报,可能还包含 UDP 的头部,甚至 IP 的伪头部 发送端如何做 Check-Sum? 我们把这个 D 按照 16bit 的大小,切成小块。然后每一个小块中的 16bit 都代表一个整数。把这些整数加起来,进行处理,就形成了一个校验和。 累加时需要注意,进位应该回滚。然后最后取反码得到 EDC。 接收端如何检验? 把收到的 D 按照 16bit 切块,不足的补 0,然后累加(进位需要回滚),然后把 EDC 也加进来。如果最后结果是 16bit 全 1,那么校验成功。 # 可靠数据传输 RDT 的原理 传输层可靠数据传输:最常见的是传输层的 TCP 实现了可靠数据传输。有些网络在链路层或者网络层就实现了可靠数据传输(极少) 上层应用 sending process,receiving process(要求可靠的服务)。借助下层的服务实现(下层不可靠 UDT) 如何向上层提供可靠服务? 本层与上层的接口 rdt_send(), deliver_data() ,本层和下层的接口 udt_send(), rdt_rev() 是原语形式 渐进地解释可信数据传输 RDT 实现原理: 假设底下的 channel 有两个特性:不出错,不丢失。那么这边的协议就不需要做任何处理。 底层协议的不可靠性,决定了 RDT 实现协议的复杂性。底层越不可靠,RDT 越复杂。 我们只考虑单项数据传输简化数据传输(虽然实际情况下是双向传输,但是双向传输是两个单向传输的综合)并尝试使用有限自动机来描述协议的原理。 RDT 1.0:可靠信道上的可靠数据传输。什么都没干,只封装解封装。 RDT 2.0:假设我们去掉不出错的特性(传输过程中,分组中的比特可能反转)保留不丢失特性。我们应该引入接收方的反馈机制。 如果接受方接受到的 D 和 EDC 检验成功,向发送方返回 ACK;如果检验不成功,则返回 NAK。 因为接收方可能发送 NAK(即发送方可能发送失败)所以发送方需要有重传机制,即需要把发送完的东西放一个副本。 发送方:接收方返回 ACK 则发新的,接收方放回 NAK 或者不返回则发老的。(属于停止等待协议) RDT 2.1:既然不满足不出错的特性,Package 可能出错,那么 ACK/NAK 也可能出错。那么怎么办呢。增加序号信息。 如果 ACK/NAK 重复,那么直接重发。就算接收方收到重复也没关系,再发 ACK 就行了(此时接收序号 + 1)。发送端接收到 ACK 回应,那么就把发送序号 + 1 接收方等待 P1,到来的还是 P0(收到了重复的分组),且没出错(那肯定是接收端之前回传的 ACK 出问题了),那么接收方还要把 ACK 重新放一遍。(此时分组不向上传了,重复了,直接丢掉。) 【实际上】停止等待协议中,我们只需要区分老的分组和新的分组,只需要 1bit,就可以处理这个序号问题。 RDT 2.2:无 NAK 的协议。功能同 RDT 2.1 但只使用 ACK 实现(NAK free)。但对 ACK 进行编号 对当前分组的反向确认,用对前一功能的正向确认替代。比如我想要 P1,但发来的 P1 错了,或者发来的就是 P0,那么我继续发送 P0 的 ACK 确认。 为后面一次发送多个数据单位做准备。(一次发送多个 ACK/NAK 很麻烦。如果采用这种机制,可以使得信息确认减少一半,信息处理更加便捷) RDT 3.0:假设我们把另一个特性也去掉,即 Package 也可能丢失。那么可能会引起死锁。引入超时重传机制。 设计一个超时计时器,发送端发送完分组就启动。重传时间一般设置为比一次正常往返多一点。如果重传时间内,没有收到对应确认,那么就重发。(如果 P1 出问题,那么接收端返回的 ACK0,但是这时候发送端不马上重传,等一手超时重传) 反正所有的重传,都可以等超时重传。 超时定时器重传时间设置是一个学问。如果设置不好,那么会有一个时间上的交错,导致 packet 和 ack 都要发两次,效率不高。 采用适应式的超时重传机制。 到此为止,对于停止等待型的 RDT,已经比较完备,能够对抗丢失和出错。 停止等待型在信道容量大时,效率比较低。比如北京到天津的告诉公路。如果只允许一辆车,确认到了以后,才发下一辆车,那么效率肯定低。 端到端的延迟 t=15ms,那么往返一次的时间 RTT=2t=30ms(发送数据,返回确认),若分组长度 L=1KB=8000bits,带宽 R=1Gbps,那么分组的发送时间,就是 L/R=8us,占了 30ms 的极小一部分。利用率 **u=8us/(8us+30ms)=0.027%** 非常低。 有效吞吐就很低 270kbps。利用率很低。问题在协议。这个协议一次只发一个。 流水线协议一次发送多个未经确认的分组。 需要用多个 bit 表示分组序号 发送方需要缓冲区。以便于检错重发,或者超时重发。 接收方需要缓冲区。发送方的发送能力和接收方的处理能力有差距。所以需要缓冲区。 通用协议:滑动窗口协议 slide window 协议 send window = 1, receive window = 1 就是停止等待协议 send window > 1, receive window = 1 就是 GBN 协议(属于流水线协议) send window > 1, receive window > 1 就是选择重发协议(属于流水线协议) 发送窗口,是发送缓冲区的的子集,用于存放哪些已发送但是未确认的分组 每发送一个分组,发送窗口的前沿,向前移动一格(但不能超过发送缓冲区大小) 当发送窗口,把发送缓冲区已经占满,就不能发送了。 收到老分组的确认,那么发送窗口的后沿,向前移动。(发送缓冲区也向前移动)发送缓冲区可以罩住新的分组,来了分组可以发送。 后沿的向前移动,不能超过前沿。 GBN 协议 如果接收窗口只有 1 的大小。已经顺序接收了 012 三个分组,在等分组 3,此时来了分组 4,那么会返回 ACK2(确认最近到的,序号最大的分组) 造成分组异常的因素有两点:1. 所传的分组在过程中出错或丢失。 2. 接收方给的确认,没有到达发送方。这两种都可能造成分组乱序到达。 异常情况下 GBN 协议的窗口互动:(顺序确认)只有给出了新分组的确认,发送窗口才能向前滑动。如果超时,那么发送窗口会把所有已发送未确认的分组,全部重新再传一遍。 选择重传协议。 如果接收窗口有 5 的大小,那么哪个分组到来,就确认哪个分组。比如等待 01234(来 0,则发 ACK0,窗口前移),然后变成等待 12345(若来 2,则发送 ACK2 单独确认,但窗口不前移,因为 1 没到)。 如果此时 1 到来,发送 ACK1,然后 12 一起解封装向上传递,窗口前移两个。 如果 1 一直没到,那么 1 会超时,所以发送端要重新发送。因为已经收到了 2 的确认,所以不再传 2(选择重传) 协议对比 GBN SR 优点 简单,所需资源少(接收方一个缓存单元) 出错时重传一个,代价小 缺点 一旦出错,回退 N 步,代价大 复杂,所需资源多(接收方多个缓存单元) 适用范围 出错率低的场景使用,如果出错是罕见的,那么没有必要用 SR 链路容量大的场景适合用 SR(用 GBN 的话一点出错代价太大) 思考:如果用 n 个 bit 来代表发送窗口的序号,GBN 发送窗口最大值是 $$2n-1$$,SR 协议的发送窗口最大值是 $$2$$. 为什么 # 面向连接的 TCP 提供点对点的服务。(进程到进程,一个发送方,一个接收方) 可靠的字节流的服务。(不出错,不重复,不丢失,不失序,原原本本)但不区分报文的界限。 是管道化、流水线的协议。在未经确认的情况下,可以发送很多连续的 TCP 段。 存在发送缓冲区,要检错重发和超时重传;存在接收缓冲区,接收端的读取能力和线路的传送能力不匹配 是全双工的。在同一连接中,数据可以同时、双向流动。 面向连接,需要建立连接才能通信。 TCP 段的载荷部分存在一个最大报文大小 MSS。 每一个物理网络都有一个 MTU 最大传输单元。以太网的 MTU=1500 Byte. 其中 IP 头部 20B,TCP 头部 20B,所以报文最大是 1460B。所以应用层交下来的字节流,需要按照 1460B 来切分。 TCP 报文段结构: 16bit 源端口, 16bit 目标端口 32bit 序号(这个序号不是上面说的 PDU 的序号,而是 TCP body 的第一个字节,切分前在原字节流中的偏移量) 32bit 确认号(确认号也是以字节为单位的,如果发送方收到 ACK=555,那么代表,接收方已经接收到 554 及 554 以前的全部字节)确认号是累计确认的。 首部长度、保留未用的位,以及标志位 U,A,P,R,S,F(不同标志位组合,表示报文的不同功能类型),共 16bit ; 接收窗口 16bit(用于流量控制)。 校验和 16bit ;紧急数据指针 16bit(一般不用,是一个古老的字段) 可选项 32bit 也是属于头部。 接收方如何处理乱序的报文段?协议没有规定。 简单 telnet 场景: 接收方,根据收到报文的 ACK 值,确定发出的段的序号。 怎样设置 TCP 的超时定时器?如果不合适,就会造成链路利用率低。 必须要比 RTT 长,但 RTT 是变化的 如果太短,那么会过早超时重传,会传很多本不必要传的 如果太长,那么如果报文丢失,反应慢。 如何估计 RTT? 不是一个固定的值,而是一个适应式的测量计算。 TCP 的往返延迟随着时间变化非常的大,通信环境非常复杂。 应当定期去测量往返延迟。然后计算平均值 E,然后计算往返延迟的方差 D。取 RTT=R+4D。 我们会先收集一个 sample RTT(从发送方发出,到发送方接收到应答)。如果直接用 sample RTT 不合适。因为 sample RTT 会有较大的浮动。所以我们要不断去修正这个 RTT: newE(RTT)= (1-a)prevE(RTT) + a * sampleRTT 当前时间采样值对 RTT 的贡献越大。越往前的采样值,对 RTT 的贡献要越小,得到移动平均的 RTT。 我们再计算偏里程度 DevRTT: newDevRTT = (1-b)prevDevRTT + b * |sampleRTT-newE(RTT)| TCP 的可靠数据传输:TCP 是 GBN 和 SR 的混合体,有些方面像 GBN,有些方面像 SR TCP 在 IP 的基础上,建立了 RDT。是管道化的,且采取累计确认的机制(ACK 是表示期待,如 555,表示 555 之前的收到了,希望从 555 收开始接收)。 像 GBN:发送方只设置一个定时器,不是为每个端都设置定时器(只和最老发出去的那个段相关联。)确认的时候,是对顺序到来的最后一个字节的确认。(最后一个字节 + 1 然后返回) 像 SR:如果超时定时器超时,那么只重传最老的那个段,而不是把所有端都重传。 如果收到乱序报文段?TCP 协议没有规定处理方式。可以抛弃,也可以缓存。 触发重发:超时定时器触发超时重传,收到了某些段的连续三个冗余确认(第一个正常确认不算)而触发快速重传;。 TCP 发送事件:发送一段长度为 MSS 的报文后,发送窗口前沿移动 MSS 的单位,然后开启超时定时器。如果 TCP 发送端接收到一个 ACK 555,那么就把发送窗口的后沿,移动到 555。 产生 TCP ACK 的建议: 接收窗口,顺序接收到一个段,不建议直接法确认,而是建议启动辅助计时器。 如果在这个计时器内,顺序的下一个段到,那么直接发送两个段的累计确认。 如果辅助计时器到了,顺序的下一个段还不来,那么赶紧确认,而发送方避免重传。 接收窗口,乱序到了一个段,那么赶快把前面没收到的那个段的期待发给对方。让对方赶快补发这个段。 如果来了一个段,把 GAP 补齐(部分补齐,全部补齐)发送最后到达的连续分组的序号。 快速重传机制:如果 ACK 大于 BASE,那么滑动窗口后沿向前滑动。如果 ACK=BASE,就进行计数。如果连续收到 3 个冗余,那么就重发 流量控制:接收缓冲区。通过反馈空闲缓冲区的尺寸,达到流量控制的目的(捎带 Piggybacking)receive window 字段 什么是捎带?由于是全双工,所以既是接收方,也是发送方。我们不必为 ACK 专门浪费一个报文,可以在传输 data 的同时,携带对上一个报文的确认。 两个重要变量: lastByteRead 上一个被读的字节 lastByteRcvd 上一个被接收的字节 相减计算得到 RcvBuffer 接收缓冲区大小 TCP 连接建立:三次握手 客户端向服务器发送连接请求报文(SYNbit=1 代表连接请求,选择 seq=x 是报文初始序号) 服务端向客户端返回(SYNbit=1,ACKbit=1,ACKnum=x+1,seq=y) 客户端向服务器发送确认(ACKbit=1,ACKnum=y+1 希望服务器从 y+1 开始发,即 y 已经收到) 异常情况:如果 TCP 只采用两次握手,则会产生大量的半连接(半连接只在服务器端维护的连接,可能是由于超时重传引起的)服务器还会将老的数据(重传的数据)当做新数据接收。 三次握手的话,如果产生超时重传,客户端就会把连接关掉(不会产生半连接)。 有可能产生老数据当新数据接收的情况。但只要初始的 seq 不同,这个几率几乎为零。 初始序号的选择:客户端和服务器可以根据时钟周期选择初始序号。比如,当前时间,取低 32 位作为初始序号。 TCP 连接关闭和释放:四次挥手 需要双方各自拆除连接。但这个连接拆除是不可靠的 客户端要向服务器发起拆除,服务器返回拆除确认 服务器也要向客户端发起拆除,然后客户端返回拆除确认 # 拥塞控制原理 拥塞的原因(场景化描述)/ 代价: 2 个发送端,2 个接收端,一个路由器缓冲无限大,输出链路的带宽为 R,没有重传。 网络中的数据,超出网络处理能力了,就会拥塞。 延迟特别大。比在不拥塞的时候,延迟大很多。 一个路由器,有限的缓冲,分组丢失时,发送方应当重传。路由器输入λin\\lambda_{in}λin,路由器输出\\lambda_ 【理想化】发送端有完美的信息。发送端知道什么时候路由器的缓冲区可用。只在缓冲区可用的时候发送,这样分组就不会丢失。 【理想化】掌握丢失信息。分组可以丢失(路由器发送缓冲区满而被丢弃)如果知道分组丢失了,那么发送方重传分组。随着拥塞情况的不断增加(重传的分组增加)所以,传输效率会降低。(输出比输入少。因为重传了丢失分组和没有必要重传的分组) 拥塞代价:发出许多没有必要重传的分组。(许多分组只是由于拥塞,而超出了超时定时器,并不是因为丢失) 4 个发送端,多重路径,超时重传 拥塞时,路由器的空闲缓冲区大小总是 0 或 1 拥塞造成死锁,而且会丢包。 【代价】当分组丢失时,任何的 “关于这个分组的上游传输能力” 都被浪费了。(前面传的都白传了) 拥塞控制方法: 端到端的拥塞控制 没有来自网络的显式反馈 端系统根据延迟和丢失时间推断是否有拥塞 TCP 采用这种方法。 网络辅助的拥塞控制 路由器向端系统提供反馈信息 显示提供发送端可以采用的速率 单个 bit 置位,显示有拥塞(SNA,DECbit,TCP/IP ECN,ATM) 【例】ATM 的 ABR 拥塞控制 available bit rate 弹性服务: 如果发送端的路径 “轻载”,那么发送方可以使用全部带宽 如果发送方的路径拥塞了,那么发送方限制其发送速度到一个最小的保障速率上来 RM(资源管理)信元 信元是 ATM 网络中传递的基本单元。在若干个数据信元之中,就会间隔插入一个 RM 信元 RM 信元中的比特被交换机设置。(网络辅助就体现在这里) 如果发生轻微拥塞,就把 NI 这个 bit 位置 1(no increase in rate)轻微拥塞,速率不要增加了 如果发生拥塞,则 CI bit 置 1(congestion indication) ER 字段(explicit rate)体现了所有交换设备的瓶颈带宽(短板效应),防止拥塞。拥塞的交换机会改变 ER 字段的值。 数据信元的 EFCI bit 位:如果 RM 前的那个数据信元,EFCI bit = 1,那么接收端在返回的 RM 中,将 CI bit 设置为 1 发送端发送的 RM 信元被接收端返回,接收端不做任何改变。直到 RM 信元被发送端重新接收 # TCP 拥塞控制 端到端,网络不提供任何辅助信息。网络辅助拥塞控制的代价太大。 发送端如何探测到拥塞? 某个段超时了(或丢失了):拥塞 超时时间到,某个段的确认还没有来 原因 1:网络拥塞,某个路由器的缓冲区没有空间了,被丢弃(概率大) 原因 2:出错被丢弃(各级错误,没有通过校验,被丢弃)(概率小) 一旦超时,就认为是拥塞了,虽然有一定误判,但是总体方向是对的 有关某个段的三次重复冗余 ACK:轻微拥塞 段的第一个 ACK 是正常 ACK 段的第 2,3,4 个 ACK 是冗余 ACK,说明乱序到达。(后面三个段都到了,但是目标段还没到,丢失的可能性很大) 这时候,网络还能进行一定的传输,拥塞情况比第一种要好。 速率控制的方法: 维持一个拥塞窗口值 CongWin(这个值是动态的,是感知到的网络拥塞程度的函数) 如果超时,或者有 3 个重复、冗余 ACK,那么 CongWin 下降。 超时时,CongWin 降为 1MSS,进入 SS 阶段然后再倍增到CongWin2\\frac{CongWin}{2}2CongWin(每个 RTT),从而进入 CA 阶段 3 个重复 ACK,CongWin 降到CongWin2\\frac{CongWin}{2}2CongWin(每个 RTT),处于 CA 阶段 如果没有以上情况,那么 CongWin 跃跃欲试(上升) SS 阶段(慢启动阶段):加倍增加(每个 RTT) CA 阶段(拥塞避免阶段):线性增加(每个 RTT) 发送端限制已发送,但未确认的数据量(的上限) 从而粗略地控制发送方往网络中注入的速率 rate =\\frac{CongWin} TCP 的拥塞控制和流量控制联合作用: 发送端控制发送但是未确认的量的同时,也不能超过接收窗口。需要满足流量控制的要求:SendWin=min TCP 拥塞控制策略概述: 慢启动 连接刚建立 CongWin = 1 MSS 如 MSS = 1460bytes; RTT = 200 msec 初始速率 = 58.4kbps(非常小,必须要想办法扩大) 每收到一个确认,拥塞窗口值 + 1,这样一来,每个 RTT,拥塞窗口就加倍了。 AIMD:线性增,乘性减少 CongWin 的测试原理,从 1 开始,依次 2,4,8,16(在 16 处拥塞,即超时了)。然后乘性减少,将 8 作为警戒值。 第二次测试:还是从 1 开始,进入慢启动状态,依次 2,4,8,然后进入拥塞避免阶段,开始线性增加,依次 9,10,11,12(在 12 处拥塞,即超时了)。随后乘性减少,将 6 作为警戒值。 第三次测试:还是从 1 开始,进入慢启动状态,依次 2,4,6(达到警戒值),然后进入拥塞避免阶段,开始线性增加,依次 7,8,9,10(在 10 处,收到连续 3 个冗余 ACK)。随后乘性减少,将 5 作为警戒值 第四次测试:从 5 开始(由于上一次是连续三个冗余 ACK,属于轻微拥塞),直接进入拥塞避免阶段,依次 6,7,8, ...... 超时事件后的保守策略 【总结】阈值 threshold,拥塞窗口:CongWin CongWin 小于 threshold 时,处于慢启动状态(SS 阶段),窗口指数增长 CongWin 大于 threshold 时,处于拥塞避免状态(CA 阶段),窗口线性增长 当收到三个重复的 ACK 时,threshold 设置成 CongWin/2,然后 CongWin 设置成 threshold+3(为什么是 + 3,因为 3 个冗余 ACK) 超时事件 timeout 发生时候,threshold 设置成 CongWin/2,然后 CongWin 设置为 1MSS,进入慢启动阶段(SS 阶段) TCP 吞吐量: 平均的窗口尺寸:12(W+W2)=34W\\frac{1}{2}(W+\\frac{W}{2})=\\frac{3}{4}W21(W+2W)=43W 平均吞吐量(RTT 时间吞吐34W\\frac{3}{4}W43W)即吞吐量为34⋅WRTT\\frac{3}{4}·\\frac{W}{RTT}43⋅RTTW bytes/sec TCP 公平性: n 个主机对,共享瓶颈带宽 R,长期来看,会均分共享,每一对主机对,获得 R/n 的带宽。 但 UDP 存在很强的侵略性。多媒体应用通常是 UDP,会侵占 TCP 进程的带宽。","categories":[{"name":"计算机科学","slug":"computer-science","permalink":"http://blog.sunforge.cn/categories/computer-science/"},{"name":"计算机网络","slug":"computer-science/计算机网络","permalink":"http://blog.sunforge.cn/categories/computer-science/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/"}],"tags":[{"name":"笔记","slug":"笔记","permalink":"http://blog.sunforge.cn/tags/%E7%AC%94%E8%AE%B0/"}]},{"title":"Chapter 2 Application Layer","slug":"computer-science/computer-networks/Chapter-2-Application-Layer","date":"2022-09-11T05:05:06.000Z","updated":"2022-10-18T12:44:06.628Z","comments":true,"path":"computer-science/computer-networks/Chapter-2-Application-Layer/","link":"","permalink":"http://blog.sunforge.cn/computer-science/computer-networks/Chapter-2-Application-Layer/","excerpt":"","text":"# 应用层原理 总述:应用层协议最多。中国在网络中应用层上的创新还不错,原创性创新一般。 网络应用体系结构:C-S 模式、P2P 模式以及混合型模式 CS 模式中,服务器是中心,先启动,并且服务器一般是固定 IP。客户端主动找服务端请求资源。可扩展性比较差,随用户规模增加,系统性能断崖式下降。 P2P 模式中,可以做到平滑扩展。同一台主机,在某些会话中是服务器,在某些会话中又是客户端。 混合型架构:Napster,在校园网中分发 mp3 音乐。服务器作为目录和注册中心。做成了 P2P 文件共享系统。 进程通信: 同一主机的进程间,通过操作系统提供的进程通信机制进行通信。 不同主机,通过报文交换来通信。分为客户端进程(发起通信的进程)和服务端进程(等待连接的进程) 注意:P2P 架构的应用也有客户端进程和服务端进程之分。 分布式进程通信: ** 应用进程如何标识自己,如何让别人找到自己?** 标识和寻址。有三个要素,主机 IP,协议 TCP/UDP,端口号。例如 HTTP 采用 TCP 协议,在 80 端口。一个进程采用 IP+port 标识端节点。本质上,任何一对应用进程之间的通信就是两个端节点(end point)之间的通信 ** 应用层如何使用传输层提供的服务?** 形式:使用应用程序接口 API 也就是 socket API,位置:层间接口的 SAP 处,就是 socket。 层间接口必须携带的信息: 要传输的报文(即传输层 SDU) 然后是源主机以及目的主机的标识(ip+port)。 传输时,可能在某个时间段内,要传输大量的信息,如果每个报文都要加上 ip 和 port,那么会造成很大浪费。可以采用 socket,减少层间传输的信息量。 socket:用代号(一个整数),表示通信的双方或单方。用一个整数表示两个应用实体之间的通信关系,代表自己和对方的 ip 和 port 的本地表示。可以使得穿过层间接口的信息量最小,且便于管理。 socket 是本地应用层和传输层的约定,只有本地操作系统知道,对方是不知道的。收发的时候查表就行,操作系统负责维护这张表 TCP 的 socket,代表的是会话关系,是四元组,源和目标的 ip+port。目标主机两个不同的端口,对应两个不同的 socket UDP 的 socket,对应二元组,包含本地的 ip+port。通过层间接口时:需要传数据、传 UDP socket 和目标主机的 ip+port 才能发送出去。 ** 应用进程使用传输层服务,如何实现报文交换?** 定义协议,编写程序,借助 OS 的接口 如何描述传输层的服务?应用层需要传输层提供什么样的服务? 数据丢失率 吞吐量 时间敏感性(延迟) 安全性(机密性、完整性、可认证性) TCP 实体:实现网络协议(TCP 协议)的软硬件模块 传输层提供的服务 TCP 服务:可靠、流量控制、拥塞控制、面向连接。不保证时间、最小吞吐和安全性。 UDP 服务:不可靠,不控制流量、拥塞,没有时间、带宽的保证。不建立连接。 安全性: TCP/UDP 都没有加密,明文传输 SSL 是在 TCP 上实现的。提供加密的 TCP 连接(私密性、数据完整性、可以提供端到端鉴别) SSL 在应用层,采用 SSL 库,SSL 库采用 TCP 通信 SSL socket API # WEB 与 HTTP web 页:由一些对象组成(可以使 HTML 文件,可以使 JPG 图片,Java 程序等) web 页含有一个基本的 HTML 文件,这个文件里又包含对于若干个对象的引用。通过 url 对每个对象进行引用。 url 的格式为 Prot://user:[email protected]/someDept/pic.gif:port (协议名、用户、口令、主机名、路径名、端口) HTTP:超文本(携带各种资源)传输协议,是 web 的应用层协议,采用客户(浏览器)/ 服务器模式。跑在 TCP 上。是无状态的。 服务器在 80 号端口打开一个 socket(守候 socket),然后当一个 web 浏览器与服务器建立连接时,新建另一个 socket(连接 socket)来标识这个连接。原来的守候 socket 仍然在 80 端口监听 非持久 HTTP(HTTP 1.0):TCP 连接建立(一趟往返),HTTP 传数据(一趟往返),TCP 连接拆除。 持久 HTTP(HTTP 1.1):TCP 连接建立,HTTP 连接,TCP 连接不关,可以一直通过 HTTP 传数据。 如果使用 HTTP 1.0,我们通过解析 base.html 文件,发现了(如 10 个)资源,然后要再次建立 TCP 连接,请求对象,然后拆除关闭连接。 相应时间模型 RTT(round-trip time) 往返时间 HTTP 1.0(非持久 HTTP)的响应时间是:2RTT + 传输时间 HTTP 1.1(持久 HTTP) 流水线方式:请求直接 ” 流水 “ 发出 非流水线方式:一个一个请求。前一个对象回来,后一个请求发出 HTTP 请求报文: 采用 ASCII 码(人能阅读) 请求行包括 method(GET/POST/HEAD/PUT/DELETE),url 和 version 信息。 put 和 delete 通常是维护使用。需要网络管理员使用一些工具进行请求。 head 命令通常只请求首部,用于搜索引擎建立索引或者网站维护。 首部行(好多行,格式为首部名:首部值) 换行回车符,表示报文结束 如果有 body 那再传 body(有些命令如 post 包含 body,有些命令不包含 body) TCP 上运行的所有应用进程,都需要自己维护报文之间的界限。 HTTP 响应: 状态码:200 OK,301 已被永久移除, 400 请求无法理解, 404 资源未找到, 505 版本号不支持。 HTTP 协议是无状态的协议(服务器不维护客户端的状态) Cookie 机制维持客户状态:第一次发送请求,不带 cookie,服务器生成并发送 cookie,后续请求携带 cookie。可以做用户行为的分析,但是也涉及到隐私问题。 web 缓存机制:用户通过代理服务器访问资源。代理服务器通常较多。代理服务器没有,则向 original server 请求,并缓存,然后返回给用户。(好处:用户体验快。服务器端的负载较轻。) 为什么要用 web 缓存?大家的访问具有趋同性。如果流量强度大,那么排队延时就会很大。使用缓存可以减少网络的载荷。 缓存:本地命中,直接返回,本地不命中,从外网服务器中取数据。如果 original server 的对象发生修改,检查 web 缓存,有需要则更新 # FTP 协议 现在用的已经不多。 功能:可以上传下载(对于客户端而言)。 工作原理:控制连接与数据连接分开。FTP 服务器守护在 21 端口。先建立 TCP 连接(控制连接),然后进行身份认证(用户名和口令),完成认证后,客户端可以通过某种指令,向服务器请求某个文件。服务器收到指令,会 ** 主动(有点违反常理)** 与客户端 20 号端口建立 TCP 数据连接。 控制报文与数据报文分开传,就是带外的。合在一起就是带内的。 组成:FTP 客户端,FTP 服务器,用户接口,本地文件系统。 FTP 是有状态的。要维护客户端的状态。 FTP 命令与响应: 命令在控制连接上以 ASCII 码文本的方式传送。如 USER username,PASS password,LIST,RETR filename,STOR filename 等 返回码样例:状态码和状态码解释。 # E-Mail 电子邮件 组成部分:用户代理(客户端软件 outlook,foxmail 等),邮件服务器(就是服务器),发送协议:简单邮件传输协议 SMTP,拉取协议:POP 3,IMAP,HTTP 也可以。 IMAP 协议不仅可以拉取,还可以远程管理目录,比如在收件箱中建文件夹,移动邮件到另一个文件夹中等。但 POP 3 协议不支持这个功能。 发信(SMTP 协议):用户代理,配置好邮件服务器的 ip 地址端口号,通过邮件服务器发邮件。用户代理把邮件发给邮件服务器,暂存在队列中,邮件服务器从队列中挨个取邮件,然后向相应的目标邮件服务器发送。目标邮件服务器受到邮件后,放到每个用户的 mailbox 中。 收信(三种协议都可):用户通过用户代理,从邮件服务器中的邮箱里拉取收到的信件。 ** 为什么放在队列中发?** 进来的速度和处理(发出)的速度有差别,要用队列平滑一下。发邮件不是来了就发,而是定期发,比如五分钟十分钟。不至于服务器那么劳累。有时候也没有这么多邮件发,所以是定期发。 email 过程,简单 SMTP 发送:简单,采用 ascii 码。容易被篡改。安全性不高。可打印,所以是 readable。 SMTP 和 HTTP 的比较。都采用 ASCII 码,都支持相应交互。 HTTP 是 pull 的,每个对象有单独的相应报文。 SMTP 是 push 的,多个对象整合在一个报文里(邮件可携带附件)。 SMTP 协议包含:首部行(包括 to,from,subject 还有抄送人 cc 等),空行以及 body 但这里会产生一个问题,原式的 SMTP 只支持 ASCII,那么图片,汉子等都传不了了。所以有 MIME 多媒体邮件扩展。 MIME 采用了 base64 的编码。base64 编码是通过 ASCII 码做的映射。相当于把若干个不在 ASCII 码范围内的字节,转化为在 ASCII 范围内的字节,然后进行传输。 因此原式的邮件协议经过扩展,可以传输中文和 exe 等文件。 POP 3 协议: 可以跑在 tcp 上也可以跑在 ssl 上。 POP 3 可以采用下载并删除模式(一个端看了另一个端就看不到了)和下载并保留模式(每个端都可以看到)。 POP 3 是无状态的协议。 IMAP 协议:有状态,因为可以维护远程目录 # DNS (Domain Name System) 域名解析系统 不是给人使用的。而是为其他应用所使用的。提供域名到 ip 地址的转换。是跑在应用层的基础设施。 web 系统以及 ftp 等系统都要使用 DNS 服务。 DNS 系统的必要性 网络层工作的主机,通过 ip 地址标识自己,也方便别人找到它(寻址)。但 ip 地址不好记。人们常常习惯于用有意义的字符串来标识 internet 上的设备。因此,就需要一个 DNS 系统,通过字符串找到 ip。 ** 如何命名?** 分层的命名,方便增加。 ** 对应关系如何解析?** 不能集中式维护。分布式的数据库,进行解析。 运行在 UDP 的 53 号端口。 DNS 是在主机系统的应用层实现的。是互联网的核心功能,但不在网络核心,而在边缘系统实现。互联网的复杂性体现在网络边缘。在边缘的传输层以上。 DNS 的主要目的: 提供域名到 ip 地址的转换,提供主机别名到规范名字的转换。还提供负载均衡的功能。 一个域名通常对应一个服务器集群去支持它的访问。比如 github.com 这个域名,必定对应着许多服务器。github.com 这个域名是所有服务器的别名。每个服务器为了区分,有着不同的规范名字,如 server123.github.com 等。 **DNS 采用层次树状结构的命名方法。** 树叶代表主机。 顶级域 通用:.com .net .gov .edu .org 等 国家:.cn .us .nl .jp 等 每个域(子域)下面可以更加分为不同的子域。在子域可以对每台主机进行命名。解决了重名问题:从本域往上,用点号分割。 域是逻辑的。与物理网络无关。 一个域的主机,可以分属不同的网络;在同一个网络的主机,可能分属不同的域。 DNS 根名字服务器 所有的域名归结到一个根上。但如果只有一个名字服务器的话,如果宕机就会有灾难性后果(可靠性问题),通信容量也不够大(可扩展性问题),维护非常麻烦(可维护性问题)。互联网的根名字服务器一共有 13 个。 查询域名的时候,要从 13 个根的任何一个往下去寻找。这样比较可靠一点。这 13 个根大部分在北美,欧洲和日本也有,中国大陆没有。 **DNS13 个根一个都不在中国,有安全风险?** 是又不是。 为了解决单个名字服务器的可靠性,可扩展性以及可维护性的问题,我们将域分成一个个区域,区域互不重叠。 每一个区域设置一个权威名字服务器。维护这个区域上的域名和 ip 地址。名字服务器可以设置在区域之外,以保障可靠性。 TLD 服务器:顶级域服务器负责查询顶级域名和国家域名。 区域名字服务器维护资源记录(数据库):域名到 ip 地址的对应关系,子域等信息。字段包含域名、ttl 生存时间、class,value 和 type。 ttl 生存时间是为了效率而存在的,ttl 到期则删除,保证一致性(如果是权威记录,那么 ttl 是无限大) class 是代表网络类型。如 IN 代表 Internet 互联网。 type 表示不同的意思 type 是 A 的话:name 字段代表主机,value 字段代表 IP 地址 type 是 CNAME 的话:name 字段为规范名字的别名,value 字段放规范名字 type 是 MX Mailbox 的话:name 字段是邮件服务器的别名,value 放的是邮件服务器别名所对应的规范名字 type 是 NS,那么 name 是域名,value 为该域名的权威服务器域名。 DNS 大致工作流程 应用调用解析器 resolver 解析器作为客户,向 Name Server 发出查询报文(UDP) 解析器怎么知道 local name server 的 ip 地址?是配置好的。或手工配,或者通过 DHCP 协议自动配。 一个机器上线之后,必须要知道这几个信息:ip 地址,子网掩码,local name server 是什么,default gateway 默认网关 本地名字服务器 LNS 并不严格属于层次结构,每个 ISP(居民区的 ISP,公司,大学)都有一个本地的 DNS 服务器。也称为默认名字服务器。当一个主机发起 DNS 查询时,这个查询就被发送到其本地 DNS 服务器上(起着代理的作用,将查询转发到层次结构中去) 如果 LNS 中有缓存,直接返回。 如果没有缓存 采用递归查询方法,顺着树根查下来(往下找,一直找到权威的名字服务器,然后得到域名和 ip 的关系)但是这种递归查询很烦,因为都要问根服务器,所以就很忙。 还有迭代查询方法,“类似踢皮球” Name Server 返回相应报文(name /ip) DNS 协议、报文 查询和相应的报文相同。 报文首部:标识符 (ID),flags(包括:查询 / 应答,希望递归,递归可用,应答为权威等字段) 提高性能:缓存 一旦名字服务器学到了一个映射,就将该映射缓存起来。 根服务器通常都在本地服务器中缓存着,使得根服务器不用经常被访问。 可能存在的问题:如果情况发生变化,缓存结果就会和权威记录不一致。所以设置 TTL(默认两天) 维护问题:新增一个域 上级域的名字服务器中增加两条记录,指向这个新增的子域的域名和域名服务器的地址。 在新增子域的名字服务器上运行名字服务器,负责本域的名字解析。名字 ->IP 地址。 攻击 DNS: 总的来说 DNS 比较健壮。 DDOS 攻击 对服务器进行流量轰炸攻击:发送大量 ping 命令。 没有成功,原因是:根目录服务器配置了流量过滤器,防火墙。local DNS 服务器缓存了 TLD 服务器的 IP 地址,因此无需查询根服务器。 向 TLD 服务器进行流量轰炸攻击:发送大量查询 可能更危险,但是效果一般。因为大部分 DNS 缓存了 TLD。 重定向攻击 中间人攻击 截获查询,伪造回答,从而攻击某个(DNS 回答指定的 IP)结点 DNS 中毒 发送伪造的应答给 DNS 服务器,希望它能够缓存这个虚假的结果。 技术上较困难 利用 DNS 基础设施进行 DDOS 攻击 伪造某个 IP 进行查询,攻击这个目标 IP。 查询放大,相应报文比查询报文大 效果有限 因为基本上所有 DNS 服务器都缓存了顶级域名的对应关系,所以即便中国没有 13 根,也没有那么大的安全隐患。 # P2P 应用 纯 P2P 应用:没有(或极少)一直在运行的服务器。任意端系统都可以直接通信。P2P 系统既是客户端,又是服务器。peer 结点间歇性上网,每次 IP 地址都有可能变化。 可靠性高。流量是分布式的。是由成千上万个 peer 结点提供的。 例子:文件分发(BitTorrent),流媒体(KanKan),VoIP(Skype 互联网电话)等 传统的 CS 架构分发文件:从服务器向 N 台不同的主机,分发统一文件 F。时间下限为:$$\\max {\\frac {F}{D_{min}},\\frac {NF}{U_s}}$$($$D_i$$ 代表客户端下载带宽,$$U_s$$ 是服务器的上传带宽)随着客户端数 N 越来越大,服务器的上载带宽成为瓶颈,下载时间随着用户增加线性增加。 当客户端少时,瓶颈是客户端的下载带宽。 当客户端多时,瓶颈是服务端的上载带宽。 P2P 分发文件:为了解决 CS 模式可扩展性问题。分发文件 F 的时间下限为 $$\\max {\\fracF}{D_{min}},\\frac{NF}{U_s},\\frac{NF}{U_s+\\sum_{i=1}(N U_i)}$$(假设服务器有一个文件的拷贝,每一个客户端都有一份文件,每一个节点都可以上载。)但是由于 P2P 网络具有动态性,因此不易管理。 P2P 的类型 非结构化 P2P DHT(结构化)P2P 【基于分布式散列表】(暂不学 **P2P 应用通过会话间的合作关系,相互协作,形成了一个覆盖网 overlay(是一种应用层上的逻辑网络)** 如果 overlay 是任意的、随机的,就是非结构化的 P2P;如果 overlay 是有序的,构成环或者树,那就是 DHT 结构化的。 非结构化 P2P 有集中化目录的文件分发系统(如 Napster) 每个结点上线时都要向目录服务器注册(我是哪台主机,我有哪些资源) 结点请求资源时,要从目录服务器获得资源结点 list(哪些结点有这个资源)然后向这些结点请求资源。 目录服务器存在单点故障、性能瓶颈的问题。也可能存在侵权问题。 完全分布式的文件分发系统(如 Gnutella) 没有中心服务器。所有结点构建成一个 Overlay。 如何建立 Overlay?下载 Gnutella 客户端时,有一个配置文件。其中有若干个 Gnutella 网络经常在线的结点的 IP。 只要同其中一个建立联系,那么就可以通过其中转,随机与一些结点连接,接入 Gnutella 网络。 如果要下线,那么要一个个与邻居切断联系。此时邻居需要随机找另一个主机连接,以维持连接强度。 结点通过泛洪的方式进行资源查询。通过 Overlay,先找邻居,然后再找邻居的邻居,以 “发洪水” 的方式查询全网。拥有资源的服务器给出应答。以此构建资源目录。 泛洪查询方法存在问题。查询可能会陷入循环,还可能被放大。这样不行 解决方法:1. 设置 TTL,比如说五跳查询失效;2. 添加一个结点访问状态。被访问的结点不在泛洪。 根据资源目录,向拥有资源的服务器发起查询 Gnutella 的运行非常不成功。有人说在 Gnutella 网络上什么也找不到。后来才被迫开源,但也没有扩充太多用户群。 混合体,利用不对称性(例如 KaZaA) 每个结点都属于一个组。要么是组长,要么是组员。 组长和组长的关系是 Gnutella 关系。组长和组员的关系是 Napster 关系。组内集中式,组间分布式 将文件对应的哈希值,作为唯一 ID,标识文件。 BitTorrent(也属于非结构化) 工作原理:peer 要加入一个 Torrent 中(Torrent:结点的组,之间互相交换文件,互通有无) 每个结点都拥有文件的一部分块。根据拥有块的多少,有一个对应的 bitmap。每隔一段时间,torrent 中的所有结点会通过泛洪的方式,交换 bitmap。 一个新结点加入时,bitmap 全 0,随机请求 4 块。然后根据稀缺优先原则,请求剩下的块。同时,按照 **tit-for-tat(针锋相对)** 的策略为其他结点提供服务。(对我好的节点,我也对他好) 由于稀缺优先的策略,所以自己被别人请求的概率就会变大,所以别人就会给自己提供更好的服务。所以,根据针锋相对的规则,自己的下载速度就会更快。性能就会更高 如果一个结点拥有这个文件的全部,就是种子。否则就是吸血鬼。种子可以选择离开。 是不是所有结点来了都要提供服务呢?采取有限疏通的方式。每三个周期中,前两个周期,排队优先级根据对方提供的带宽大小确定。第三个周期,采用随机的方法优化疏通。 如何加入 torrent: 采用带外方式。在文件分发的网站,根据描述进行匹配,找到对应的 hash 值,然后下载对应的 torrent 文件。 torrent 文件是描述信息,携带了维护这个文件的 tracking server(跟踪服务器)信息 检索的这个结点,就要向 tracking server 发送加入洪流的请求。通过 tracking server 找到 peer 结点,构成洪流,互通有无 结构化 DHT P2P:维护的是一种树状、环状的有序拓扑。不是用 IP 地址,而是用 IP 地址的 hash 值作为唯一标识。 以环状拓扑为例,结点按照 hash 值大小首尾相连构成环。然后对文件也作哈希。 比如说一个 DHT P2P 中有【5】和【88】等结点,那么文件哈希值为 6-88 的,那么这些文件的目录,都维护在 88 这个结点处。 # 视频优化服务和 CDN:上下文 互联网中,杀手级应用有很多种,其中视频业务是其中一种。据统计,互联网中七八成的流量都被视频流量占据。 杀手级应用:网络流量占的比较多,而且可以吸引用户。 ** 如何向成千上万的人提供并行的播放业务?** 挑战:规模性问题,以及每个结点的网络带宽制约,需求不同。由于客户端异构,需要的视频质量也不尽相同 采用分布式的应用层面的基础设施 CDN 来解决。 视频是什么?图像序列。利用了视觉的滞留效应。有一个帧率。 视频压缩:视频如果不压缩,直接传输,通常占用带宽很大。一般都以小码率传输。对时间冗余和空间冗余进行压缩。 有 CBR 和 VBR 两种编码策略。 存储视频的流化服务一边下一遍播放。 多媒体流化服务器 DASH 服务器将文件分成多个块,以不同码率编码、存储。 生成告示文件 manifest,提供不同块的 URL。 边看便请求,自动决定要向哪些服务器请求后续块。 Content Distribution Network (CDN) 内容分化网络:服务器如何通过网路向上百万用户同时提供流化视频服务? 存在的问题:1. 跳数比较多 2. 网上的重复流量比较多(浪费)3. 单点故障 4. 服务器瓶颈 5. 网络拥塞 CDN 服务商在全球部署 CDN 缓存结点。用户可以通过域名解析重定向的技术,定位到(离他最近的,服务最好的)CDN 服务器。 视频流媒体提供者,购买 CDN 运营商的服务。ISP 购买 CDN 运营商的服务,提升 ISP 运营商服务用户的能力。 CDN 运营商的部署策略: enter deep 策略:部署在 local ISP,深入接入网,离用户进,数量多,质量好,但难以管理。 bring home 策略:部署在少数关键结点。而是部署到上层的 ISP 的附近,如在某些数据中心机房附近。 用户怎么知道从哪个 CDN 访问资源呢:1. manifest 文件 2. 域名解析重定向 3. 如果网络路径堵塞,可以选择不同的拷贝 CDN 结点运行在应用层,运行在网络的边缘,呈现 OVER-THE-TOP 的特点。挑战主要在: 那么多节点有,我从哪个缓存节点获取? 如果结点堵塞,我怎么换另一个结点? 我应该在那些结点部署拷贝? CDN 使用的简单场景: 用户通过视频链接,访问并解析。 然后根据 DNS 解析,问 LocalNameServer。 从 LNS 的权威名字服务器中,查到的不是一个 ip,而是重定向(返回了另一个域名) 再去解析返回的命名,就会解析到 CDN 的权威名字服务器。 然后 CDN 的权威名字服务器,给到一个 ip 地址,这个 IP 地址是离用户最近的。 由这个 IP 地址向用户提供流化服务。 CDN 的重定向对用户是透明的,根本感受不到是原始服务器还是 CDN 服务器提供服务。 # TCP Socket 编程 应用进程使用传输层提供的服务,才能互相通信。传输层提供 Socket API TCP 可靠的,字节流的服务,无连接。保证按照流是对的,但是不保证界限。报文需要应用自己维护 UDP 不可靠的(数据 UDP 数据报)数据报,有连接。 前面学过,Socket 就是一个整数。就像文件句柄一样。对 Socket 操作,就是对会话上两个应用进程之间的操作。TCP Socket 的整数代表了自己的 ip+port 和对方的 ip+port,代表两个进程间的会话关系。 TCP Socket 编程场景:通过 socket 的方式,将小写字母变成大写。 前提:服务器要先运行(C/S 模式)等待连接 服务器创建 welcome Socket,返回一个整数,然后这个 socket 会与服务器本地的 ip/port 相捆绑。 服务器调用 socket api 中的 accept 函数。阻塞式等待远程客户端的 socket 连接建立请求。 之后,客户端也要创建 socket,然后返回整数,与客户端本地的 ip/port 进行隐式(如果你不指定,就默认和当前一个没有用的端口)的捆绑。 客户端调用 calnet 函数,指定服务器的 ip/port,与服务器进行阻塞式连接。 如果客户端收到了服务器的确认,那么连接建立。此时客户端 calnet 就会解除阻塞,向客户端返回一个有效值。 服务端的 welcome socket 在 accept 客户端的请求后,会返回一个新的 socket(connection socket)包含了服务器 ip/port(没变),还包含了客户端的 ip/port。 连接建立,然后可以开始收发。收发完成后,解除 connection socket,但 welcome socket 仍然在守候。 两个重要的结构体 struct sockaddr_in { short sin_family; //AF_INET 协议族 u_short sin_port; //port struct in_addr sin_addr; // ip address, unsigned long char sin_zero[8]; //align}不仅可以用于 IP 通信,也可以用 IPX 的通信。 struct hostent { char *h_name; // 主机域名 char **h_aliases; // 主机别名 int h_addrtype; int h_length; // 地址长度 char **h_addr_list; // 给出 ip 地址列表 #define h_addr h_addr_list[0];} // 主要作域名解析的函数调用客户端 TCP socket 代码 /* client.c */void main(int argc,char *argv[]){ struct sockaddr_in sad; /* structure to hold an lP address of server */ int clientSocket; /* socket descriptor */ struct hostent *ptrh; /* pointer to a host table entry */ char Sentence[128]; char modifiedSentence[128]; host = argv[1]; port = atoi(argv[2]); /* Create client socket, connect to server: */ memset((char *)&sad,0,sizeof(sad)); /* clear sockaddr structure */ sad.sin_family = AF_INET; /* set family to Internet */ sad.sin_port = htons((u_short)port); ptrh = gethostbyname(host); /*Convert host name to lPaddress */ memcpy(&sad.sin_addr, ptrh->h_addr, ptrh->h_length); // 将 lP 地址拷贝到 sad.sin__addr connect(clientSocket, (struct sockaddr *)&sad, sizeof(sad)); /* get input stream from user*/ gets(Sentence); /*send line to server*/ n = write(clientSocket, Sentence, strlen(Sentence)+1); /* Read line from server */ n=read(clientSocket, modifiedSentence, sizeof(modifiedSentence)); printf(\"FROM SERVER: %sln\",modifiedSentence); /*Close connection*/ close(clientSocket);}服务端 TCP socket 代码 /*server.c */void main(int argc, char *argv[]){ struct sockaddr_in sad; /* structure to hold an lP address of server*/ struct sockaddr_in cad; /*client */ int welcomeSocket,connectionSocket; /* socket descriptor *lstruct hostent *ptrh; l* pointer to a host table entry */ char clientSentence[128]; char capitalizdSentence[128]; port = atoi(argv[1]); /* create welcoming socket at port & bind a local address*/ welcomeSocket = socket(PF_INET,SOCK_STREAM,O); memset((char *)&sad,0,sizeof(sad)); /* clear sockaddr structure *lsad.sin_family = AF_INET; /* set family to lnternet */ sad.sin_addr.s_addr = INADDR_ANY; /*set the local lP address */ sad.sin_port = htons((u_short)port);/*set the port number */ bind(welcomeSocket, (struct sockaddr *)&sad, sizeof(sad)); /* Specify the maximum number of clients that can be queued */ listen(welcomesocket,10); while(1) { /*wait on welcoming socket for contact by a client*/ connectionSocket=accept(welcomeSocket,(struct sockaddr *)&cad,&alen); n=read(connectionSocket, clientSentence, sizeof(clientSentence)); /*capitalize Sentence and store the result in capitalizedSentence*/ /*write out the result to socket*/ n=write(connectionSocket, capitalizedSentence, strlen(capitalizedSentence)+1); close(connectionSocket); } // end of while loop, loop back and wait for another client connection.}# UDP Socket 编程 没有握手。socket 只和本地 ip/port 捆绑,作为本地 ip/port 的代表。 所以发送报文时以 socket 作为参数,必须明确指明对方的 ip/port 进程接收报文时,必须从报文中提取出发送者的 ip/port 这样才能发回去。 可能乱序,可能丢失。因为无连接,所以可以叫做数据报。 UDP 客户端代码 /* client.c */void main(int argc,char *argv[]){ struct sockaddr_in sad; /* structure to hold an lP address */ int clientSocket; /* socket descriptor */ struct hostent *ptrh; /* pointer to a host table entry */ char Sentence[128]; char modifiedSentence[128]; host = argv[1]; port = atoi(argv[2]); clientSocket = socket(PF_INET,SOCK_DGRAM,0);/* determine the server's address */ memset((char *)&sad,0,sizeof(sad)); /* clear sockaddr structure */ sad.sin_family = AF_INET;/* set family to Internet */ sad.sin_port = htons((u_short)port); ptrh = gethostbyname(host); /* Convert host name to lPaddress */ memcpy(&sad.sin_addr,ptrh->h_addr, ptrh->h_length); gets(Sentence); /*Get input stream from user*/ /* send line to server */ addr_len =sizeof(struct sockaddr); n=sendto(clientSocket, Sentence,strlen(Sentence)+1,(struct sockaddr *) &sad, addr len); /*read line from server*/ n=recvfrom(clientSocket, modifiedSentence,sizeof(modifiedSentence),(struct sockaddr *) &sad,&addr_len); printf(\"FROM SERVER: %sln\",modifiedSentence); close(clientSocket); /*close connection*/}UDP 服务端代码 /*server.c */void main(int argc, char *argv[]){ struct sockaddr_in sad; /* structure to hold an lP address */ struct sockaddr_in cad; int serverSocket; /* socket descriptor */ struct hostent *ptrh; /* pointer to a host table entry */ char clientSentence[128]; char capitalizedSentence[128]; port = atoi(argv[1]); /* create welcoming socket at port & bind a local address*/ serverSocket = socket(PF_INET,sOCK_DGRAM,O); memset((char *)&sad,0,sizeof(sad)); /* clear sockaddr structure */ sad.sin_family = AF__INET;/* set family to Internet */ sad.sin_addr.s_addr = INADDR_ANY; /* set the local lP address */ sad.sin_port = htons((u_short)port);/* set the port number */ bind(serverSocket, (struct sockaddr *)&sad,sizeof(sad)); while(1){ n=recvfrom(serverSocket, clientSentence, sizeof(clientSentence), (struct sockaddr *)&cad,&addr_len ); /*receiving messages from clients*/ /* capitalize Sentence and store the result in capitalizedSentence*/ n=sendto(serverSocket , capitalizedSentence,strlen(capitalizedSentence)+1,(struct sockaddr *)&cad, &addr len); /*write out the result to socket*/ } // end of the loop, loop back and wait for another client connection.}","categories":[{"name":"计算机科学","slug":"computer-science","permalink":"http://blog.sunforge.cn/categories/computer-science/"},{"name":"计算机网络","slug":"computer-science/计算机网络","permalink":"http://blog.sunforge.cn/categories/computer-science/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/"}],"tags":[{"name":"笔记","slug":"笔记","permalink":"http://blog.sunforge.cn/tags/%E7%AC%94%E8%AE%B0/"}]},{"title":"Chapter 1 Computer Networks and the Internet","slug":"computer-science/computer-networks/Chapter-1-Computer-Networks-and-the-Internet","date":"2022-09-11T05:00:18.000Z","updated":"2022-10-18T12:44:06.628Z","comments":true,"path":"computer-science/computer-networks/Chapter-1-Computer-Networks-and-the-Internet/","link":"","permalink":"http://blog.sunforge.cn/computer-science/computer-networks/Chapter-1-Computer-Networks-and-the-Internet/","excerpt":"","text":"# 什么是网络 互联网、网际:很多网络,通过网络互联设备连在一起(网络的网络) 网络:蜘蛛网、渔网、神经网络,包括节点和链路(图结构,与形状无关) 计算机网络:联网的计算机构成的系统。 节点: 包括主机节点(笔记本电脑、平板、手机、联网的冰箱、服务器等,源主机目标主机) 和数据交换节点(负载均衡设备、中继器、路由器、交换机等,既不是源也不是目标,起转发作用) 链路:连接主机和交换节点。连接交换节点和交换节点。 分为接入网链路:主机接入到最近的交换机的链路 和主干链路:交换节点和交换节点之间的链路 协议:对等层实体,在通信过程中应该遵守的规则的集合。包括语法语义和时序 互联网: TCP/IP 协议为主的一族协议。由这些协议支撑起的那个网络就是互联网。Internet 如果与别人不连,但仍然也是依照 TCP/IP 协议工作,就是 intranet,企业网、内联网 从构成的角度:是网络的网络 拥有数以亿计的、互联的计算设备。 包括主机:端系统,即 host 或 end system(用方框表示) 能够运行网络应用程序 通信链路 包括光纤、同轴电缆、无线电等 主要指标:传输速率(带宽 bps) 协议:互联网中所有行为都通过协议规范(显式的法律、隐式的校规)。包括语法语义时序动作。 标准:以互联网工程任务组 IETF 发布的 RFC 标准。 从服务的角度: 使用通信基础设施进行通信的分布式应用进程。 分布式应用:网络存在的理由 通信基础设施:为分布式应用,提供远程的通信服务。包括应用层之下所有的应用实体,以及所有网络部分。 通信基础设施为 apps 提供编程接口(通信服务) 互联网,按照组成类型,分成一个个子系统(包括网络边缘、网络核心和接入网与物理媒体) 边缘通过接入,连接核心 核心把所有边缘连在一起 任意两个端系统之间,可通信 接入形式:可以是移动接入,可以有线接入 # 网络边缘:边缘系统上存在的网络应用,是网络存在的理由 应用进程之间通信的两种模式 客户端服务器模式 主机进一步分为客户端和服务器。客户端请求,服务端响应。资源在服务器。客户端依赖服务器。服务器要先运行起来,等待客户端请求。 这种模式可扩展性较差。可能会导致宕机。可靠性也不高。 Peer-Peer 模式(对等模式,P2P 模式) 每个结点,既是客户端又是服务器,是分布式的。在部分的会话中,是客户端,接受文件;但在另一部分会话中,是服务器,发送文件。 你向其他迅雷客户端,请求文件片段。然后你拥有了一定的文件片段,又可以向其他用户提供文件片段。 通信方式:采用网络基础设施提供的面向连接的通信服务 TCP 服务 可靠的,保序的。面向连接:通信状态在端系统中维护,网络不维护。有连接:通信状态端系统和网络都维护。 流量控制。协调发送接收速度。受到发送端接收端缓冲池大小。 拥塞控制。受到网络传输速度影响 HTTP,FTP,SMTP 等 UDP 服务:用户数据报协议 无连接的,不可靠,没有流量控制,没有拥塞控制。 常用于:流媒体、远程会议、网络电话 # 网络核心:数据交换 是路由器的网状网络。基本问题:数据如何通过网络进行传输 电路交换(线路交换) 为每个呼叫预留一条专有线路。如电话网 主机间通信,首先通过信令系统,在网络核心中,为两者的通信分配一条独享的线路。 带宽很大,通过一系列的技术,可以进行分片复用(频分 FDM、时分 TDM、波分 WDM、码分 CDM)。 频分:连续性得到部分带宽。以频段分割 时分:间歇性获得全部带宽。以时间周期性分割(时分,将每个周期都均分为时槽) 资源独享,可以保证性能。如果没有数据发送,资源就会被浪费。 建立时间长。且计算机间通信具有突发性,如果建立独占连接,那么浪费多。 可靠性不高。如果中心节点损毁,那么通信中断,影响范围大。 分组交换:以分组为单位,存储转发 节点之间通信链路不再细分为 pieces 主机主机之间通信数据分成 packet 以 packet 为单位,在每个交换节点中存储转发(先把分组存下来,然后再转发) 为什么要存储转发?可以按需使用,如果不存储,就变成了独享。 属于统计多路复用。分组没有固定的模式,是随机划分时间片的,是特殊的时分。 延迟:比线路交换大。 节点中要消耗存储时间、排队时间。但作为交换,得到了共享性。但利用率高,避免浪费。 在一个速率为 R bps 的链路(一跳),一个长度为 L bits 的分组的存储转发延时:L/R s 排队延迟和丢失:如果路由器缓存满了,那么新来的分组,会被丢弃。 过度使用会导致拥塞。 网路核心的关键功能:路由和转发 路由:决定分组采用的,从源到目标的路径。通过路由算法算出 转发:将分组从输入链路转发到输出链路 存储转发的两个方式:数据报和虚电路 数据报:无需建立连接,有数据直接发送,每一个分组都独立路由(路径不一样,可能失序)路由器根据分组目标地址进行转发 虚电路:要建立虚电路表。靠信令建立。查表转发。 # 接入网和物理媒体 边缘系统通过接入网接入网络核心:接入网的带宽一般是共享的 住宅接入:modem,调制解调器。 现行的解决方法是,专线铺到每家每户。但成本高。 90 年代考虑利用现有的网络资源,让每家每户接入进来。(利用原来的电话线网络,通过调制解调器) 由于电话线穿的是语音,所以带宽只有 4 kHz。所以需要借助一些额外的设备。 装一个猫(起到调制解调的作用),通过调频或调相位,连接电话网和互联网。在音频载波上,加载 01 的数据,就好像在载波上冲浪一样。 但这样,就与打电话形成了互斥。打电话时,不能上网。同样的,上网时,没办法打电话 接入网:digital subscriber line,DSL(电信公司提供的上网网络) 能够保证 4 kHz 的带宽,高于 4 kHz 的部分,非对称地划分为上行带宽(小些)和下行带宽(大些)两个部分,称为 ADSL,并且同样采用调制解调的方法。 通过 ADSL 猫来上网。这样可以同时保证打电话和上网。 接入网:线缆网络(有线电视公司提供的上网网络) 有线电视信号线缆的双向改造。(原来是单向,仅有下行带宽,电视公司用于广播电视信号) 现在通过双向改造,不同频段传输不同信道的通信数据。有些带宽是上行的,有些带宽是下行的。这些带宽是共享的。 往上层是光纤,往下是铜轴电缆。带宽划分非对称,最高 30 Mbps 的下行速率,最低 2 Mbps 的上行传输速率。 住宅接入:电缆模式 很多都采用了互联网电视。有限电视公司的业务在萎缩。 无线接入网路 WLANs,广域无线接入,无线局域网 WiFi 企业接入网:Ethernet 被企业、大学等机构采用。现在端系统常直接接到以太网络交换机上。 # 物理媒体:第 0 层 发送和接收两个节点。在两个节点对之间传送比特。 物理媒体:可以是 ** 光纤、铜轴电缆、以太网网线或者开放的空间(传送电磁波)** 等 导引型媒体 电磁波信号沿着固体媒体被导引(同轴电缆、光纤、双绞线) 同轴电缆:连根同心的铜导线。是双向的。分为宽带电缆(多信道)和基带(窄带)电缆(单信道)。 双绞线:两根绝缘铜线绞合在一起。常用 5 类、6 类两种 光缆和光纤:不会受到电磁波干扰,涉及全反射理论。有单模光纤和多模光纤两类 非导引型媒体 开放空间的无线链路,双向。受到传播环境影响 地面微波 LAN(例如:WiFi) wide-area 广域无线(例如:蜂窝) 卫星 # Internet 结构和 ISP 互联网的结构:网络的网络 ISP,Internet Service Provider 互联网服务提供商(提供入网) ICP,Internet Content Provider 互联网内容服务商(提供业务) IXP,Internet Exchange Point 互联网交换中心 端系统通过接入 ISPs(住宅、公司和学校的 ISPs)连接到互联网。 接入 ISPs 相应的,必须是互联的。所以任何两个端系统,才可以互相发送数据 经济政治策略影响互联网演化 问题:如何将 ISP 互联?演化过程: 全连接,两个 ISP 直接相连,可扩展性差,不可扩展。复杂度为O(n)O(n)O(n) 每个 ISPs 都接入到 Global ISPs 中。以经济合约约束双方的行为。 Global ISPs 之间的竞争与合作 通常 ICP 如 Google 会在全球各地建造 DC(Data Center),然后自拉或者租用干线光缆,使得 DC 互联,原因有: ISP 的服务费用高 ISP 不能提供及时有效的服务 在大网里面部署专网,可以为用户提供较好的服务,并减少成本。 通常会在凉的地方(降温),高山之中(安全),地质稳定(不地震) 网络结构: Tier1 ISP(中心,第一层 ISP,全球、全国范围,点少但带宽大,通过 peer 连接或者 IXP 连接) Tier2 ISP:Rigional ISP,第二层 ISP,更小一些的,区域性的 ISP,可与一个或多个第一层 ISP 连接,也可以与其他第二层 ISP 连接 还有 Tier3 ISP 等 local ISP:access net,access ISP,终端通过 local ISP 接入。 # 分组延时、丢失和吞吐量 分组的丢失和延时是怎么发生的:路由器缓冲区中存在一个分组队列 如果分组达到路由器的速率大于链路输出的能力,那么对应地,分组进入分组队列等待,造成延迟。 四种延时每一跳都会产生这四种延时: 结点处理延时(校验错误,提取目标 ip 查路由表,进行其他处理,这个时间是比较固定的,可以预估,一般是微秒) 排队延时(取决于网络使用情况,是随机的) 传输延时(R 是链路带宽,L 是分组长度,将分组发送到链路上的时间是 L/R,是固定的,可以预估) 传播延时(与距离以及传播速度有关,距离如果超近,可忽略) 但是队列是有限的。如果队列已经满了,还来了新的分组,那么新分组就会被丢弃。这就是丢失。 丢失了怎么办? 如果链路本身可靠,则由上一个结点重传 如果链路不可靠,则由源主机重传 如果是 UDP,那么根本不重传 为什么不把队列调大一点,避免丢失?调大虽然不丢,如果有几千个分组,排队一两天到队头被转发,用户早就不耐烦了 信道容量:局域网容量小,广域网容量大。 流量强度:$$I=\\frac {La}{R}$$,其中 L 是每个分组的长度,a 是单位时间内通过这条链路转发的分组数,R 是链路带宽。 流量强度越接近极限值 1,排队延时越大。超过 1,排队延时无穷。流量强度越接近与 0 或较小的时候,排队延时就很小 同样的网络资源,分组交换允许更多的用户。 可以在 cmd 窗口运行 traceroute 命令,测量往返延迟,运用了 ICMP 协议:互联网控制报文协议。分为 IP 头、TTL 以及 IP 数据。 吞吐量:在源端和目标端之间的传输速率(数据量 / 时间单位) 瞬间吞吐量:在一个点的速率 平均吞吐量:在一个长时间的平均值 端到端的平均吞吐取决于瓶颈链路的大小。 实际情况,每一跳的链路,实际上都被很多用户共用,平分带宽。所以平分后的带宽才是瓶颈带宽 # 协议层次和服务模型 引例:异地哲学家的交流,航线的功能和层次。 分层的思想:把网络非常复杂的功能分解成功能明确的层次。每一层实现一个,或者一组功能。 本层的一些功能可以被上层调用。上层可以调用的本层功能的子集,就是服务。 协议是水平的一个关系,本层的协议实体相互交互实行本层协议动作,形成新的服务特性 协议的实现:通过层间接口访问下层服务才能实现,通过下层服务交换 PDU,实现本层的功能 协议的目的:为上层提供更好的服务 服务和服务访问点 服务提供者,通过层间界面具体的 SAP 服务访问点,向服务用户提供服务。 服务用户通过原语(提供服务的形式)使用服务提供者的服务,服务提供者通过原语向服务用户提供服务 服务访问点:上层访问下层所提供服务的点 服务的形式: 面向连接的服务,如 TCP(需要握手,建立连接) 无连接的服务,如 UDP(不需要建立连接) 服务是垂直的关系,层间的关系。 本层协议实现的时候,需要借助下层的服务。实现本层协议的目的,就是为了为上层提供更好的服务。 数据单元 DU 服务数据单元 SDU:上层要求传的东西。 SDU 穿过层间接口时,增加控制信息 ICR,变成了 IDU 穿过层间接口后,这个 ICR 就没用了,SDU 拿到之后,然后增加本层的 header,形成本层的 PDU。 如果 SDU 很大,那么可能会分成好几部分,分别加上 header,然后形成多个 PDU 也有可能 SDU 很小,那么我们可能会把好多个 SDU 拼在一起,然后加上 header,形成一个 PDU header 一部分是从 ICR 转过来的,一部分是协议新加的。 PDU 的不同称呼 应用层:应用报文 message 传输层:报文段(段)segment 网络层:分组(无连接:IP 数据报)packet 链路层:帧 frame 物理层:传的是比特 bit 分层处理的好处 概念化,结构清晰,分层参考模型。 结构化,分而治之。层间接口不变,那么层内具体实现无关,改变某一层的实现也不影响系统其他部分。 模块化,便于维护和系统升级。 分层处理的坏处 一层层实现,效率相对来说较低 但总体来说,好处比坏处多得多 Internet 协议栈(应用层最高,物理层最低) 应用层(可以进行应用报文交互) 传输层(传输层借助网络层主机到主机的服务,实现进程到进程的区分,借助 socket 和端口等。TCP 可将不可靠变为可靠) 网络层(源主机到目标主机的端到端的传输,可能不可靠) 链路层(传输以帧为单位的数据,区分哪些比特是帧的开始,哪些比特是帧的结束,中间夹着的就是帧的数据,在相邻两点间传输帧) 物理层(把一个个 bit 中数字信号转化为媒体信号,承载在媒体上,然后从一点传到另一点,然后再将物理信号反转成数字信号) ISO 的 OSI 七层模型 表示层:表示转换,解释传输的数据,关心语义方面的信息,不管怎么样编码。 会话层:数据交换的同步、检查、恢复。 封装和解封装 源主机大封装(按层从上到下封装),目的主机大解封装(按层从下到上解封装)。 路由器解封装三层(到网络层)。交换机解封装两层(到链路层)。 # 计算机网络的发展历史 早期 1960 前:线路交换(不适合。**1.** 线路建立时间长代价大,**2.** 线路交换资源独享,不适合突发性很强的计算机通信,**3.** 可靠性不高,核心节点一旦损毁,影响很大) 分组交换的研究 1962-1972:三个研究小组分别展开。突发性强的情况下,比较适合计算机之间的通信。 1969 年,第一个 ARPAnet 节点开始工作,给军方使用。这个节点叫做 IMP 接口报文处理机。1969 年底(4 个节点)。 1972 年,第一个 email 程序发布,ARPAnet 有了 15 个节点。 专用网络和网络互联 1972-1980 很多专用网络出现。但是标准多,混乱。IBM 内部的标准就有 40 多种。更不要说各种不同的公司要互联互通 用覆盖的方式,解决网络互连 如果弃用原来的所有设备,另起炉灶虽然好,可以解决互连,但成本大。 采用覆盖的方式,解决互连:ip 层之下,各个网络各管各的(每种类型的物理网络分配一个 ip 头),在 ip 层上统一成 ip 网络,路由器将 ip 数据报取出,然后转发,打入另一个物理网络。原来的网络可以完美利用 网络 IP 提供的服务是最小限度的,尽力而为的服务。在端系统,通过 TCP 协议保证可靠。路由器不维护通信状态。 投资保护性很强,包容性很强。只需要改变一下软件,网络就可以接入互联网。 NCP 协议变化为 TCP/IP(一层变两层) 1983,ALOHA net 所有设备停机,进行软件升级,升级到新的协议栈。层次的变化,将主机设备和路由设备区分开来了。对当时来说也是一个 IP 协议的包容性:在 IP 层上可以统一部署各种应用。IP 可以将底层的所有物理架构包容起来。 1982 SMTP 协议可实现 email,1983 DNS 协议被定义实现域名解析,1985 实现了 FTP,1988 TCP 加入了拥塞控制 1990 左右,ARPAnet 是美国军方支持的,NSF net 是 ARPAnet 的访问网。 1994 Netscape 公司成立弄出了 Netscape 浏览器。 出现了即时通信、P2P 文件共享,等杀手级应用。促进了 ISP 扩容。但安全性问题以及地址不够的问题不断突出。 2001 网络泡沫一些烂公司倒闭了,好公司(包括微软雅虎谷歌思科等)得以沉淀。 ……","categories":[{"name":"计算机科学","slug":"computer-science","permalink":"http://blog.sunforge.cn/categories/computer-science/"},{"name":"计算机网络","slug":"computer-science/计算机网络","permalink":"http://blog.sunforge.cn/categories/computer-science/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/"}],"tags":[{"name":"笔记","slug":"笔记","permalink":"http://blog.sunforge.cn/tags/%E7%AC%94%E8%AE%B0/"}]},{"title":"更新Hexo主题为Shoka","slug":"computer-science/hexo/更新Hexo主题为Shoka","date":"2022-07-01T02:26:23.000Z","updated":"2022-10-18T12:44:06.648Z","comments":true,"path":"computer-science/hexo/更新Hexo主题为Shoka/","link":"","permalink":"http://blog.sunforge.cn/computer-science/hexo/%E6%9B%B4%E6%96%B0Hexo%E4%B8%BB%E9%A2%98%E4%B8%BAShoka/","excerpt":"","text":"# 背景 原本使用的 pure 主题非常简约优秀,已经基本完成配置。 寻到一个更戳我的高颜值主题 shoka ,所以更换主题。 # 主题变换 将 shoka 主题 fork 到自己的仓库,然后在本地 hexo 根目录下运行命令: git submodule add https://github.com/你的Github用户名/hexo-theme-shoka.git themes/shoka 修改站点配置文件 <root>/_config.yml ,将主题改为 shoka ltheme: shoka 修改主题配置 参考 shoka 文档,进行主题配置。Theme Shoka Documentation (lostyu.me) 注意:如果 algolia 相关字段存在,却没有正确配置 appid 和 apikey 等参数,博客会产生页面异常。(具体表现为首页轮播图失效变黑,以及页面滚动失效。) 注意:如果使用 <root>/themes/shoka/example/source 文件夹来替代 <root>/source 文件夹,会出现顶部标题栏和搜索栏背景失效的情况 此时需要打开 <root>\\source\\_data 目录下的 colors.styl 文件,找到第 47 行,加入以下配置即可正常显示 --nav-bg: linear-gradient(-225deg, var(--color-cyan-light) 0, var(--color-pink-light) 100%); 配置 valine 评论 需要在 leancloud 平台注册账号。国内建议选择华东区,国外建议选择国际版。然后参照文档申请 appid 和 appkey 并配置即可。 # 配置 shoka 主题必看的文档教程 Hexo 主题 Shoka & multi-markdown-it 渲染器使用说明 - Theme Shoka Documentation - 二进制杂谈 - 计算机科学 | Yume Shoka = 優萌初華 = 有夢書架 (lostyu.me) Hexo 博客搭建:基础配置主题:shoka] - hexo - blog | Moe Hz = 萌 Hz | 木白の时记 = 日々私たちが过ごしている日常は、実は、奇迹の连続なのかもしれない Hexo-Shoka 主题功能介绍补充点 | ReverseSacle-Blog = 逆转天平 = 执着过去的人,无法迈向未来 Algolia 使用教程 , 超详细傻子看都会 - 天的博客 (cnblogs.com)","categories":[{"name":"计算机科学","slug":"computer-science","permalink":"http://blog.sunforge.cn/categories/computer-science/"},{"name":"Hexo博客","slug":"computer-science/hexo","permalink":"http://blog.sunforge.cn/categories/computer-science/hexo/"}],"tags":[{"name":"教程","slug":"教程","permalink":"http://blog.sunforge.cn/tags/%E6%95%99%E7%A8%8B/"},{"name":"Hexo","slug":"Hexo","permalink":"http://blog.sunforge.cn/tags/Hexo/"}]},{"title":"通过Github管理Hexo博客源码,并配置Github Action自动编译部署","slug":"computer-science/hexo/使用Github管理Hexo博客源码,并配置Github-Action自动编译部署","date":"2022-06-27T07:33:01.000Z","updated":"2022-10-18T12:44:06.636Z","comments":true,"path":"computer-science/hexo/使用Github管理Hexo博客源码,并配置Github-Action自动编译部署/","link":"","permalink":"http://blog.sunforge.cn/computer-science/hexo/%E4%BD%BF%E7%94%A8Github%E7%AE%A1%E7%90%86Hexo%E5%8D%9A%E5%AE%A2%E6%BA%90%E7%A0%81%EF%BC%8C%E5%B9%B6%E9%85%8D%E7%BD%AEGithub-Action%E8%87%AA%E5%8A%A8%E7%BC%96%E8%AF%91%E9%83%A8%E7%BD%B2/","excerpt":"","text":"# 背景 前述的 Hexo 博客方案的运行模式是:本地写作、本地编译、远端部署。 一旦本地的博客环境受到破坏,那么博客源文件就会丢失。 所以妥善管理源代码就是十分必要的。 但由于源代码中,引入了各种插件,存放着不少 appid 和 appkey 。这些信息不合适公开存放在 github 的 public 仓库里。 如今比较推荐的方案是: 用 github 私有仓库存储博客源码 配置 github action 监听博客源码仓库的 push 事件 当 push 事件触发时, github action 自动对博客源码仓库进行编译 编译结果推送到正式博客公开仓库 不论使用 github page 部署博客,还是使用前述的 vercel 部署博客,都建议这样配置自己的 Hexo 博客。 当然,如果使用 vercel 的话,可以将自己的私有仓库直接授权给 vercel ,这样可以免去使用 github action 的麻烦,在 vercel 上选择 Hexo 模板,剩下的就交给 vercel 了。 # 设置 Github Action # 代码仓库准备 首先新建私有的博客源代码仓库,命名随意。比如 hexo-blog-src 博客发布的公开仓库要么是 你的github用户名.github.io (假如使用 github page 托管),要么是自定义的一个仓库(不论公开或私有,假如使用 vercel 托管) 在本地,使用 git 工具,连接 hexo-blog-src 仓库(不必上传 node_modules 文件夹) # 使用 git 的 submodule 管理 hexo 主题 参考文档:为 Hexo 博客更换主题 - 知乎 (zhihu.com) 前文,在安装 pure 主题时,使用的命令为: hgit clone https://github.com/cofess/hexo-theme-pure.git themes/pure产生了一个问题: 用 git clone 是把一个独立的仓库克隆到我们的的 Hexo 源码中,但同时,我们的 Hexo 源码也是一个仓库,所以两个仓库产生了父子关系。即 Pure 主题仓库成为了我们 Hexo 主仓库下的一个独立子仓库 但在 git 的设计上,父仓库不会对子仓库进行管理。这样就违背了我们用 Git 进行 Hexo 博客版本控制的初衷。 可以删除 pure 项目下的 .git 文件,把 themes/pure 变成一个普通的目录,这样就取消了父子仓库关系。但是如果后续主题作者有更新,就不能直接用 git pull 拉取更新,而是需要手动安装,覆盖原来的文件,重新配置主题,不易维护。 当我们进行 git add * 的时候, Git 会报错 warning: adding embedded git repository: themes/hexo-theme-purehint: You've added another git repository inside your current repository.hint: Clones of the outer repository will not contain the contents ofhint: the embedded repository and will not know how to obtain it.hint: If you meant to add a submodule, use:hint: hint: git submodule add <url> themes/hexo-theme-purehint: hint: If you added this path by mistake, you can remove it from thehint: index with:hint: hint: git rm --cached themes/hexo-theme-purehint: hint: See \"git help submodule\" for more information.如果强行 push ,在 GitHub 上会显示子模块图标,但是不知道这个模块仓库所在的 url ,因此在 GitHub 上无法打开这个文件夹。 解决方案: 好在 Git 提供了子模块 submodule 功能,可以优雅地避免上面的问题。它允许我们将一个 Git 仓库作为另一个 Git 仓库的子目录,同时还保持提交的独立。 但是,直接在终端输入如下的代码,仍然是不妥当的 git submodule add https://github.com/cofess/hexo-theme-pure.git themes/pure为什么呢?其实这样子,在我们本地修改和使用主题的时候是没有问题的 但是当我们要把修改提交到 GitHub 时,会导致我们把自己的文件,提交到主题原作者的仓库去,这显然是不合适的(也提交不上去,没有权限) 因此,下载主题的正确操作流程应该是这样的: 在 GitHub 上,把原作者的主题 fork 到我们自己的仓库中 运行以下命令,把 Pure 主题添加为我们博客的子模块 git submodule add https://github.com/你的Github用户名/hexo-theme-pure.git themes/pure成功添加子模块后,目录下会生成 .gitmodules 文件,再次运行 git add * 添加 .gitmodule 文件和子模块文件夹。此时不会报错,随后依次运行 git commit -m "your message" 和 git push 命令提交更改。 或使用 Git 的图形界面客户端,比如 Github Desktop 或 SourceTree 等 此时, Github 界面上显示如图。 可以看到, pure 文件夹已经成为蓝色。然后显示了 @17dcbb1 的字样。实际上 @17dcbb1 是 pure 仓库里最新提交记录的 hash 值。 如果点击这个链接,会跳转到之前从 cofess/hexo-theme-pure 仓库 fork 过来的仓库 BEATING-HEART/hexo-theme-pure 中。 可以类比 C 语言中的指针来理解 # 配置 Github Token 参考文档:通过 GitHub Actions 实现私有仓库的免费 Github Pages 部署 - 掘金 (juejin.cn) 首先,配置个人 github token 有的教程也会使用 ssh-keygen 命令生成密钥对。此处我们采用 github token 的方式管理仓库的访问权限。 进入 developer settings 配置界面后,选择 personal access token 选项卡,点击 generate new tokens 按钮,添加新 token 然后跳转到如图所示界面,按照下图配置即可。 其中, token 命名随意,没有特殊要求。过期时间可以选择永不过期。由于还涉及到私有仓库,所以必须要把 token 所有 repo 相关的权限全部打开。 最后会生成这样的一个 token ,需要妥善处理,做好复制(如图, token 只会显示这一次)。为保密,不建议保存在本地或其他任何地方。 将这个 token 复制下来,部署到 hexo-blog-src 仓库中去。 进入 hexo-blog-src 仓库,在 settings 中选择 secret 选项卡,并添加 repository secret 将刚才复制的内容,填写到弹出页面的 Value 字段中,并命名(可任意命名)例如 MY_REPO_TOKEN 。 # 编写 Github Action 代码 参考文档:[用 GitHub Actions 自动部署 Hexo | 老苏的 blog (laosu.ml)](https://laosu.ml/2022/01/24 / 用 GitHub Actions 自动部署 Hexo) 在本地的 git 仓库根目录,新建文件 .github/workflows/hexo-blog-deployer.yml 文件。 文件名实际上是任意的。但文件格式必须是 yml 格式。文件目录不可以改变,必须在 .github/workflows 文件夹下 name: Deployon: [push]env: # 根据自己情况修改 GIT_USER: BEATING-HEART GIT_EMAIL: [email protected] GITHUB_REPO: BEATING-HEART/hexo-blog GITHUB_REOP_BRANCH: mainjobs: build: runs-on: ubuntu-latest name: A job to deploy blog. steps: - name: Checkout uses: actions/checkout@v3 with: token: $<!--swig0--> # 这个就是刚刚添加的secret(也就是前面生成的personal access token) # 此处 $ 的格式就是环境变量的格式,下同 # 如果不加token字段,会使用默认的token,但不能访问对应的submodule submodules: true # Checkout private submodules(themes or something else). - name: Setup-Node uses: actions/setup-node@v3 with: node-version: '16' cache: 'npm' cache-dependency-path: '**/package-lock.json' # setup-node 的时候,会根据 package-lock.json 来安装依赖 # 所以 package-lock.json 这个文件一定要提交到 github 上去 - run: npm ci # npm ci 命令,多用于自动化平台。与 npm install 功能类似,也有部分区别。 - name: Hexo clean & generate run: | ./node_modules/hexo/bin/hexo clean ./node_modules/hexo/bin/hexo generate echo -e \"\\033[33m [success] hexo clean & generate finished \\033[0m\" # 实际上,刚开始的时候,直接运行的 hexo clean 结果报错没找到目录或文件。 # 后来尝试了很多,比如使用 npm config get prefix 找到 npm 目录,然后寻找 hexo。但都失败了。 # 最终使用 ls . 命令列出了当前文件夹下的文件目录,才在 node_modules 文件夹中找到 hexo # 上面 echo 命令里面,控制了文字颜色为黄色。 - name: Hexo deploy run: | cd ./public git init git config user.name \"$\" git config user.email \"[email protected]\" git remote add origin \"https://[email protected]/$.git\" # 这里使用了github的token验证功能。是往博客正式仓库中推送内容。 git checkout --orphan $ # orphan,意为孤儿,此命令会生成一个没有历史提交记录的分支。 git add --all echo -e \"\\033[33m Start Commit \\033[0m\" git commit --allow-empty -m \"Site updated: $(TZ=UTC-8 date +%Y-%m-%d\" \"%H:%M:%S)\" # 按照shell中的时间控制串格式,设置时区为东八区,然后显示年月日时分秒。 echo -e \"\\033[33m Start Push \\033[0m\" git push origin \"$\" --force echo -e \"\\033[33m Deployment succesfully! \\033[0m\" 当仓库发生 push 事件时,该 action 脚本将会自动执行。 ${{ xxx }} 表示环境变量 env 字段中的值,需要根据自己情况修改 # 发布博客,测试部署 在本地编辑文档,然后上传到 hexo-blog-src 仓库,触发 github action ,自动向 hexo-blog 仓库提交代码,随后网站页面自动更新。 # 参考文档 GitHub Actions 入门教程 - 阮一峰的网络日志 (ruanyifeng.com) 用 GitHub Actions 自动部署 Hexo | 老苏的 blog (laosu.ml) Github Actions: submodule 下公私有仓库授权和通信 - 知乎 (zhihu.com) actions/checkout: Action for checking out a repo (github.com) actions/cache: Cache dependencies and build outputs in GitHub Actions actions/setup-node: Set up your GitHub Actions workflow with a specific version of node.js","categories":[{"name":"计算机科学","slug":"computer-science","permalink":"http://blog.sunforge.cn/categories/computer-science/"},{"name":"Hexo博客","slug":"computer-science/hexo","permalink":"http://blog.sunforge.cn/categories/computer-science/hexo/"}],"tags":[{"name":"教程","slug":"教程","permalink":"http://blog.sunforge.cn/tags/%E6%95%99%E7%A8%8B/"},{"name":"Hexo","slug":"Hexo","permalink":"http://blog.sunforge.cn/tags/Hexo/"}]},{"title":"使用vercel托管Hexo博客,解决github.io无法被baidu收录的问题","slug":"computer-science/hexo/使用vercel托管Hexo博客,解决github-io无法被baidu收录的问题","date":"2022-06-27T03:07:16.000Z","updated":"2022-10-18T12:44:06.644Z","comments":true,"path":"computer-science/hexo/使用vercel托管Hexo博客,解决github-io无法被baidu收录的问题/","link":"","permalink":"http://blog.sunforge.cn/computer-science/hexo/%E4%BD%BF%E7%94%A8vercel%E6%89%98%E7%AE%A1Hexo%E5%8D%9A%E5%AE%A2%EF%BC%8C%E8%A7%A3%E5%86%B3github-io%E6%97%A0%E6%B3%95%E8%A2%ABbaidu%E6%94%B6%E5%BD%95%E7%9A%84%E9%97%AE%E9%A2%98/","excerpt":"","text":"# 背景 用了一段时间的博客,发现百度并没有收录我的文章。尽管我已经配置了 hexo-baidu-url-submit 插件,也无效。 查询资料发现,Github 禁止了 baidu 爬虫访问 github.io 网页,配置 hexo-baidu-url-submit 插件无法解决这个问题。 于是开始寻找替代方法。 # 探索 网上有很多方法可以使百度爬虫爬取博客页面,总结起来主要有: CDN,利用云服务提供商将 blog 多做几个镜像。 CDN 比较贵 换托管平台,比如说国内的代码托管平台。 比如 gitee 。但 gitee 需要开源审核,不想用 gitee page 了。 有些教程会说到 coding 平台,目前 coding 平台并入腾讯云,如果使用静态网站托管服务,需要付费。 自行使用 VPS 托管。VPS 大陆访问速度不快 # 解决方案:使用 vercel(zeit)托管 Guillermo Rauch 大神创业搞了一个静态站 hosting 服务 zeit.co : http://zeit.co 现在已经重定向到了 Develop. Preview. Ship. For the best frontend teams – Vercel 可以通过 GitHub 实现自动部署, vercel 提供 存储 + CDN + DNS 一套完整的服务,截至目前(2022-06)在中国大陆可以正常访问。 ** 换而言之,不用 github page 了。** 而且 vercel 免费,可以白嫖。 进入首页,点击右上方的 sign up 按钮,进入登录界面 通过 Github 账号授权登录。 选择 Github 为 Git 源 添加 Github 账户。 vercel 会作为 github app 被安装到 Github 账户上。 设置 vercel 对 github 仓库的访问权限 vercel 网页会自动跳出设置界面 也可以去 github 官网上配置。 在 github 的账号 setting 界面( https://github.com/settings/installations ),点击 applications ,设置 ``vercel` 的权限 往下拉,设置 permissions 和 repository access 经过授权,可以访问包括私有仓库在内的所有 github 仓库。此处我仅选择开放了部分仓库。 在控制面板中,点击 New Project 按钮,新建项目 选择新建项目,导入对应博客的仓库后,不做任何调整(保持 other 模板,root 设置为 ./ 即可),直接点击部署按钮,也就是 deploy 按钮。项目即完成部署。 注意:使用 vercel 部署,可以完全替代 github page 的功能 换言之,可以不使用 你的github用户名.github.io 这个特殊仓库 项目完成部署后,按照下述步骤,可以配置自己的域名。 按照报错信息教程,做好域名配置即可 我的域名在阿里云,所以在阿里云的 DNS 解析上添加一条 CNAME 记录,即可使用自己的域名,正常显示博客。而且 vercel 也会自动签发 HTTPS 证书。 随后再向百度站长工具提交链接,就能保证内容被抓取。 # 参考文献 解决 github 屏蔽百度爬虫的问题 - 知乎 (zhihu.com) 使用 zeit.co 托管 hexo 静态博客 - 知乎 (zhihu.com) 如何让百度收录 GitHub Pages 个人博客 - 大数据 - 亿速云 (yisu.com)","categories":[{"name":"计算机科学","slug":"computer-science","permalink":"http://blog.sunforge.cn/categories/computer-science/"},{"name":"Hexo博客","slug":"computer-science/hexo","permalink":"http://blog.sunforge.cn/categories/computer-science/hexo/"}],"tags":[{"name":"教程","slug":"教程","permalink":"http://blog.sunforge.cn/tags/%E6%95%99%E7%A8%8B/"},{"name":"Hexo","slug":"Hexo","permalink":"http://blog.sunforge.cn/tags/Hexo/"}]},{"title":"用Hexo搭建个人博客(使用Pure主题)并托管到Github Page","slug":"computer-science/hexo/用Hexo搭建个人博客(使用Pure主题)并托管到Github-Page","date":"2022-06-24T11:27:29.000Z","updated":"2022-10-18T12:44:06.652Z","comments":true,"path":"computer-science/hexo/用Hexo搭建个人博客(使用Pure主题)并托管到Github-Page/","link":"","permalink":"http://blog.sunforge.cn/computer-science/hexo/%E7%94%A8Hexo%E6%90%AD%E5%BB%BA%E4%B8%AA%E4%BA%BA%E5%8D%9A%E5%AE%A2%EF%BC%88%E4%BD%BF%E7%94%A8Pure%E4%B8%BB%E9%A2%98%EF%BC%89%E5%B9%B6%E6%89%98%E7%AE%A1%E5%88%B0Github-Page/","excerpt":"","text":"本文讨论的是在 Windows 环境下,安装使用 Hexo 博客。 # 什么是 Hexo Hexo 是一个快速、简洁且高效的博客框架。Hexo 使用 Markdown(或其他渲染引擎)解析文章,在几秒内,即可利用靓丽的主题生成静态网页。 # Hexo 框架安装 # 安装准备 安装 Node.js 环境(最低要求 10.13,推荐 12.0 以上)安装教程:Node.js 安装与配置详解 - 知乎 (zhihu.com) 安装 Git 安装教程: Git 详细安装教程(详解 Git 安装过程的每一个步骤)_mukes 的博客 - CSDN 博客_git 安装 # 安装 Hexo-cli 通过 npm 工具,安装 Hexo npm install -g hexo-cli 高级安装(略)可参考:Documentation | Hexo # Hexo 初始化 选定一个文件夹,运行下面的命令,对本地的 hexo 进行初始化 hexo init <folder>cd <folder>npm install初始化后,该文件夹下的目录结构如图: w.├── _config.yml├── package.json├── scaffolds├── source| ├── _drafts| └── _posts└── themes# 本地测试启动 Hexo hexo clean # 清除缓存hexo g # 生成静态文件 也作 hexo generatehexo s # 本地启动 Hexo 也作 hexo server默认主题是 landscape ,效果如图 拿了别人博客的图,打个码,总之效果就是这样。 运行上述命令后,访问 http://localhost:4000 查看效果。 如果不喜欢 4000 这个端口,可以使用命令 hexo server -p 1314 来改变端口为 1314 。 至此,安装 Hexo 完成。 # Hexo 配置 若运行以下命令,可以新建文章。 hexo new \"your title\"打开 博客根目录/source/_posts 目录,可以看见命令生成的 your-title.md 文件 随后就可以编写博客。 但,工欲善其事,必先利其器。正式写博客之前,需要对框架做一些配置,使其支持图片插入,Latex 公式显示以及标题自动翻译。 # 图片显示 参考文档:使用 hexo 新建、编辑并预览文章 - 知乎 (zhihu.com) Hexo 插入图片,需要指定资源文件夹,步骤如下 在博客根目录打开 _config.yml 文件做如下修改: post_asset_folder: true 使用 hexo 新建文章,此时会创建同名文件夹。 使用 typora 编辑器,编写文档。调整 Typora 编辑器的默认图片路径。然后插入图片,就会自动添加到上述的同名文件夹中。 安装插件 hexo-asset-image hnpm install hexo-asset-image --save 运行命令,部署博客,查看效果。发现图片已经能够正常显示。 # Latex 数学公式显示 参考文档:hexo-theme-pure #数学公式 (github.com) 变换默认 Hexo 的 Markdown 渲染引擎 hnpm un hexo-renderer-marked --savenpm i hexo-renderer-markdown-it-plus --save 修改 Hexo 项目根目录下的配置文件 _config.yml markdown_it_plus: highlight: true html: true xhtmlOut: true breaks: true langPrefix: linkify: true typographer: quotes: “”‘’ plugins: - plugin: name: markdown-it-katex enable: true - plugin: name: markdown-it-mark enable: false然后依次运行 hexo clean 和 hexo g -d 命令,如果报错说,不存在依赖 markdown-it-katex 则还需另外安装 hnpm i markdown-it-katex --save 在 Hexo 模板中启用 mathjax 渲染 从 Hexo 项目根目录,进入 scaffolds 文件夹,修改 post.md 模板,修改以下内容 title: 用Hexo搭建个人博客(使用Pure主题)并托管到Github Pagedate: 1656070049000mathjax: true # 此处是添加部分tags: 在博客中,添加 Latex 公式,编译部署。Latex 公式能够正常显示。 # 安装配置 hexo-neat 插件 参考文档:hexo-theme-pure #hexo-neat (github.com) 自动压缩 html,css,js 等代码,减小生成文件的体积。 hnpm install hexo-neat --save然后在 Hexo 配置文件 ./_config.yml 中添加以下代码 # hexo-neatneat_enable: trueneat_html: enable: true exclude: neat_css: enable: true exclude: - '*.min.css'neat_js: enable: true mangle: true output: compress: exclude: - '*.min.js'# 404 错误的排除:设置标题自动翻译 hexo 文件标题如果含有中文字符,可能会产生 404 错误。特别是如果要部署到 Github 等平台,必须要配置这个标题自动翻译。 推荐使用 hexo-translate-title 插件。 参考文档: Hexo,添加标题翻译插件 - 简书 (jianshu.com) cometlj/hexo-translate-title: 使用 Google 翻译,百度翻译和有道翻译将 Hexo 文章中的汉字标题转成英文标题 (github.com) 使用 npm 工具,安装 hexo-translate-title 插件 npm install hexo-translate-title --save 配置 Hexo 博客。在博客项目根目录下的配置文件 _config.yml 中,添加下述字段。 ltranslate_title: translate_way: baidu_with_appid # google,youdao,baidu_with_appid,baidu_no_appid # youdao_api_key: '' # Your youdao_api_key # youdao_keyfrom: xxxx-blog # Your youdao_keyfrom is_need_proxy: false # true | false # proxy_url: http://localhost:50018 # Your proxy_url baidu_appid: '' # Your baidu_appid baidu_appkey: '' # Your baidu_appkey rewrite: false # is rewrite true | false 由于 google 翻译可能受到影响。因此,若使用 google 翻译,可能需要使用本地代理。 baidu_no_appid 不起作用了,会有报错。 所以只能选择 youdao 或 baidu_with_appid 。对应的 appid 和 key 需要到对应官网去申请 文本翻译_机器翻译_在线翻译 - 有道智云 AI 开放平台 (youdao.com) , 百度翻译开放平台 (baidu.com) 配置好翻译接口后,运行 hexo clean 命令,再运行 hexo g 命令。翻译生效。此时,可以运行 hexo s 命令,本地启动博客。博客链接已经替换成了翻译生成的英文标题。 Hexo 博客的基础配置已经全部完成。 # 博客发文 前面说到,运行 hexo new "your title" 命令,可以新建博客文章。 在 博客根目录/source/_posts 目录,编辑生成的 your-title.md 文件,保存后,依次运行 hexo clean , hexo g 和 hexo s ,即可在本地启动博客。 为更方便发文,首先修改模板:从 Hexo 项目根目录,进入 scaffolds 文件夹,修改 post.md 模板为: title: 用Hexo搭建个人博客(使用Pure主题)并托管到Github Pagedate: 1656070049000mathjax: truecategories:tags:** 随后开始新建文章:** 我使用 hexo new "testblog" 命令,新建了博客 testblog ,此时,文件夹 博客根目录/source/_posts 中自动生成了以下两个文件 打开 testblog.md 文件后,框架为我们自动生成了以下内容。 title: testblogmathjax: truetranslate_title: testblogdate: 2022-06-26 13:39:42categories:tags: 其中 translate_title 是上述 hexo-translate-title 插件生成的。 其余字段是 post.md 模板生成的。 编辑好博客内容后。我们还可以对文章增加标签和目录。以本文为例。 title: 用 Hexo 搭建个人博客(使用 Pure 主题)并托管到 Github Pagemathjax: truetranslate_title: set-up-a-personal-blog-with-hexo-(using-the-pure-theme)-and-host-it-to-github-pagedate: 2022-06-24 19:27:29categories: - Hexotags: - 教程本文就会自动出现分类和标签,并展示。 # 部署 Hexo 到 Github Page 托管 # Github 访问加速 如果不会魔法上网操作,可以使用 Github 大神 dotnetcore 开发的 FastGithub 客户端。 # 在 Github 上构建仓库 新建一个仓库,命名为: 你的Github用户名.github.io 【必须这么命名,这个仓库会被识别为特殊仓库】 Github用户名 大小写最好区分【一些教程中统一用的小写,我没试过】 我的用户名是 BEATING-HEART ,所以,我的仓库命名为 BEATING-HEART.github.io # 配置 Github SSH 登录 见本站另一博客。【详解】配置 github 的 ssh key (Windows) | Sunforge's Blog # 调整 Hexo 配置 打开 Hexo 项目文件夹目录下的 _config.yml 文件,拉到最底部,修改 deploy 字段为: # Deployment## Docs: https://hexo.io/docs/one-command-deploymentdeploy: type: git repo: [email protected]:你的Github用户名/你的Github用户名.github.io.git branch: main 本人的用户名是 BEATING-HEART , 所以,本人在上述的 repo 字段中填写的是 [email protected]:BEATING-HEART/BEATING-HEART.github.io.git 注意,这里必须配置 SSH key 后,使用 Git 地址,否则可能需要登录验证。 # 部署 Hexo 在 Hexo 目录中,执行以下命令: npm install hexo-deployer-git --save #安装部署工具hexo clean # 清除缓存hexo g # 生成静态文件 也作 hexo generatehexo d # 部署 Hexo 到 Github 也作 hexo deploy运行结束后,在浏览器中输入 http://你的Github用户名.github.io 就可以访问博客。 比如访问 https://beating-heart.github.io/ 就可以到我的博客。 但由于我配置了域名,这个连接会被重定向到 https://blog.sunforge.cn/ # 绑定域名(非必选) 购买域名后,打开域名控制台,添加解析记录【这里以阿里云域名为例】 选择记录类型为 CNAME 添加主机记录(域名二级地址)这里我分配了 blog 这个地址。 这样一来,访问我的博客就是用 blog.sunforge.cn 这个域名 记录值就是上面设置的,你的 github 的域名(我的域名是 beating-heart.github.io ) TTL 值和解析路线值,保持默认即可 在 Github 网站上,配置博客域名 首先进入博客配置的仓库 进入设置界面,转到 pages 选项卡 添加自定义域名为你自己的域名 和上一步添加的解析记录保持一致,例如我的域名是 blog.sunforge.cn 勾选 HTTPS 选项,Github 可以自动给你的域名配置 SSH 证书 白嫖使人快乐 访问博客,查看效果。 (此时的主题是默认的 landscape 主题) 如果你没有域名,那么必须遵从上面的步骤配置,采用规定的仓库命名方式。 github 会为你统一分配域名为 https://你的github用户名.github.io/ 如果你有域名,则可以不遵守上面的配置,意命名你的 github 仓库。只需要在上述页面中,绑定自己的域名,即可将页面部署到自己的域名下。 # 设置 Hexo 主题(非必须) Hexo 默认主题可以满足大多使用需要,可以不更换主题。 # Hexo 主题的挑选 可访问 Themes | Hexo 挑选心仪主题,也可查看 CSDN、博客园平台发布的经验贴。 # 配置 Pure 主题 Pure 主题参考效果:Cofess - Web Developer & Designer 参考文档:cofess/hexo-theme-pure 中文说明文档 (github.com) Hexo 主题 pure 使用指南 | 非典型性程序员 (plcent.com) 1. 启用 pure 主题 修改 Hexo 项目根目录下的配置文件 _config.yml language: zh-CN # 设置主题为中文版,若使用英文版则不修改theme: pure # 修改 hexo 主题随后复制 博客根目录/themes/pure/_source/ 目录下的所有内容到 博客根目录/source/ 目录下,使用默认的菜单 categories (分类)、 tags (标签)、 repository (项目)、 books (书单)、 links (友链)、 about (关于) 页面。 并且将主题配置文件 博客根目录/themes/pure/_config.yml ,移动到并重命名为 博客根目录/_config.pure.yml 每个主题,都有一个主题配置文件,存放在 博客根目录/themes/pure/_config.yml 中。Hexo 默认会读取这个文件的内容。 为了方便修改,我们将博客配置文件移动到并重命名为 博客根目录/_config.主题名.yml 。此时 Hexo 会读取根目录下的这个新配置文件的内容。 根据官方文档 配置 | Hexo,如果有两个配置文件,配置内容会 “互通有无”,所以,应当集中在同一个配置文件中修改。 效果如图: 2. 开启字数及阅读时间统计 主题内置了该功能,使用前需要先安装插件: npm i -S hexo-wordcount npm 命令中 install 可以缩写为 i , --save 可以缩写成为 -S 在主题配置文件中(根目录下的主题配置文件 _config.pure.yml ), 开启设置即可: # wordcountpostCount: enable: true ## 从 false 修改成 true wordcount: true # 文章字数统计 min2read: true # 阅读时长预计3. 开启站内搜索功能 主题中已经内置。首先需要安装 hexo-generator-json-content 插件。 npm install hexo-generator-json-content --save然后在主题配置文件 博客根目录/_config.pure.yml 中修改添加如下属性。 search: insight: true # you need to install `hexo-generator-json-content` before using Insight Search baidu: false # you need to disable other search engines to use Baidu search即可使用站内搜索功能 4. 支持 rss 订阅 主题中已经内置好了,只需要安装插件即可。 npm install hexo-generator-feed --save5. 生成站点地图 站点地图描述了网页的架构,生成站点地图可以方便搜索引擎收录你的博客。 npm install hexo-generator-sitemap --savenpm install hexo-generator-baidu-sitemap --save更改完成后,每次进行打包的时候,会自动在 public 文件夹下生成 sitemap.xml 和 baidusitemap.xml 分别用于 Google 和百度。 将页面提交到服务器后,通过 域名/sitemap.xml 或者 域名/baidusitemap.xml 可以进行访问 sitemap 。 最后到 Google 或百度站长工具进行提交 sitemap 就可以主动使搜索引擎收录页面。 6. 配置主题颜色 主题定制了五套颜色,可以在主题配置文件 _config.pure.yml 中更改。 默认白,黑:theme-black,蓝:theme-blue,绿:theme-green,紫:theme-purple # configconfig: skin: # 主题颜色 theme-black theme-blue theme-green theme-purple7. 配置导航菜单 # 导航菜单menu: Home: . Archives: archives # 归档 Categories: categories # 分类 Tags: tags # 标签 # Repository: repository # github repositories # Books: books # 书单 Links: links # 友链 About: about # 关于# 导航菜单图标(font awesome)menu_icons: enable: true # 是否启用菜单图标 home: icon-home-fill archives: icon-archives-fill categories: icon-folder tags: icon-tags # repository: icon-project # books: icon-book-fill links: icon-friendship about: icon-cup-fill 我将书单和 github 仓库关闭了,所以不配置相关内容。 8. 设置个人信息 头像在 themes\\pure\\source\\images 目录下替换图片即可,捐献的二维码同理。个人信息大部分都在 主题配置文件 中设置 9. 设置分享 支持 weibo,qq,qzone,wechat,tencent,douban,diandian,facebook,twitter,google,linkedin # Share# weibo,qq,qzone,wechat,tencent,douban,diandian,facebook,twitter,google,linkedinshare: enable: true # 是否启用分享 sites: weibo,qq,wechat,facebook,twitter # PC 端显示的分享图标 mobile_sites: weibo,qq,qzone # 移动端显示的分享图标10. 侧边栏设置 在文章头部自动生成的配置栏中,添加字段如下 title: testblogmathjax: truetranslate_title: testblogdate: 2022-06-26 13:39:42toc: true ### toc: table of content 目录categories:tags:此时,文章右侧显示出目录。 如果在增加配置 sidebar: none ,则右侧目录组件(或原组件)就不会显示。 但这个目录功能有一个 bug,如果是手机访问的话,这个目录会浮动在内容上面,遮挡内容。 改天有时间了尝试着修复下。 # Pure 主题博客优化(非必须) 博客如果只作笔记,以记录作用为主,那么可以不配置下面的内容。 如果要作为个人主页来展示,那么,建议继续配置以下内容。 1. 文章阅读量统计 主题内置了 不蒜子 统计和 基于 leancloud 的统计 开启不蒜子统计: 在主题配置文件中(根目录下的主题配置文件 _config.pure.yml ), 开启设置即可: # PVpv: # 浏览量统计 busuanzi: enable: true # 不蒜子统计,一般使用不蒜子统计,使用 true 开启 经过验证,发现基于 leancloud 的统计不生效,不知原因,实现等效的方法就是: 评论框使用 valine 评论框 (主题已经内置), 同时开启 visitor: true 配置项即可。 2. 配置评论功能 参考文档:快速开始 | Valine 一款快速、简洁且高效的无后端评论系统。 Valine 是一个无后端的评论框工具,其依赖于 Leancloud 开发,所以使用前需要先注册 Leancloud 账号 首先,在控制台界面,创建应用。成功创建后,效果如图。 点击进入应用内,查看自己的 appid 和 appkey ,并复制。 在主题配置文件中(根目录下的主题配置文件 _config.pure.yml )修改字段并添加内容: comment: type: valine # 启用哪种评论系统valine: # Valine 官方地址: https://valine.js.org appid: # 你的 leancloud 应用 appid appkey: # 你的 leancloud 应用 appkey notify: true # 是否开始评论邮件提醒,教程: https://github.com/xCss/Valine/wiki verify: false # 是否开始验证码功能,开始邮件提醒会自动开启验证码功能 placeholder: 说点什么... # 输入框默认内容 avatar: mp # 头像展示方式,具体设置项教程: https://valine.js.org/configuration.html#avatar meta: nick,mail,link # 自定义评论信息 pageSize: 10 # 评论列表分页 lang: zh-cn, # 多语言支持 zh-cn | en visitor: true # 文章阅读量统计: https://valine.js.org/visitor.html highlight: true # 代码高亮 recordIP: true # 记录评论者的 IP 如果设置了不蒜子统计,那么 visitor 字段就填 false ,否则会重复统计浏览量。 如果没有设置不蒜子统计,那么 visitor 可以设置 true 评论的管理:在 Leancloud 中创建一个 Comment Class ,其余配置不变。 使用博客系统发表评论时,即会同步显示在 Comment 对象中。如果开启了 visitor: true 功能,那么还会自动创建 Counter Class ,用以记录访问人数。 3. 评论头像的修改:头像配置 | Valine 一款快速、简洁且高效的无后端评论系统。 Valine 目前使用的是 Gravatar 作为评论列表头像。需要自行登录或注册 Gravatar,然后修改自己的头像。评论的时候,留下在 Gravatar 注册时所使用的邮箱即可。 非自定义头像有 7 中默认值可以选择。(上述配置中使用的 mp,因此,如果不添加邮箱,则会展示灰白头像) 4. 向百度爬虫提交链接 参考文档:Hexo 插件之百度主动提交链接 | 王辉的博客 (hui-wang.info) 请注意, 本插件的配置文件中包含秘钥, 请妥善管理好博客源码【源码可以保存在本地,如要推上 Github,一定要推到私有仓库】 首先,注册百度站长工具,然后在工具 -> 网页抓取 -> 链接提交里找到你的密匙。 随后,安装 hexo-baidu-url-submit 插件 npm install hexo-baidu-url-submit --save其次,在根目录下,把以下内容配置到 _config.yml 文件中: baidu_url_submit: count: 5 ## 提交最新的 5 个链接 (一次最多新增 5 篇文章,否则向百度提交链接就会漏掉一些) host: blog.sunforge.cn ## 在百度站长平台中注册的域名 token: your_token ## 请注意这是您的秘钥, 所以请不要把博客源代码发布在公众仓库里! path: baidu_urls.txt ## 文本文档的地址, 新链接会保存在此文本文档里再次,记得查看博客根目录下 _config.yml 文件中 url 的值, 必须包含是百度站长平台注册的域名, 比如: # URLurl: http://blog.sunforge.cnroot: /permalink: :year/:month/:day/:title/最后,加入新的 deployer: deploy:- # 原来的内容- type: baidu_url_submitter ## 这是新加的执行 hexo deploy 的时候,新的链接就会被推送了。 5. 引入 fancybox 图床实现图片点击放大 主题已经内置 FancyBox 功能。只需在主题配置文件 _config.pure.yml 中开启即可。 # Fancyboxfancybox: true至此,hexo 博客的配置教程告一段落。祝顺利。","categories":[{"name":"计算机科学","slug":"computer-science","permalink":"http://blog.sunforge.cn/categories/computer-science/"},{"name":"Hexo博客","slug":"computer-science/hexo","permalink":"http://blog.sunforge.cn/categories/computer-science/hexo/"}],"tags":[{"name":"教程","slug":"教程","permalink":"http://blog.sunforge.cn/tags/%E6%95%99%E7%A8%8B/"},{"name":"Hexo","slug":"Hexo","permalink":"http://blog.sunforge.cn/tags/Hexo/"}]},{"title":"配置github的ssh key (Windows)","slug":"computer-science/git/配置github的ssh-key","date":"2022-06-22T06:20:10.000Z","updated":"2022-10-18T12:44:06.632Z","comments":true,"path":"computer-science/git/配置github的ssh-key/","link":"","permalink":"http://blog.sunforge.cn/computer-science/git/%E9%85%8D%E7%BD%AEgithub%E7%9A%84ssh-key/","excerpt":"","text":"# github 添加 ssh key 通过 ssh key,可以配置 git 的多平台操作。实际上,通过 ssh 协议连接 github,gitee 等平台,相比 https 协议,速度更快,也更稳定。不会受到网络影响。 # 1. 找到 .ssh 文件夹 在当前用户目录 C:\\User\\yourname 下,找 .ssh 文件夹,如果没有这个文件夹,那么自己新建一个。 # 2. 在 git bash(或 Windows Powershell)中,打开 .ssh 目录 # 3. 生成 SSH 密匙对 在目录中,输入以下命令 ssh-keygen -t rsa -C '[email protected]' 第一步中的更名,是自定义的。推荐改名,默认名字会产生覆盖,并且无法区分用途。 口令可以不设置。 如下,已经生成了测试的 SSH 密钥对(SSH 协议底层使用 RSA 密码算法进行数据加密) # 4. 将 SSH 公钥上传到 github(gitee 等)代码托管平台 将 .pub 文件(公钥文件)在记事本(或 vscode 等)中打开,将公钥复制。并粘贴到 github 上 # 5. 在 .ssh 文件夹中,配置 config 文件(如果没有 config 文件,就自己新建一个) 实际上,如果有多平台使用需求(比如我有一个 github 仓库,一个 gitee 仓库,公司使用 gitlab 仓库)那么才需要配置 config 文件。否则可以跳过。 注意,需要设置显示文件后缀名,然后连着扩展名一起改掉。可以参考这里:[windows11 显示文件后缀名_vbind 的博客 - CSDN 博客](https://blog.csdn.net/vbind/article/details/124369484#:~:text = 查看文件 查看文件是否有扩展名,没有,后缀名 通过 ctrl%2BE 打开计算机,找到 “工具”—%26gt%3B “文件夹选项”—%26gt%3B “查看”,取消勾选 “隐藏已知文件类型的扩展名”,然后就可以看到文件的扩展名。) 输入下述内容 # github Host github.com HostName github.com PreferredAuthentications publickey IdentityFile ~/.ssh/id_rsa_testgithub User git # gitee Host gitee.com HostName gitee.com PreferredAuthentications publickey IdentityFile ~/.ssh/gitee_id_rsa User git 配置文件中的 HostName 是远程仓库的访问地址,这里可以是 IP,也可以是域名。Host 是用来拉取的仓库的别名,配不配置都行。如果 HostName 没配置的话,那就必须把 Host 配置为仓库 IP 地址或者域名,而非别名。 IdentityFile 必须要是 .ssh 文件夹中真实存在的私钥文件 # 6. 测试 ssh 连接 在 git bash 或 powershell 中 输入 ssh -T [email protected] ,若返回结果如图所示,则连接成功。 首次操作连接会询问 Are you sure you want to continue connecting (yes/no)? 填写 yes 即可。 如果没有配好上一步的 config 文件,就会出现 Permission denied (public key) 此处,SSH key 已经配好。以下部分是 SSH key 的使用 # 7. 用 ssh 连接代替 https 连接 将此处的地址复制,打开 github desktop(或 source tree 等)git 图形界面软件,粘贴到仓库地址中。 或者直接使用 git 命令行界面,修改仓库地址 可以打开 git bash 界面,修改仓库的地址 git config --global url.\"git://\".insteadOf https://这样可以使得,你的 .gitconfig 中会多出一行参数设置。 [url "git://"] insteadOf = https:// 这样一来,不管你在终端进行 clone,使用 git:// ,或者 http:// 去访问别人的 repository,两种方式都会默认变成 git:// 的形式进行连接并正常的工作了。 有时候系统可能会提示你防火墙禁止对 git:// 的访问,这时候就只能用 https:// 来访问 repository,这时候可以采用类似地方式,设置到 https:// 的模式 # 8. 配置仓库的用户名和邮箱(可选) 在本地的仓库目录下,配置该仓库使用的用户名和邮箱。 git config --local user.name 张三git config --local user.email [email protected]这里的账户可以和我们开始时生成密钥时( ssh-keygen -t rsa -C '[email protected]' )的邮箱可以不同,与 git 的 global 邮箱可以不同。(当然也可以相同...... 相同就不用配) 生成密钥的邮箱是使用那个密钥的全局用户(所以一定要设置自己正确的邮箱)。 这里配置的是密钥在某个仓库下的 “局部” 用户。","categories":[{"name":"计算机科学","slug":"computer-science","permalink":"http://blog.sunforge.cn/categories/computer-science/"},{"name":"git","slug":"computer-science/git","permalink":"http://blog.sunforge.cn/categories/computer-science/git/"}],"tags":[{"name":"教程","slug":"教程","permalink":"http://blog.sunforge.cn/tags/%E6%95%99%E7%A8%8B/"},{"name":"git","slug":"git","permalink":"http://blog.sunforge.cn/tags/git/"}]}],"categories":[{"name":"计算机科学","slug":"computer-science","permalink":"http://blog.sunforge.cn/categories/computer-science/"},{"name":"机器学习","slug":"computer-science/机器学习","permalink":"http://blog.sunforge.cn/categories/computer-science/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0/"},{"name":"回归模型","slug":"computer-science/机器学习/回归模型","permalink":"http://blog.sunforge.cn/categories/computer-science/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0/%E5%9B%9E%E5%BD%92%E6%A8%A1%E5%9E%8B/"},{"name":"基本法则","slug":"基本法则","permalink":"http://blog.sunforge.cn/categories/%E5%9F%BA%E6%9C%AC%E6%B3%95%E5%88%99/"},{"name":"数学","slug":"基本法则/数学","permalink":"http://blog.sunforge.cn/categories/%E5%9F%BA%E6%9C%AC%E6%B3%95%E5%88%99/%E6%95%B0%E5%AD%A6/"},{"name":"凸优化","slug":"基本法则/数学/凸优化","permalink":"http://blog.sunforge.cn/categories/%E5%9F%BA%E6%9C%AC%E6%B3%95%E5%88%99/%E6%95%B0%E5%AD%A6/%E5%87%B8%E4%BC%98%E5%8C%96/"},{"name":"数据结构与算法","slug":"computer-science/数据结构与算法","permalink":"http://blog.sunforge.cn/categories/computer-science/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E4%B8%8E%E7%AE%97%E6%B3%95/"},{"name":"图论","slug":"computer-science/数据结构与算法/图论","permalink":"http://blog.sunforge.cn/categories/computer-science/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E4%B8%8E%E7%AE%97%E6%B3%95/%E5%9B%BE%E8%AE%BA/"},{"name":"强化学习","slug":"computer-science/强化学习","permalink":"http://blog.sunforge.cn/categories/computer-science/%E5%BC%BA%E5%8C%96%E5%AD%A6%E4%B9%A0/"},{"name":"计算机网络","slug":"computer-science/计算机网络","permalink":"http://blog.sunforge.cn/categories/computer-science/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/"},{"name":"Hexo博客","slug":"computer-science/hexo","permalink":"http://blog.sunforge.cn/categories/computer-science/hexo/"},{"name":"git","slug":"computer-science/git","permalink":"http://blog.sunforge.cn/categories/computer-science/git/"}],"tags":[{"name":"笔记","slug":"笔记","permalink":"http://blog.sunforge.cn/tags/%E7%AC%94%E8%AE%B0/"},{"name":"索引","slug":"索引","permalink":"http://blog.sunforge.cn/tags/%E7%B4%A2%E5%BC%95/"},{"name":"教程","slug":"教程","permalink":"http://blog.sunforge.cn/tags/%E6%95%99%E7%A8%8B/"},{"name":"Hexo","slug":"Hexo","permalink":"http://blog.sunforge.cn/tags/Hexo/"},{"name":"git","slug":"git","permalink":"http://blog.sunforge.cn/tags/git/"}]}