# VRP-GA
**Repository Path**: looiise/VRP-GA
## Basic Information
- **Project Name**: VRP-GA
- **Description**: 用遗传算法求解VRP问题
- **Primary Language**: C++
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 2
- **Created**: 2022-03-26
- **Last Updated**: 2022-03-26
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
**车辆路径问题** (Vehicle Routing Problem,以下简称**VRP问题**)最早由*Dantzig*和*Ramser*于1959年首次提出,是运筹学中一个经典问题。VRP问题主要研究**物流配送中的车辆路径规划问题**,是当今物流行业中的基础问题。
VRP问题的主要研究对象是以下问题:
> 有一个配送中心,每天需要向若干配送点配送货物,配送中心有若干辆车可用于配送。已知配送中心和各配送点的位置,请问如何设计配送方案才能让配送效率尽可能高?
该问题是一类物流配送优化问题的典型代表。对以上问题进行不同条件的约束,并设定不同的最优化目标,就得到了不同种类的VRP问题。VRP问题一共有十几种类型,每种类型的求解算法都大不相同。
VRP问题属于NPC问题,目前**没有多项式时间复杂度的求解算法**。求解VRP问题是一项十分具有挑战性的工作。
*拓展资料:*
[车辆路径问题(MBA智库)]([https://wiki.mbalib.com/wiki/%E8%BD%A6%E8%BE%86%E8%B7%AF%E5%BE%84%E9%97%AE%E9%A2%98](https://wiki.mbalib.com/wiki/车辆路径问题))
[车辆路径问题详解(百度文库)](https://wenku.baidu.com/view/36d5ec9109a1284ac850ad02de80d4d8d15a0109.html?from=search)
[物流配送问题(百度文库)](https://wenku.baidu.com/view/064a0da0d05abe23482fb4daa58da0116d171f12.html?from=search)
[什么是P问题、NP问题和NPC问题(Matrix67)](http://www.matrix67.com/blog/archives/105)
* 基因重组:两条染色体的部分片段发生了随机交换。**基因重组不会产生新的基因,但是可能将父代的一些优良基因片段集中到子代基因上**(当然,也有可能将父代不好的基因片段集中到子代基因上)。**基因重组发生的概率也很低,但是比基因突变的概率高**。
## 遗传算法基本流程
遗传算法忠实地复原了生物进化的过程。以下是遗传算法的基本流程:

该流程适用于所有遗传算法,但是对于具体问题应用遗传算法时,需要根据具体问题设计算法中各种遗传操作。
*拓展资料:*
[遗传算法:内存中的进化(科学松鼠会)](https://songshuhui.net/archives/10462)
[有史以来最容易理解的遗传算法(知乎)](https://zhuanlan.zhihu.com/p/35986593)
# 用遗传算法求解VRP问题
遗传算法求解的关键是设计个体的存储结构和各种遗传操作的实现。这些细节不仅决定程序实现的难度,也影响着算法最终的执行效果。
为便于叙述,我们将所有配送点编号为 $1$ 到 $n$ ,将所有车辆编号为 $1$ 到 $m$ 。
## 个体的编码
为方便起见,个体的编码采用与穷举法中相同的编码方案。这种方案简单直观,没有冗余信息,而且可以简化接下来的变异操作,提高程序的运行效率。
## 个体的生成
利用如下算法随机生成一个个体:
1. 随机生成 $1$ 到 $n$ 的全排列。
2. 在排列中随机插入 $m-1$ 个 $0$ 。
**注意:由于载重量和里程的约束,以上算法生成的个体可能是不合法的,因此在第二步分割时需要根据当前车辆的里程和载重进行合理划分,以保证所有生成的个体都是合法的。**
## 初始种群的生成
利用以上算法随机生成 $1000$ 个个体作为初始种群。
## 适应度计算
个体的适应度根据以下公式计算:
$$
fitness=score=-(w_t \cdot t + w_s \cdot s + w_n \cdot n)
$$
其中 $score$ 为问题分析中介绍过的得分公式。
## 选择操作
按照如下步骤对种群进行选择:
1. 对种群中的所有个体按照适应度从大到小排序。
2. 选择前 $50\%$ 的个体(即适应度较大的 $50\%$ 个体)保留到下一代。
执行选择操作后,种群中的个体数减少为原来的一半,后面会通过繁殖操作使种群大小恢复为原来的水平。
## 变异操作
按照如下步骤对个体进行变异:
1. 随机选定个体数组中的两个元素。
2. 交换两个元素的值。
3. **若变异后的个体不合法,则变异失败,撤销变异操作(即保持个体不变)**。
> 例:
> $$
> 2\quad1\quad3\quad0\quad9\quad4\quad7\quad6\quad0\quad8\quad5
> $$
> 该个体变异后可能产生的新个体如下:
> $$
> 2\quad1\quad3\quad0\quad7\quad4\quad9\quad6\quad0\quad8\quad5
> $$
> 其中 `9` 和 `7` 交换了位置,改变了第二辆车配送的顺序。
>
> 还可能产生如下的变异:
> $$
> 2\quad4\quad3\quad7\quad9\quad1\quad0\quad6\quad0\quad8\quad5
> $$
> 这次变异交换了 `0` 的位置,产生了一个新划分。
显然,若个体能成功变异,则经过变异后的个体还是合法的。这种变异算法能够很好地保留父代的大部分特征,同时也有一定的机率产生较大的改变(如上例中的第二种变异情况),可以大大增强种群多样性,提高算法搜索的效果。
## 交叉操作
如果用传统的交叉算法(即随机交换两条染色体的片段)对个体进行交叉操作,则交叉后产生的新个体不一定是合法的,需要进行调整。为简单起见,这里**不对个体进行交叉操作**,仅仅通过变异操作产生新个体。
## 繁殖操作
选择操作后,种群大小变为原来的一半。每次在留下的个体中随机选取一个进行变异操作(若变异失败,则重新选择一个个体),并将产生的新个体插入到种群中,直到种群恢复原来的大小。
## 算法结束条件
程序会记录每次进化过程中个体的最大适应度。若最大适应度持续 $1000$ 代都无变化,则结束算法,并输出最大适应度对应的方案。
# 算法执行效果展示
利用以上遗传算法实现的程序能够在较短时间内求解一定规模的VRP问题,且求解质量还不错。以下给出不同规模的VRP问题的求解结果和相关数据。
**地图中的红点P表示配送中心,蓝点表示配送点,蓝点旁边的数字表示需求量。**
下面是各个问题的相关参数:
| 问题规模 | 车辆总数 | 载重约束 | 里程约束 | 权重($w_t:w_s:w_n$) |
| :--------: | :------: | :--------------: | :------: | :-------------------: |
| 10个配送点 | $5$ | 全部为5 | $20$ | $1:1:1$ |
| 20个配送点 | $20$ | 10辆为2,10辆为5 | $20$ | $1:1:10$ |
| 30个配送点 | $20$ | 10辆为2,10辆为5 | $20$ | $1:1:2$ |
| 40个配送点 | $20$ | 全部为5 | $20$ | $1:10:1$ |
| 50个配送点 | $20$ | 全部为5 | $20$ | $10:1:1$ |
**注:数据中的时间、重量和里程经过单位换算,不代表实际大小,只表示相对大小。**
## 10个配送点
## 20个配送点


## 30个配送点


## 40个配送点


## 50个配送点

