Fork me on GitHub

旅行商问题+背包问题--经典问题

问题描述:

  • 旅行商问题(Traveling Salesman Problem,TSP)是旅行商要到若干个城市旅行,各城市之间的费用是已知的,为了节省费用,旅行商决定从所在城市出发,到每个城市旅行一次后返回初始城市,问他应选择什么样的路线才能使所走的总费用最短?此问题可描述如下:设G=(V,E)是一个具有边成本cij的有向图,cij的定义如下,对于所有的i和j,cij>0,若<i,j>不属于E,则cij=∞。令|V|=n,并假设n>1。 G的一条周游路线是包含V中每个结点的一个有向环,周游路线的成本是此路线上所有边的成本和。

  • 旅行商问题(Traveling Saleman Problem,TSP)又译为旅行推销员问题、货郎担问题,简称为TSP问题,是最基本的路线问题,该问题是在寻求单一旅行者由起点出发,通过所有给定的需求点之后,最后再回到原点的最小路径成本。最早的旅行商问题的数学规划是由Dantzig(1959)等人提出。 

  • TSP问题在物流中的描述是对应一个物流配送公司,欲将n个客户的订货沿最短路线全部送到。如何确定最短路线。

  • TSP问题最简单的求解方法是枚举法。它的解是多维的、多局部极值的、趋于无穷大的复杂解的空间,搜索空间是n个点的所有排列的集合,大小为(n-1)。可以形象地把解空间看成是一个无穷大的丘陵地带,各山峰或山谷的高度即是问题的极值。求解TSP,则是在此不能穷尽的丘陵地带中攀登以达到山顶或谷底的过程。

问题分析

  • 旅行商问题要从图G的所有周游路线中求取最小成本的周游路线,而从初始点出发的周游路线一共有(n-1)!条,即等于除初始结点外的n-1个结点的排列数,因此旅行商问题是一个排列问题。排列问题比子集合的选择问题通常要难于求解得多,这是因为n个物体有n!种排列。通过枚举(n-1)!条周游路线,从中找出一条具有最小成本的周游路线的算法,其计算时间显然为O(n!)。

旅行商问题的解法

  旅行推销员的问题,我们称之为巡行(Tour),此种问题属于NP-Complete的问题,所以旅行商问题大多集中在启发式解法。Bodin(1983)等人将旅行推销员问题的启发式解法分成三种:
  1、途程建构法(Tour Construction Procedures)
  从距离矩阵中产生一个近似最佳解的途径,有以下几种解法:
  1)最近邻点法(Nearest Neighbor Procedure):一开始以寻找离场站最近的需求点为起始路线的第一个顾客,此后寻找离最后加入路线的顾客最近的需求点,直到最后。
  2)节省法(Clark and Wright Saving):以服务每一个节点为起始解,根据三角不等式两边之和大于第三边之性质,其起始状况为每服务一个顾客后便回场站,而后计算路线间合并节省量,将节省量以降序排序而依次合并路线,直到最后。
  3)插入法(Insertion procedures):如最近插入法、最省插入法、随意插入法、最远插入法、最大角度插入法等。
  2、途程改善法(Tour Improvement Procedure)
  先给定一个可行途程,然后进行改善,一直到不能改善为止。有以下几种解法:
  1)K-Opt(2/3 Opt):把尚未加入路径的K条节线暂时取代目前路径中K条节线,并计算其成本(或距离),如果成本降低(距离减少),则取代之,直到无法改善为止,K通常为2或3。
  2)Or-Opt:在相同路径上相邻的需求点,将之和本身或其它路径交换且仍保持路径方向性,并计算其成本(或距离),如果成本降低(距离减少),则取代之,直到无法改善为止。
  3、合成启发法(Composite Procedure)
  先由途程建构法产生起始途程,然后再使用途程改善法去寻求最佳解,又称为两段解法(two phase method)。有以下几种解法:
  1)起始解求解+2-Opt:以途程建构法建立一个起始的解,再用2-Opt的方式改善途程,直到不能改善为止。
2)起始解求解+3-Opt:以途程建构法建立一个起始的解,再用3-Opt的方式改善途程,直到不能改善为止。

背包问题

  • 背包问题(Knapsack problem)是一种组合优化的NP完全问题。问题可以描述为:给定一组物品,每种物品都有自己的重量和价格,在限定的总重量内,我们如何选择,才能使得物品的总价格最高。问题的名称来源于如何选择最合适的物品放置于给定背包中。
  • 也可以将背包问题描述为决定性问题,即在总重量不超过W的前提下,总价值是否能达到V?

题目

  • 有N件物品和一个容量为V的背包。第i件物品的费用是c,价值是w。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。

基本思路

  • 这是最基础的背包问题,特点是:每种物品仅有一件,可以选择放或不放。
  • 用子问题定义状态:即f[v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值。则其状态转移方程便是:f[v]=max{f[v],f[v-c]+w}。
  • 这个方程非常重要,基本上所有跟背包相关的问题的方程都是由它衍生出来的。所以有必要将它详细解释一下:“将前i件物品放入容量为v的背包中”这个子问题,若只考虑第i件物品的策略(放或不放),那么就可以转化为一个只牵扯前i-1件物品的问题。如果不放第i件物品,那么问题就转化为“前i-1件物品放入容量为v的背包中”;如果放第i件物品,那么问题就转化为“前i-1件物品放入剩下的容量为v-c的背包中”,此时能获得的最大价值就是f [v-c]再加上通过放入第i件物品获得的价值w。
posted @ 2017-05-05 23:27  ranjiewen  阅读(7273)  评论(0编辑  收藏  举报