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

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

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

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

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

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

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

这个路口有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. LoadXml 加载XML时,报错:“根级别上的数据无效。 行1,位置1“

    ==XML=================================== <?xml version="1.0" encoding="utf-8" ...

  2. [转载]Oracle日期周详解IW

    1 ORACLE中周相关知识描述 1.1           日期格式化函数 TO_CHAR(X [,FORMAT]):将X按FORMAT格式转换成字符串.X是一个日期,FORMAT是一个规定了X采用 ...

  3. 五一培训 DAY1

    DAY1 枚举 例题1 题解: 例题2 题解: 例题3 题解: vis[ ]判断是否为素数,pri[ ]储存素数 例题4 题解: 例题5 题解: PS: i  <  1<<n    ...

  4. jQuery和react实现二维码

    jq如何生成二维码 代码如下: 1.jquery.qrcode生成二维码代码 <!DOCTYPE html> <html> <head> <script ch ...

  5. android 模拟器 访问 localhost IIs Express 400错误

    如果用安卓模拟器调试本机的网站,比如 localhost:63586,是访问不到的,返回结果是 400 错误.原因是模拟器上的localhost指向的默认是模拟器自己. 解决方法是:(1) 把安卓模拟 ...

  6. kubernets kubevirt 分析

    目前kubevirt提供虚机管理的功能. kill, delete, shutdown, migration 等. VMI是virtual machine interface的缩写. SyncVMI, ...

  7. Tomcat类加载

    一.为什么会有类加载 1.在类加载阶段,虚拟机需要完成以下3件事情 1)通过一个全限类定名来获取此类的二进制字节流 2) 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构 3)在内存中生成 ...

  8. 富文本编辑器Quill(二)上传图片与视频

    image与video在Quill formats中属于Embeds,要在富文本中插入图片或者视频需要使用insertEmbed api. insertEmbed insertEmbed(index: ...

  9. vector某元素是否存在、查找指定元素 、去重

    vector.map 判断某元素是否存在.查找指定元素 [C++]判断元素是否在vector中,对vector去重,两个vector求交集.并集 PS:注意重载

  10. Bigger-Mai 养成计划,前端基础学习之CSS

    在标签上设置style属性: background-color: #2459a2; height: 48px; ... 编写css样式: 1. 标签的style属性 2. 写在head里面 style ...