前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >图形图像算法中必须要了解的设计模式(2)

图形图像算法中必须要了解的设计模式(2)

作者头像
OpenCV学堂
发布2018-07-26 10:51:22
发布2018-07-26 10:51:22
49300
代码可运行
举报
运行总次数:0
代码可运行

图形图像算法中必须要了解的设计模式(2)

AI越来越火热,人工智能已然成风!而人工智能最重要是各种算法,因此机器学习越来越受到追捧,算法越来越被重视。

作为一个算法的研究者,写出一手高级算法当然是令人兴奋的一件事!但你是否有时会有这种感觉:

  1. 写的算法很难通用于所有的数据类型!每来一个新类型的数据,又得改一下算法,或新加一个方法来支持这种类型。
  2. 有时候多个算法需要灵活组合,甚至每个算法的顺序不一样都会产生不一样的效果;每一种组合都要为其构建一个新算法,即累又麻烦。
  3. 算法越来越多,自建的算法库也越来越庞大而难于管理;

这个时候,让你的算法具有更好通用性、拓展性就显得极为重要!因此,你必须要掌握几个重要的设计模式来解决这些问题。今天介绍一种在算法领域中应用最广泛的设计模式——策略模式

策略模式

定义一系列算法,将每个算法都封装起来,并且使他们之间可以相互替换。策略模式使算法可以独立于使用它的用户而变化。

策略模式是对算法、规则的一种封装。它具有以下的优点:

  • 算法(规则)可自由地切换。
  • 避免使用多重条件判断。
  • 方便拓展和增加新的算法(规则)。

应用案例

假设有这样一个应用场景:

有一Person类,有年龄(age),体重(weight),身高(height)三个属性。现要对Person的一组对象进行排序,但并没有确定根据什么规则来排序,有时需要根据年龄进行排序,有时需要根据身高进行排序,有时可能是根据身高和体重的综合情况来排序,还有可能……

通过对这个应用场景进行分析,我们会发现,这里需要有多种排序算法,而且需要动态地在这几种算法中进行选择,在未来可能还会添加一新的排序规则……

怎样让我们的排序算法更加的灵活,以适应各种各样的排序规则呢?这里我们就要用到策略模式。来,我们一起看一下具体的代码实现吧。

源码示例:

代码语言:javascript
代码运行次数:0
运行
复制
class Person:
    "人类"

    def __init__(self, name, age, weight, height):
        self.name = name
        self.age = age
        self.weight = weight
        self.height = height

    def showMysef(self):
        print(self.name + " " + str(self.age) + " years old, " + str(self.weight) + "kg, " + str(self.height) + "m.")

class ICompare:
    "比较算法"

    def comparable(self, person1, person2):
        "person1 > person2 返回值>0,person1 == person2 返回0, person1 < person2 返回值小于0"
        pass


class CompareByAge(ICompare):
    "通过年龄排序"

    def comparable(self, person1, person2):
        return person1.age - person2.age

class CompareByHeight(ICompare):
    "通过身高进行排序"

    def comparable(self, person1, person2):
        return person1.height - person2.height

class SortPerson:
    "Person的排序类"

    def __init__(self, compare):
        self.__compare = compare

    def sort(self, personList):
        "排序算法,这里采用最简单的冒泡排序"
        n = len(personList)
        for i in range(0, n-1):
            for j in range(0, n-i-1):
                if(self.__compare.comparable(personList[j], personList[j+1]) > 0):
                    tmp = personList[j]
                    personList[j] = personList[j+1]
                    personList[j+1] = tmp
            j += 1
        i += 1

测试代码:

