数学建模系列-优化模型(二)---图论模型(一)

图论模型可以简单理解为画图解决的模型。比较经典的有树状图、TSP算法等等。其中上一篇文章中提到的动态规划也看作图论的一种。

图论模型可以简单的分为以下几种:

  1. 最短路径问题
  2. 最小生成树问题
  3. 网络最大流问题
  4. 排队问题

接下来一一解释,并给出常见的算法。值得注意的是,以上都可以看作是或转化单目标优化。

1.最小路径问题
1.1经典的问题是路径规划问题,即求一个点到另一个点的最短路径。(无权)
思路:
**1.遍历法,**广度优先(钻井,先把每一层都扩建到最大再打下一层),按照树图的思想以起点为中心,分层,分层的层数与A的跳数相同。查看每一个节点的下一跳,求出所有解法后找到最佳的一条。
PS:深度优先(钻井直接钻到最深处,再返回扩建):
(1)首先以一个未被访问过的顶点作为起始顶点,沿当前顶点的边走到未访问过的顶点;
(2)当没有未访问过的顶点时,则回到上一个顶点,继续试探别的顶点,直至所有的顶点都被访问过。

两种思路的目的:在图论问题中,遍历中如果没有准则依靠来寻找的话容易去到之前取得过的路径造成浪费,因此我们一般基于这两种思想。

1.2 路径规划加权情况(每一跳长度不一样):
无法使用广度优先进行遍历,但是依然用遍历的方法解决。
2.DJ斯特拉算法
这个算法的本质,是不断刷新起点与其他各个顶点之间的 “距离表”。这个图的表现和我们之前有提到过的动态规划在底层逻辑一样。本算法的遍历依然是基于广度优先。

第1步,创建距离表。表中的Key是顶点名称,Value是从起点A到对应顶点的已知最短距离。但是,一开始我们并不知道A到其他顶点的最短距离是多少,Value默认是无限大:

第2步,遍历起点A,找到起点A的邻接顶点B和C。从A到B的距离是5,从A到C的距离是2。把这一信息刷新到距离表当中。每一次遍历更新一遍最短距离。

第三步,A遍历完后,遍历B,C的子层。一直到遍历完成为止。代码引自:程序员小灰

/**

* Dijkstra最短路径算法

*/

public static Map<Integer, Integer> dijkstra(Graph graph, int startIndex) {
   

//创建距离表,存储从起点到每一个顶点的临时距离

Map<Integer, Integer> distanceMap = new HashMap<Integer,Integer>();

//记录遍历过的顶点

Set<Integer> accessedSet = new HashSet<Integer> ();

//图的顶点数量

int size = graph.vertexes.length;

//初始化最短路径表,到达每个顶点的路径代价默认为无穷大

for(int i=1; i<size; i++){
   

distanceMap.put(i, Integer.MAX_VALUE);

}

//遍历起点,刷新距离表

accessedSet.add(0);

List<Edge> edgesFromStart = graph.adj[startIndex];

for(Edge edge : edgesFromStart)

{
   

distanceMap.put(edge.index, edge.weight);

}

//主循环,重复 遍历最短距离顶点和刷新距离表 的操作

for(int i=1; i<size; i++)

{
   

//寻找最短距离顶点

int minDistanceFromStart = Integer.MAX_VALUE;

int minDistanceIndex = -1;

for(int j=1; j<size; j++)

{
   

if(!accessedSet.contains(j) && distanceMap.get(j) < minDistanceFromStart)

{
   

minDistanceFromStart = distanceMap.get(j);

minDistanceIndex = j;

}

}

if(minDistanceIndex == -1){
   

break;

}

//遍历顶点,刷新距离表

accessedSet.add(minDistanceIndex);

for(Ed
  • 4
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值