zoukankan      html  css  js  c++  java
  • Genetic Algorithms with python 学习笔记ch5

    利用遗传算法解决图着色问题

    我们使用4个颜色来为美国地图着色,但要确保没有相邻的州具有相同的颜色。程序实现的过程中将不过分讨论地图的表示,只需各个州之间的相邻关系简单的表示就可以了。
    graphColoringTests.py 完整代码如下;

    import csv
    import unittest
    import datetime
    import genetic
    
    def load_data(localFileName):
        with open(localFileName, mode= 'r') as infile:
            reader = csv.reader(infile)
            lookup = {row[0]: row[1].split(';') for row in reader if row}
        return lookup
    
    class Rule:
        def __init__(self, node, adjacent):
            if node < adjacent:
                node, adjacent = adjacent, node
            self.Node = node
            self.Adjacent = adjacent
    
        def __eq__(self, other):
            return self.Node == other.Node and 
                self.Adjacent == other.Node
    
        def __hash__(self):
            return hash(self.Node) * 397 ^ hash(self.Adjacent)
    
        def __str__(self):
            return self.Node + " -> " + self.Adjacent
    
        def IsValid(self, genes, nodeIndexLookup):
            index = nodeIndexLookup[self.Node]
            adjacentStateIndex = nodeIndexLookup[self.Adjacent]
            return genes[index] != genes[adjacentStateIndex]
    
    def build_rules(items):
        rulesAdded = {}
    
        for state, adjacent in items.items():
            for adjacentState in adjacent:
                if adjacentState == '':
                    continue
                rule = Rule(state, adjacentState)
                if rule in rulesAdded:
                    rulesAdded[rule] += 1
                else:
                    rulesAdded[rule] = 1
    
            for k,v in rulesAdded.items():
                if v != 2:
                    print("rule {} is not bidirectional".format(k))
    
            return rulesAdded.keys()
    
    class GraphColoringTests(unittest.TestCase):
        def test(self):
            states = load_data("adjacent_states.csv")
            rules = build_rules(states)
            optimalValue = len (rules)
            stateIndexLookup ={key: index
                               for index, key in enumerate(sorted(states))}
    
            colors = ["Orange", "Yellow", "Green", "Blue"]
            colorLookup = {color[0]: color for color in colors}
            geneset = list(colorLookup.keys())
    
            startTime = datetime.datetime.now()
    
            def fnDisplay(candidate):
                display(candidate, startTime)
    
            def fnGetFitness(genes):
                return get_fitness(genes, rules, stateIndexLookup)
    
            best = genetic.get_best(fnGetFitness, len(states),
                                    optimalValue, geneset, fnDisplay)
            self.assertTrue(not optimalValue > best.Fitness)
    
            keys = sorted(states.keys())
            for index in range(len(states)):
                print(keys[index] + " is " + colorLookup[best.Genes[index]])
    
    def display(candidate, startTime):
        timeDiff = datetime.datetime.now() - startTime
        print("{}	{}	{}".format(
            ''.join(map(str, candidate.Genes)),
            candidate.Fitness,
            timeDiff))
    
    def get_fitness(genes, rules, stateIndexLookup):
        rulesThatPass = sum(1 for rule in rules
                            if rule.IsValid(genes, stateIndexLookup))
        return rulesThatPass
    

    第一部分为读取文件,文件中的每一行格式为:州1,(州2;州3;州4),表示州1与有分号分隔开的其他三个州相邻。下面的函数 load_data 功能为读取文件然后将有关各州之间相邻关系的键值对进行返回。

    def load_data(localFileName):
        with open(localFileName, mode= 'r') as infile:
            reader = csv.reader(infile)
            lookup = {row[0]: row[1].split(';') for row in reader if row}
        return lookup
    

    下面所描述的 Rule 类主要表示一对相邻关系。

    class Rule:
        def __init__(self, node, adjacent):
            if node < adjacent:
                node, adjacent = adjacent, node
            self.Node = node
            self.Adjacent = adjacent
    
        def __eq__(self, other):
            return self.Node == other.Node and 
                self.Adjacent == other.Node
    
        def __hash__(self):
            return hash(self.Node) * 397 ^ hash(self.Adjacent)
    
        def __str__(self):
            return self.Node + " -> " + self.Adjacent
    
        def IsValid(self, genes, nodeIndexLookup):
            index = nodeIndexLookup[self.Node]
            adjacentStateIndex = nodeIndexLookup[self.Adjacent]
            return genes[index] != genes[adjacentStateIndex]
    

    下面的函数 build_rules 表示为每一对相邻的点建立相邻关系,并且保证相邻关系是双向的。

    def build_rules(items):
        rulesAdded = {}
    
        for state, adjacent in items.items():
            for adjacentState in adjacent:
                if adjacentState == '':
                    continue
                rule = Rule(state, adjacentState)
                if rule in rulesAdded:
                    rulesAdded[rule] += 1
                else:
                    rulesAdded[rule] = 1
    
            for k,v in rulesAdded.items():
                if v != 2:
                    print("rule {} is not bidirectional".format(k))
    
            return rulesAdded.keys()
    

    下面这个类表示测试图着色问题的具体流程:
    首先读取文件,然后建立邻接关系,在调用engine求最优解。

    class GraphColoringTests(unittest.TestCase):
        def test(self):
            states = load_data("adjacent_states.csv")
            rules = build_rules(states)
            optimalValue = len (rules)
            stateIndexLookup ={key: index
                               for index, key in enumerate(sorted(states))}
    
            colors = ["Orange", "Yellow", "Green", "Blue"]
            colorLookup = {color[0]: color for color in colors}
            geneset = list(colorLookup.keys())
    
            startTime = datetime.datetime.now()
    
            def fnDisplay(candidate):
                display(candidate, startTime)
    
            def fnGetFitness(genes):
                return get_fitness(genes, rules, stateIndexLookup)
    
            best = genetic.get_best(fnGetFitness, len(states),
                                    optimalValue, geneset, fnDisplay)
            self.assertTrue(not optimalValue > best.Fitness)
    
            keys = sorted(states.keys())
            for index in range(len(states)):
                print(keys[index] + " is " + colorLookup[best.Genes[index]])
    

    另一个重要的部分就是计算适应值,这里的适应值就是计算有效的着色对数,即当两个相邻的州为不同颜色,那么这一对州之间的着色是有效的,如果有效的对数等于所有相邻的关系数,则为最优解。

    def get_fitness(genes, rules, stateIndexLookup):
        rulesThatPass = sum(1 for rule in rules
                            if rule.IsValid(genes, stateIndexLookup))
        return rulesThatPass
    
  • 相关阅读:
    HDU 4734 F(x) 2013 ACM/ICPC 成都网络赛
    VC++中的头文件包含问题
    php调用com组件配置 以openoffice为例
    Android 进程和线程
    文件队列 QueueFile
    Android zip文件压缩解压缩
    Internet Explorer 11(IE11)无法切换第三方输入法
    非递归实现快速排序
    class_create()
    字符设备 register_chrdev_region()、alloc_chrdev_region() 和 register_chrdev()
  • 原文地址:https://www.cnblogs.com/idella/p/13412721.html
Copyright © 2011-2022 走看看