关于问题求解,书中有一个实际的案例。

上图是一个交叉路口的模型,现在问题是,怎么安排红绿灯才可以保证相应的行驶路线互不交错。

第一步,就是把问题弄清楚。

怎么能让每一条行驶路线不冲突呢?

其实,就是给所有的行驶路线分组(这样保证了安全问题,不会撞车)。

并且,所做的分组应该尽可能大一些,用以提高路口的通行效率(经济问题,如果一个组一条路线,虽然不会撞车,但是等待的时间会很长)。

有了上面的最大化分组的想法。那么就进一步将问题具体化。

这个路口有13个可供行驶的方向:AB,AC,AD,BA,BC,BD,DA,DB,DC,EA,EB,EC,ED。

现在问题就转化为,给这13条路线分组,使其各个组不冲突,并且最大化组中的成员。

在书中引出了一个冲突图,用来表示各个路线的冲突。

其中图中元素称之为顶点,连线称之为边或者弧。相互之间有边的顶点称为邻接顶点。

安全分组就变成了另外一种说法,为冲突图中的顶点确定一种分组,保证属于同一分组的所有顶点互不邻接。

到了这里就完了第一步,将问题严格化。

第二步,就是进行数据结构与算法设计

使用什么样的数据结构来表示冲突中的形式路线,又用哪种算法来计算分组。

书中首先提到了一个最佳着色算法,其实就是著名的四色问题,这个算法能找到最佳的分组方案。但是由于算法代价太高,效率不高。因此着重介绍了一个更为简单的算法。

那就是贪心法。它的基本想法是这样的:利用当时掌握的信息,尽可能地向得到解的方向前进,知道不能继续再换一个方法。

那么在这个例子中的具体表现就是:就是确定一个分组,这个分组里的成员互相都不邻接,也就是说不能冲突。当这个分组完成之后,再确定下一个分组。

按照这个方法,上面的例子分组就是:

{AB,AC,AD,BA,DC,ED}

{BC,BD,EA}

{DA,DB}

{EB,EC}

算法的伪代码如下:

输入:图G             #记录着图中顶点连接的关系

集合verts保存G中所有的顶点      #建立初始状态

设置集合groups为空集     #记录得到的分组,元素是顶点集合

while 存在未着色顶点:

  选一种新的颜色

  在未着色顶点中给尽量多的无连边的点着色(构建一个分组)

  记录新着色的顶点组

python伪代码:

new_group = 空集

for v in verts:

  if v 与new_group集合中的顶点都不相连:

    将v从verts中取出

    new_group.add(v)

循环结束时,new_grouo是可以用一种新的颜色着色的顶点集合

第三步,编写代码。

其实,上面的伪代码已经接近于具体程序了。只是还有一些细节需要考虑。

1、如何表示颜色。这个简单,用整数就可以。其实,用不用颜色表示都可以,只要将每个分组分开即可。这里采用二元组来表示,一个表示颜色,一个表示分好的组。、

2、如何记录分组。可以用一个集合来记录,也就是groups是集合的集合。

3、如何表示图结构?这个比较难,是后面的内容,这里先略过。

由此可得出python的代码:

def coloring(G)

  color = 0

  groups = set()

  verts = vertices(G) #用来获取所有的顶点

  while verts:

    new_groups = set()

    for v in list(verts):

      if not_adjacent_with_set(v, newgroup, G):

        new_group.add(v)

        verts.remove(v)

    groups.add((color, new_group))

    color += 1

  return grous

第四步,测试代码,寻找一些边界例子测试代码的严谨性以及逻辑性。

由于,这里并不是一个完整的项目,而且这个例子比较简单,就简单分析讨论一下,应该注意的几个问题。

1、它的解唯一吗?

其实,大致观察一下,就会发现,上面的算法只能给出一个恰好的解。例如,下面的分组也是一个解

{AB,EB,EC}

{AC,AD,BC,}

{BA,BD,DB,ED}

{DA,DC,EA}

其实,经过分析。对于BA、DC、ED三个顶点,将它们放在任何一个分组都是可以的。因为它们不跟任何一个顶点相连,也就是公认的无害右转弯。对于这个设计具体得看对于冲突概念的定义。

2、再次回顾一下算法的实现跟原来的问题是否相符

原来的问题是怎么分配,各个路线才能不冲突。

而上面的算法给出了一种不冲突的方法,但并不是最优的解。比如:上面的算法中每个分组都顶点都不允许重复,也就是各个分组互不相交。但真正的问题并没有这个要求。无害的右转弯就与各个分组都不冲突,完全可以都分配在各个分组里面。使其得到下面的分配:

{AB,AC,AD,BA,DC,ED}

{BC,BD,EA,BA,DC,ED}

{DA,DB,BA,DC,ED}

{EB,EC,BA,DC,ED}

这样就会将分组尽可能地扩充,使其经济效率更高(这个分组还可以继续扩充为{DA,DB,BA,DC,ED,AD})。

当然,这个问题还会有其他的一些具体的问题,这里就不讨论了。作者主要是用一个例子来带我们分析了一下,如何将生活中的实际问题,一步一步通过分析设计,最终得到一个完整的正确的效率高的计算机程序。

  