代码语言:javascript
代码运行次数:0
运行
复制
def testSortPerson():
    personList = [
        Person("Tony", 2, 54.5, 0.82),
        Person("Jack", 31, 74.5, 1.80),
        Person("Nick", 54, 44.5, 1.59),
        Person("Eric", 23, 62.0, 1.78),
        Person("Helen", 16, 45.7, 1.60)
    ]
    sorter0 = SortPerson(CompareByAge())
    sorter0.sort(personList)
    print("根据年龄进行排序后的结果:")
    for person in personList:
        person.showMysef()
    print()

    sorter1 = SortPerson(CompareByHeight())
    sorter1.sort(personList)
    print("根据身高进行排序后的结果:")
    for person in personList:
        person.showMysef()

输出结果:

代码语言:javascript
代码运行次数:0
运行
复制
根据年龄进行排序后的结果:
Tony 2 years old, 54.5kg, 0.82m.
Helen 16 years old, 45.7kg, 1.6m.
Eric 23 years old, 62.0kg, 1.78m.
Jack 31 years old, 74.5kg, 1.8m.
Nick 54 years old, 44.5kg, 1.59m.

根据身高进行排序后的结果:
Tony 2 years old, 54.5kg, 0.82m.
Nick 54 years old, 44.5kg, 1.59m.
Helen 16 years old, 45.7kg, 1.6m.
Eric 23 years old, 62.0kg, 1.78m.
Jack 31 years old, 74.5kg, 1.8m.

看到这,一些熟悉Python的同学肯定要吐槽了!Python是一个简洁明了的语言,使用十几行代码就能解决的问题(如下面的实现代码),为什么要写上面这一大堆的东西。

代码语言:javascript
代码运行次数:0
运行
复制
from operator import itemgetter,attrgetter
def testPersonListInPython():
    "用Python的方式对Person进行排序"

    personList = [
        Person("Tony", 2, 54.5, 0.82),
        Person("Jack", 31, 74.5, 1.80),
        Person("Nick", 54, 44.5, 1.59),
        Person("Eric", 23, 62.0, 1.78),
        Person("Helen", 16, 45.7, 1.60)
    ]

    # 使用使用operator模块根据年龄进行排序
    print("根据年龄进行排序后的结果:")
    sortedPerons = sorted(personList, key = attrgetter('age'))
    for person in sortedPerons:
        person.showMysef()
    print()

    print("根据身高进行排序后的结果:")
    sortedPerons1 = sorted(personList, key=attrgetter('height'))
    for person in sortedPerons1:
        person.showMysef()

输出的结果和上面是一模一样的,这里不再赘述。

能提出这个问题,说明你一定是带着思考在阅读!之所以还要这么写,出于以下几个原因:

  1. 设计模式是一种编译思想,他和语言没有强关联,应当适用于所有面向对象的语言。Python因为语言本身的灵活性和良好的封装性,使得其自带了很多的功能,而其他语言并没有这样的功能。也许你的算法就是用C++或者Java来写的呢!为了让熟悉其他语言的人也能看懂,这里使用了最接近面向对象思维的方式进行实现(即使你熟悉Python也可通过他来学习一种新的思维方式)。
  2. 使用Python语言本身的特性,还是难以实现一些特殊的需求,如要根据身高和体重的综合情况来排序(身高和体重的权重分别是0.6和0.4)。用策略模式就可以很方便地实现,只需要增加一个CompareByHeightAndWeight的策略类就可以,如下面代码:
代码语言:javascript
代码运行次数:0
运行
复制
class CompareByHeightAndWeight(ICompare):
    "根据身高和体重的综合情况来排序(身高和体重的权重分别是0.6和0.4)"

    def comparable(self, person1, person2):
        value1 = person1.height * 0.6 + person1.weight * 0.4
        value2 = person2.height * 0.6 + person2.weight * 0.4
        return value1 - value2

使用策略模式能让我们写的算法适用于各种规则和各种对象类型,极大地提高了算法的灵活性和拓展性。

Get到技能点了吗?

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-07-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 OpenCV学堂 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 图形图像算法中必须要了解的设计模式(2)
    • 策略模式
    • 应用案例
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档