【ICO 组合与整数优化笔记】Introduction 导论 1
【ICO 组合与整数优化笔记】Introduction 导论 1
组合最优化(Combinatorial Optimization)是应用数学的一个领域,融合了组合数学、线性规划和算法理论中的方法。它一般被应用于解决离散结构(Discrete Structure)中的最优化问题。在组合最优化问题中,我们想要在有限的可行方案中找到最佳的组合方案,这样的最优解可以用图像或者表格的形式,具体地表现出来。但是,组合优化问题的难点通常在于,可行方案的数量过于庞大,简单粗暴的枚举法通常不适用。整数规划(Integer Programming)是其中一个行之有效的方法,它通过建立含有整数变量的数学模型来描述并解决组合问题。当然,整数规划问题的解决难度远远在线性规划(Linear Programming)之上,直接用优化解算器(Optimization Solver)来解决并不容易,所以在整数规划问题上,我们也需要寻求更有效率的方法。
本篇文章作为导论,将介绍几个组合与整数优化领域比较经典的实际问题,带领读者对组合优化问题有一个具体的认识。
- 背包问题 Knapsack Problem
- 旅行商问题 Traveling Salesman Problem
- 分配问题 Assignment Problem
背包问题 Knapsack Problem
背包问题(Knapsack problem)是一种组合优化的NP完全问题。问题可以描述为:给定一组物品,每种物品都有自己的重量和价格,在限定的总重量内,我们如何选择,才能使得物品的总价格最高。问题的名称来源于如何选择最合适的物品放置于给定背包中。—— [Wikipedia]
一个具体的例子:假设一个游客到某地观光,他只背了一个最大承重为3kg的背包,准备在当地的市场买一些特产回家后在自己的店内转卖,他需要在10样特产里做选择,以求转卖后的利润最大化。特产信息如下:
特产编号 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|
利润(元) | 160 | 150 | 100 | 90 | 95 | 105 | 65 | 50 | 80 | 75 |
重量(kg) | 1 | 0.9 | 0.8 | 0.75 | 0.7 | 0.5 | 0.8 | 0.5 | 0.6 | 0.55 |
由于每件特产的利润都是正的,我们希望可以买回所有的特产,但是10件特产的总重量为7.1kg,远远超过了背包的3kg容量;单买任意一件特产则背包内仍有剩余空间可用。所以我们的最佳特产采购方案是在所有都买和只买一件的两个极端情况中间。如何确定最佳方案呢?
最直接的方法是列举出所有的可行方案,比较它们的利润大小,在其中选择最优。假设我们买与不买一件特产的决定都是互相独立的,那么我们一共有 种可能的方案。如果我们使用枚举法,列举出1024种方案,剔除其中总重量超过3kg的方案,在剩下的方案中选择利润最大的一个,就可以得到最优解。但是,这样简单的计算和筛选仍然有一定的成本,并且随着特产数量的增加,总方案的数量也成爆炸式的指数增长,如果我们用枚举法从50种特产中进行选择,就需要分析 种可能方案。显然,我们需要寻找更加高效的方法来解决背包问题。
假设每件特产的重量为,每件特产对应的利润为,对于每一件特产而言,我们要做的判断是:买或不买,这是一个二选一的决定,所以我们可以引入一个二元变量(Binary Variable),,用数学的方式描述这个决定:
寻找最佳特产购买方案,以及与此类似的问题可用一个最优化问题表示,例如:
这样,我们只需要求解这个最优化问题,而不需要枚举出所有可能方案再慢慢筛选。
旅行商问题 Traveling Salesman Problem
旅行推销员问题(最短路径问题)(英语:Travelling salesman problem, TSP)是这样一个问题:给定一系列城市和每对城市之间的距离,求解访问每一座城市一次并回到起始城市的最短回路。它是组合优化中的一个NP困难问题,在运筹学和理论计算机科学中非常重要。 [Wikipedia]
旅行商问题是组合优化课题里最重要的问题之一,它在物流货运线路规划等实际问题中具有非常大的实用意义。我们以欧几里得旅行商问题(Euclidean Traveling Salesman Problem)为例,假设有一个集合,其中包括了欧几里得平面内所有的点,每个点都有一对 坐标。我们知道,两个坐标分别为 和 的点,它们之间的距离为 , 我们想要找到一条最短的回路,通过集合 内的所有点 。
欧几里得旅行商问题:
根据欧几里得平面内所有点组成的点集V,找到一条经过平面内所有点并回到起始点的最短路径。
假如我们针对这个问题采用枚举法,即找到所有可能解,从中挑出最短路径,这样当然可以保证我们找到最优解。但是如果平面内共有n个点,,那么一共有种不同的可能需要评估。很明显,随着平面内点的数量的增加,枚举法的工作量也变得繁重,效率随之降低。为解决欧几里得旅行商问题,一个更加高效的算法——最近邻居法(Nearest Neighbour Algorithm)被提出,但这个方法并不保证给出的是最优解。
The nearest neighbour algorithm was one of the first algorithms used to determine a solution to the travelling salesman problem. In it, the salesman starts at a random city and repeatedly visits the nearest city until all have been visited. It quickly yields a short tour, but usually not the optimal one. [Wikipedia]
这个算法的基本原理是:在点集中任意选择一点作为起始点,将距离该点最近且没有去过的一点作为下一站。重复这一过程直到所有的点被遍历,而后回到起始点。
值得注意的是,虽然我们每一步都取了局部最优解(Locally Optimal),得到的解的整体效果可能很差:一是因为这种方法很容易漏掉某一点,并在后面的步骤花更大的成本来弥补;二是因为这种方法很有可能把路线”逼到角落”,这种情况下又需要一段很长的路径才能达到下一个距离最近的点。这也是最近邻居算法的局限性。
分配问题 Assignment Problem
分配问题是运筹学领域一个基础的组合优化,它一般用来处理工人与工作、学生与课题的分配。每配一对都需要付出相应的成本,通常情况下是一对一不重复的。如何达成成本最小的分配计划是研究的重点。
In its most general form, the problem is as follows:
The problem instance has a number of agents and a number of tasks. Any agent can be assigned to perform any task, incurring some cost that may vary depending on the agent-task assignment. It is required to perform all tasks by assigning exactly one agent to each task and exactly one task to each agent in such a way that the total cost of the assignment is minimized. [Wikipedia]
这里我们假设成本的计算和其它可能涉及的函数都是线性的。含有非线性项的分配问题要复杂得多。解决线性分配问题的方法可分为两种:一种是探索问题结构的特殊算法,比如狄杰斯特拉算法(Dijkstra’s Alogirthm)等;另一种是构造一个数学模型再求解。以后会有文章详细介绍这几种方法和它们的区别。