python数据结构与算法之问题求解实例的更多相关文章

  1. python数据结构与算法之问题求解

    懂得计算机的童鞋应该都知道,一条计算机程序由数据结构跟算法两大部分组成.所以,其实不管你使用哪种计算机语言编写程序,最终这两部分才是一个程序设计的核心.所以,一个不懂得数据结构与算法的程序员不是一个好 ...

  2. Python数据结构与算法之图的最短路径(Dijkstra算法)完整实例

    本文实例讲述了Python数据结构与算法之图的最短路径(Dijkstra算法).分享给大家供大家参考,具体如下: # coding:utf-8 # Dijkstra算法--通过边实现松弛 # 指定一个 ...

  3. Python数据结构与算法--算法分析

    在计算机科学中,算法分析(Analysis of algorithm)是分析执行一个给定算法需要消耗的计算资源数量(例如计算时间,存储器使用等)的过程.算法的效率或复杂度在理论上表示为一个函数.其定义 ...

  4. Python数据结构与算法之图的广度优先与深度优先搜索算法示例

    本文实例讲述了Python数据结构与算法之图的广度优先与深度优先搜索算法.分享给大家供大家参考,具体如下: 根据维基百科的伪代码实现: 广度优先BFS: 使用队列,集合 标记初始结点已被发现,放入队列 ...

  5. python数据结构与算法

    最近忙着准备各种笔试的东西,主要看什么数据结构啊,算法啦,balahbalah啊,以前一直就没看过这些,就挑了本简单的<啊哈算法>入门,不过里面的数据结构和算法都是用C语言写的,而自己对p ...

  6. Python数据结构与算法--List和Dictionaries

    Lists 当实现 list 的数据结构的时候Python 的设计者有很多的选择. 每一个选择都有可能影响着 list 操作执行的快慢. 当然他们也试图优化一些不常见的操作. 但是当权衡的时候,它们还 ...

  7. Python 数据结构和算法

    阅读目录 什么是算法 算法效率衡量 算法分析 常见时间复杂度 Python内置类型性能分析 数据结构 顺序表 链表 栈 队列 双端队列 排序与搜索 冒泡排序 选择排序 插入排序 希尔排序 快速排序 归 ...

  8. Python数据结构与算法(几种排序)

    数据结构与算法(Python) 冒泡排序 冒泡排序(英语:Bubble Sort)是一种简单的排序算法.它重复地遍历要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.遍历数列的工作是 ...

  9. Python - 数据结构与算法(Data Structure and Algorithms)

    入门 The Algorithms Python https://github.com/TheAlgorithms/Python 从基本原理到代码实现的Python算法入门,简洁地展示问题怎样解决,因 ...

随机推荐

  1. Verify_Execute 验证SQL语句执行结果

    #region Verify_Execute /// <summary> /// 验证insert.update.delete执行 /// </summary> /// < ...

  2. PHP 异常处理 throw new exception

    当异常被抛出时,其后的代码不会继续执行,PHP 会尝试查找匹配的 "catch" 代码块. 如果异常没有被捕获,而且又没用使用 set_exception_handler() 作相 ...

  3. kubernetes集群pod使用tc进行网络资源限额

    kubernetes集群pod使用tc进行网络资源限额 Docker容器可以实现CPU,内存,磁盘的IO限额,但是没有实现网络IO的限额.主要原因是在实际使用中,构建的网络环境是往超级复杂的大型网络. ...

  4. 对象序列化Serializable

    一.Java对象的存储 首先我们先来理解一下Java对象在内存中的存储! JVM的内存分为三个部分:栈(stack).堆栈(heap).方法区(method area): 栈:主要存储基本数据类型变量 ...

  5. 《视觉SLAM十四讲课后作业》第二讲

    1.设线性⽅程 Ax = b,在 A 为⽅阵的前提下,请回答以下问题:1. 在什么条件下,x 有解且唯⼀? 非齐次线性方程在A的秩与[A|B]的秩相同时方程有解,当R(A)=R(A,B)=n时方程有唯 ...

  6. caffe特征层可视化

    #参考1:https://blog.csdn.net/sushiqian/article/details/78614133#参考2:https://blog.csdn.net/thy_2014/art ...

  7. day12函数,三元表达式 ,列表推导式 ,字典推导式,函数对象,名称空间与作用域,函数的嵌套定义

    复习 # 字符串的比较 # -- 按照从左往右比较每一个字符,通过字符对应的ascii进行比较 # 函数的参数 # 1)实参与形参: # -- 形参:在函数定义时()中出现的参数 # -- 实参:在函 ...

  8. SpringBoot Tomcat启动报错

    中间的桥梁就是下面这个依赖 <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over ...

  9. 通过反射将request中的参数封装到对象中

    import java.beans.PropertyDescriptor; import java.lang.reflect.Method; import java.text.SimpleDateFo ...

  10. 【POJ 2176】Folding

    [原题链接]传送门 [题面大意] 一个字符串,可以将它改写成循环节带括号的形式进行压缩,输出压缩长度最小的字符串. [题解思路] 1.没思路没思路,不知道怎么乱搞,大概就可以想到动态规划. 2.套路区 ...