0%


title:机器学习的10个项目

Deepy

Deepy 由 Raphael Shu 开发,是一个基于 Theano 扩展深度学习框架,它提供了一个简洁的、高阶的组件(如 LSTMs)、批规范化、自动编码等功能。Deepy 宣称其框架是十分简洁明了的,它的官方文档和示例也同样如此。
Deepy 工作原理:在给定训练数据和参数(随机初始化)下运行模型,将错误(或梯度)反馈并更新参数,这个过程反复进行。

MLxtend

MLxtend 由 Sebastian Raschka 开发,是一系列有效工具的集合,也是针对机器学习任务的扩展。Sebastian Raschka 提到 MLxtend 本质上是一些有效的工具集,也是与机器学习和数据科学相关的参考资料。他提到开发 MLxtend 主要是基于以下几个原因:
一些其他地方找不到的特定算法(如序列特征选择算法、多数表决分类器、叠加预估、绘图决策区域等)
用于教学目的(逻辑回归、Softmax 回归、多层感知器、PCA、PCA 内核等)这些实现主要关注于代码的可读性,而不是单纯的效率
打包便利:tensorflow、Softmax 回归和多层感知器
MLxtend 基本上是 Sebastian Raschka 所写的一个机器学习运行常用的库,其中很多功能的实现都与 scikit-learn 的 API 相似,但作者仍在持续更新中,且作者表示所有的新增特性与创新的算法都会一起打包在 MLxtend 中。

Datacleaner

datacleaner 由 Randal Olson 开发,他认为自己开发的 datacleaner 是一个“能自动清除数据集并且让它们便于分析的 Python 工具。”他认为:datacleaner 所做的将会节约你大量的编码和清理数据的时间。
datacleaner 还处于开发过程中,但目前已经能够处理以下常规(传统方式下耗时量巨大的)数据清洗任务:
在列的基础上,用模式或中位数替换丢失的值
用数值等价物对非数值变量进行编码等

Auto-sklearn

auto-sklearn 由德国弗莱堡大学机器学习自动算法小组开发,是针对 Scikit-learn 环境的自动机器学习工具。
auto-sklearn 能将机器学习用户从算法选择和高参数调整中解救出来,它利用了近期在贝叶斯优化、元学习和集成构筑上研究的优势。其大致工作原理如下:

Deep Mining

Deep Mining 由来自 MIT CSAIL 实验室的 Sebastien Dubois 开发,是一个机器学习深管道自动调谐器。为了尽快实现最好的分类精度,该软件将迭代、智能地测试一些超参数集。
另外值得一提的是文件夹 GCP-HPO 包含所有高斯过程(GCP)的实现代码以及基于其基础上的超参数优化(HPO)。高斯过程(GCP)可以看作是一种改进的版本。这项新技术被证明优于基于 GP 的超参数优化,已经远比随机搜索表现要好。

Rusty Machine

Rusty Machine 是基于 Rust 的机器学习方法,Rust 是由 Mozilla 赞助开发的一种与C和 C++ 较为相似的计算机编程语言,其号称“Rust 是一种系统的编程语言,运行速度极快,可以防止错误,并保证线程安全。”
Rusty Machine 的开发者是否活跃,目前支持一系列想学习技术,包括:线性回归、逻辑回归、k-均值聚类、神经网络、支持向量机等等。
Rusty Machine 还支持数据结构,如内置向量和矩阵。作为一种常见的模型接口,Rusty Machine 为每个支持的模型提供了训练和预测的功能。

Scikit-image

scikit-image 图像是针对 SciPy 使用 Python 的图像处理方法。scikit-image 是机器学习吗?它其实是一个机器学习项目(没有确切地表示他们必须用机器学习方法),scikit-image 就属于数据处理和准备工具这一类。该项目包括一些图像处理算法,如点检测、滤波、特征选择和形态学等。

NLP Compromise

NLP Compromise 是由 Java 语言编写的,其在浏览器中进行自然语言处理过程。NLP Compromise 非常容易安装和使用,以下是它的一个使用范例:

Datatest

Datatest 是一个依靠数据冲突的测试集,其由 Python 编写。
Datatest 扩展了数据校正的测试工具标准数据库
Datatest 是一种寻找数据冲突和准备的不同方式,如果你的大部分时间都被花在这个任务上,也许换一种新的方法是值得的。

GoLearn

GoLearn 是一种针对 Go 语言的机器学习库,自称 Go 语言机器学习的“内置电池”学习库。简洁、易定制是其追求的目标。
对于一些想分支出来的 Python 用户或者想尝试下机器学习的 Go 语言用户来说,GoLearn 是一个不错的选项。GoLearn 实现了熟悉的 Scikit-learn 适应/预测界面,可实现快速预估测试和交换。

example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import redis
import matplotlib.pyplotasplt
import pickle

r_basicdx=redis.Redis(host='172.20.3.52',port=6373,db=1)
l_basicdx=redis.Redis(host='127.0.0.1',port=6379,db=1)
keys=r_basicdx.keys()
forkeyinkeys:
value=r_basicdx.get(key)
l_basicdx.set(key,value)
image=pickle.loads(value)
f=plt.figure()
ax=f.add_subplot(111)
ax.text(0.1,0.9,key,ha='center',va='center',transform=ax.transAxes)
plt.imshow(image)
plt.show()

下载与安装

你可以使用我们提供的 Pip, Docker, Virtualenv, Anaconda 或 源码编译的方法安装 TensorFlow.
Pip 安装
Pip 是一个 Python 的软件包安装与管理工具.
在安装 TensorFlow 过程中要涉及安装或升级的包详见 列表
首先安装 pip (或 Python3 的 pip3 ):

Ubuntu/Linux 64-bit

$ sudo apt-get install python-pip python-dev

Mac OS X

$ sudo easy_install pip
安装 TensorFlow :

Ubuntu/Linux 64-bit, CPU only, Python 2.7:

$ sudo pip install –upgrade https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-0.8.0-cp27-none-linux_x86_64.whl

Ubuntu/Linux 64-bit, GPU enabled, Python 2.7. Requires CUDA toolkit 7.5 and CuDNN v4.

For other versions, see “Install from sources” below.

$ sudo pip install –upgrade https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow-0.8.0-cp27-none-linux_x86_64.whl

Mac OS X, CPU only:

$ sudo easy_install –upgrade six
$ sudo pip install –upgrade https://storage.googleapis.com/tensorflow/mac/tensorflow-0.8.0-py2-none-any.whl
如果是 Python3 :

Ubuntu/Linux 64-bit, CPU only, Python 3.4:

$ sudo pip3 install –upgrade https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-0.8.0-cp34-cp34m-linux_x86_64.whl

Ubuntu/Linux 64-bit, GPU enabled, Python 3.4. Requires CUDA toolkit 7.5 and CuDNN v4.

For other versions, see “Install from sources” below.

$ sudo pip3 install –upgrade https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow-0.8.0-cp34-cp34m-linux_x86_64.whl

Mac OS X, CPU only:

$ sudo easy_install –upgrade six
$ sudo pip3 install –upgrade https://storage.googleapis.com/tensorflow/mac/tensorflow-0.8.0-py3-none-any.whl
备注:如果之前安装过 TensorFlow < 0.7.1 的版本,应该先使用 pip uninstall 卸载 TensorFlow 和 protobuf ,保证获取的是一个最新 protobuf 依赖下的安装包.
之后可以测试一下.
基于 Docker 的安装
我们也支持通过 Docker 运行 TensorFlow. 该方式的优点是不用操心软件依赖问题.
首先, 安装 Docker. 一旦 Docker 已经启动运行, 可以通过命令启动一个容器:
$ docker run -it b.gcr.io/tensorflow/tensorflow
该命令将启动一个已经安装好 TensorFlow 及相关依赖的容器.
其它镜像
默认的 Docker 镜像只包含启动和运行 TensorFlow 所需依赖库的一个最小集. 我们额外提供了 下面的容器, 该容器同样可以通过上述 docker run 命令安装:
b.gcr.io/tensorflow/tensorflow-full: 镜像中的 TensorFlow 是从源代码完整安装的, 包含了编译和运行 TensorFlow 所需的全部工具. 在该镜像上, 可以直接使用源代码进行实验, 而不需要再安装上述的任何依赖.
基于 VirtualEnv 的安装
我们推荐使用 virtualenv 创建一个隔离的容器, 来安装 TensorFlow. 这是可选的, 但是这样做能使排查安装问题变得更容易.
首先, 安装所有必备工具:

在 Linux 上:

$ sudo apt-get install python-pip python-dev python-virtualenv

在 Mac 上:

$ sudo easy_install pip # 如果还没有安装 pip
$ sudo pip install –upgrade virtualenv
接下来, 建立一个全新的 virtualenv 环境. 为了将环境建在 ~/tensorflow 目录下, 执行:
$ virtualenv –system-site-packages ~/tensorflow
$ cd ~/tensorflow
然后, 激活 virtualenv:
$ source bin/activate # 如果使用 bash
$ source bin/activate.csh # 如果使用 csh
(tensorflow)$ # 终端提示符应该发生变化
在 virtualenv 内, 安装 TensorFlow:
(tensorflow)$ pip install –upgrade <$url_to_binary.whl>
接下来, 使用类似命令运行 TensorFlow 程序:
(tensorflow)$ cd tensorflow/models/image/mnist
(tensorflow)$ python convolutional.py

当使用完 TensorFlow

(tensorflow)$ deactivate # 停用 virtualenv

$ # 你的命令提示符会恢复原样
基于 Anaconda 的安装
Anaconda 是一个集成许多第三方科学计算库的 Python 科学计算环境,Anaconda 使用 conda 作为自己的包管理工具,同时具有自己的计算环境,类似 Virtualenv.
和 Virtualenv 一样,不同 Python 工程需要的依赖包,conda 将他们存储在不同的地方。 TensorFlow 上安装的 Anaconda 不会对之前安装的 Python 包进行覆盖.
安装 Anaconda
建立一个 conda 计算环境
激活环境,使用 conda 安装 TensorFlow
安装成功后,每次使用 TensorFlow 的时候需要激活 conda 环境
安装 Anaconda :
参考 Anaconda 的下载页面的指导
建立一个 conda 计算环境名字叫tensorflow:

Python 2.7

$ conda create -n tensorflow python=2.7

Python 3.4

$ conda create -n tensorflow python=3.4
激活tensorflow环境,然后使用其中的 pip 安装 TensorFlow. 当使用easy_install使用–ignore-installed标记防止错误的产生。
$ source activate tensorflow
(tensorflow)$ # Your prompt should change

Ubuntu/Linux 64-bit, CPU only, Python 2.7:

(tensorflow)$ pip install –ignore-installed –upgrade https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-0.8.0rc0-cp27-none-linux_x86_64.whl

Ubuntu/Linux 64-bit, GPU enabled, Python 2.7. Requires CUDA toolkit 7.5 and CuDNN v4.

For other versions, see “Install from sources” below.

(tensorflow)$ pip install –ignore-installed –upgrade https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow-0.8.0rc0-cp27-none-linux_x86_64.whl

Mac OS X, CPU only:

(tensorflow)$ pip install –ignore-installed –upgrade https://storage.googleapis.com/tensorflow/mac/tensorflow-0.8.0rc0-py2-none-any.whl
对于 Python 3.x :
$ source activate tensorflow
(tensorflow)$ # Your prompt should change

Ubuntu/Linux 64-bit, CPU only, Python 3.4:

(tensorflow)$ pip install –ignore-installed –upgrade https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-0.8.0rc0-cp34-cp34m-linux_x86_64.whl

Ubuntu/Linux 64-bit, GPU enabled, Python 3.4. Requires CUDA toolkit 7.5 and CuDNN v4.

For other versions, see “Install from sources” below.

(tensorflow)$ pip install –ignore-installed –upgrade https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow-0.8.0rc0-cp34-cp34m-linux_x86_64.whl

Mac OS X, CPU only:

(tensorflow)$ pip install –ignore-installed –upgrade https://storage.googleapis.com/tensorflow/mac/tensorflow-0.8.0rc0-py3-none-any.whl
conda 环境激活后,你可以测试
当你不用 TensorFlow 的时候,关闭环境:
(tensorflow)$ source deactivate

$ # Your prompt should change back
再次使用的时候再激活 :-)
$ source activate tensorflow
(tensorflow)$ # Your prompt should change.

Run Python programs that use TensorFlow.

When you are done using TensorFlow, deactivate the environment.

(tensorflow)$ source deactivate

投资决策模型化,基于历史数据验证,交易自动执行

股市波动,长期、短期、相对

投资指标

风险收益率

夏普率=(收益-无风险利率)/波动率

胜率赔率

胜率是指出手赚钱次数与总出手次数之比

赔率是指平均每次出手赚到的钱除以平均每次出手赔的钱,也叫做盈亏比

策略

阿尔法策略

优点:不管指数是涨还是下跌,都能赚钱的一种方法,具体的操作思路是找出市场里最优秀的品种,做多这些品种,然后做空相应多的指数,这样就锁定了最优秀的品种带来的收益,而把指数带来的波动进行了平抑。
缺点:回撤和收益都比较小的交易策略

程序化CTA

优点:适合大众使用的程序化交易方法,是指将交易策略的思想设计成完整的逻辑运行体系,然后用合适的计算机语言编写成程序,有计算机进行自动交易。程序化交易的优点是,将交易模式系统化,制度化,排除人性的心理障碍,确保交易策略的执行行。挣的是趋势的钱,挣的是纪律的钱,但因为趋势不常有,所以这是一种低胜率,高赔率的方法。

入场条件、出场条件,品种选择、时机选择,资金管理

统计套利

通过计算某些关联品种之间出现了价差的扩大,那就可以在品种之间进行配对交易,从而进行套利

低风险套利

ETF套利也是一种低风险套利,比如某个ETF指数基金现在的价格是2.1,而如果我们用一揽子股票来组成这个ETF指数基金,价格是2块,那么我们就可以在市场上卖出基金,买入股票,来得到这0.1的差价。这些套利比较容易执行,收入也很可观,而且风险很小。

高频交易

利用计算机处理市场微观结构层面的不均衡性,往往交易次数多,持仓时间短,可能会送大量交易指令,又快速撤单,再反向做交易获得收益,每笔交易平均利润小但稳定。

优点是总收益率极高,当日平仓降低隔夜风险,隔夜资金利息收入降低资金成本,绩效评估周期短。

算法交易

降低冲击成本的一种被动的程序化交易,通过科学的成本估算模型和交易实施算法,将一个大额的交易拆分成系列小额交易 在合理的时间点分别执行,以此来尽量减少 对市场价格造成的冲击,降低交易成本,而且还能帮助机构投资者快速增加交易量。适合的对象包括大小非减持者,大宗交易接盘出货,“大宗交易-融券卖出”套利者,Alpha套利者,套期保值者,日以上级别程序化交易者等。

参考:https://www.jianshu.com/p/2c470ef5d083

开发过程中,需要根据不同场景选择不同算法和策略。

将需要经常改变的部分抽象提取为接口,通过引用该接口,就可以调用该接口实现类的行为,即具体策略。实现了策略具体实现和调用者的隔离。

优点

  1. 可以动态改变对象行为

缺点

  1. 使用哪种策略需要调用者自己决定
  2. 产生很多策略类

示例

public interface IStrategy {
    public void doSomething();
}

public class Strategy1 implements IStrategy {
    @Override
    public void doSomething() {

    }
}

public class Strategy2 implements IStrategy {
    @Override
    public void doSomething() {

    }
}

public class Context implements IStrategy {

    private IStrategy strategy;

    public Context(IStrategy strategy){
        this.strategy = strategy;
    }

    @Override
    public void doSomething() {
        strategy.doSomething();
    }
}

public static void main(String[] args) {
    IStrategy strategy = new Strategy1();
    Context context = new Context(strategy);
    context.doSomething();
}

流程相同,执行过程中有差别

可用于定义算法骨架,将一些实现放到子类中实现,达到不用改变算法结构,重新实现算法的目的

代码实现

package template;

public abstract class Model {
    /**
     * 类似的行为、逻辑
     */
    protected abstract void start();

    protected abstract void stop();

    /**
     * 固定的流程  模板化
     */
    final public void excet(){
        this.start();
        this.stop();
    }
}

package template;

public class Ocar extends Model {
    @Override
    protected void start() {

    }

    @Override
    protected void stop() {

    }
}

package template;

public class Wcar extends Model {
    @Override
    protected void start() {

    }

    @Override
    protected void stop() {

    }
}

package template;

public class Client {
    public static void main(String[] args) {
        Model wcar=new Wcar();
        wcar.excet();

        Model ocar=new Ocar();
        ocar.excet();
    }

}

代理模式+策略模式,典型 Spring 中的 DispatcherServlet

用户将任务全权委派给代理负责,代理负责根据策略任务调度具体的执行单元

执行单元

/**
 * 执行单元实现的接口
 */
public interface ITarget {

    void doSomething(String command);

}

/**
 * 执行单元A
 */
public class TargetA implements ITarget {
    @Override
    public void doSomething(String command) {

    }
}

/**
 * 执行单元B
 */
public class TargetB implements ITarget {
    @Override
    public void doSomething(String command) {
        
    }
}

执行单元调度者

public class Manager {
    private Map<String ,ITarget> targets = new HashMap<String ,ITarget>();

    public Manager(){
        targets.put("commandA",new TargetA());
        targets.put("commandB",new TargetB());
    }

    public void dispatch(String command){
        targets.get(command).doSomething(command);
    }
}

使用者

public class Boss {
    
    public static void main(String[] args) {
        Manager manager = new Manager();
        manager.dispatch("Command1");
    }

}

使用原型对象的方法创建对象的实列,创建的实例equals原型

final 类型修饰的成员变量不能进行深度拷贝

场景

  • 类初始化需要消化非常多的资源,这个资源包括数据、硬件资源等
  • 构造对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式
  • 工厂模式中使用
  • 共有信息很多

浅拷贝

对象内引用原先原型的对象

深拷贝

对象内引用也拷贝一份

代码实现

package prototype;

//Cloneable 标记对象可拷贝
public class PersonClone implements Cloneable {

    @Override //Override Object方法
    public PersonClone clone(){
        try {
            //clone 不会调用构造方法
            return (PersonClone)super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return null;
    }
}


package prototype;

public class MainClass {
    public static void main(String[] args) {
        PersonClone personClone = new PersonClone();
        PersonClone clone = personClone.clone();
        System.out.println(personClone.hashCode());
        System.out.println(clone.hashCode());
    }
}

线程安全问题

volatile:保证多线程下的可见性

读volatile:每当子线程读取volatile变量时,都会从主线程重新拷贝一份
写volatile: 每当子线程修改volatile变量时,都会在修改后同步到主线程去

synchronized:对象锁、类锁、方法锁(其它篇有介绍)

public class Singleton {

    private static volatile Singleton instance;

    private Singleton(){
    }

    public static Singleton getInstance(){
        if(instance == null){
            synchronized(Singleton.class){
                if(instance == null){
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

遗传算法(Genetic Algorithms )是基于生物进化理论的原理发展起来的一种广为应用的、高效的随机搜索与优化的方法。其主要特点是群体搜索策略和群体中个体之间的信息交换,搜索不依赖于梯度信息。

步骤

  1. 初始化 t←0进化代数计数器;T是最大进化代数;随机生成M个个体作为初始群体P(t)
  2. 个体评价 计算P(t)中各个个体的适应度;
  3. 选择运算 将选择算子作用于群体;
  4. 交叉运算 将交叉算子作用于群体;
  5. 变异运算 将变异算子作用于群体,并通过以上运算得到下一代群体P(t + 1);
  6. 终止条件判断 t≦T:t← t+1 转到步骤2;t>T:终止 输出解。

模型构成

  1. 决策变量及各种约束条件,即个体的表现型X和问题的解空间
  2. 目标函数最大OR 最小, 数学描述形式 量化方法
  3. 染色体编码方法 (二进制、整数、浮点数)
  4. 解码方法
  5. 个体适应度的量化评价方法 F(x) (旅行商问题及最短路径)
  6. 设计遗传算子
  7. 有关运行参数

缺点

  • 局部收敛
  • 全局搜索能力不够强

改进

  • 交叉算子
  • 变异算子
  • 选择策略

代码实现

package noah;  
  
import java.io.BufferedReader;  
import java.io.FileInputStream;  
import java.io.IOException;  
import java.io.InputStreamReader;  
import java.util.Random;  
  
public class GA {  
  
    private int scale;// 种群规模  
    private int cityNum; // 城市数量,染色体长度  
    private int MAX_GEN; // 运行代数  
    private int[][] distance; // 距离矩阵  
    private int bestT;// 最佳出现代数  
    private int bestLength; // 最佳长度  
    private int[] bestTour; // 最佳路径  
  
    // 初始种群,父代种群,行数表示种群规模,一行代表一个个体,即染色体,列表示染色体基因片段  
    private int[][] oldPopulation;  
    private int[][] newPopulation;// 新的种群,子代种群  
    private int[] fitness;// 种群适应度,表示种群中各个个体的适应度  
  
    private float[] Pi;// 种群中各个个体的累计概率  
    private float Pc;// 交叉概率  
    private float Pm;// 变异概率  
    private int t;// 当前代数  
  
    private Random random;  
  
    public GA() {  
  
    }  
  
    /** 
     * constructor of GA 
     *  
     * @param s 
     *            种群规模 
     * @param n 
     *            城市数量 
     * @param g 
     *            运行代数 
     * @param c 
     *            交叉率 
     * @param m 
     *            变异率 
     *  
     **/  
    public GA(int s, int n, int g, float c, float m) {  
        scale = s;  
        cityNum = n;  
        MAX_GEN = g;  
        Pc = c;  
        Pm = m;  
    }  
  
    // 给编译器一条指令,告诉它对被批注的代码元素内部的某些警告保持静默  
    @SuppressWarnings("resource")  
    /** 
     * 初始化GA算法类 
     * @param filename 数据文件名,该文件存储所有城市节点坐标数据 
     * @throws IOException 
     */  
    private void init(String filename) throws IOException {  
        // 读取数据  
        int[] x;  
        int[] y;  
        String strbuff;  
        BufferedReader data = new BufferedReader(new InputStreamReader(  
                new FileInputStream(filename)));  
        distance = new int[cityNum][cityNum];  
        x = new int[cityNum];  
        y = new int[cityNum];  
        for (int i = 0; i < cityNum; i++) {  
            // 读取一行数据,数据格式1 6734 1453  
            strbuff = data.readLine();  
            // 字符分割  
            String[] strcol = strbuff.split(" ");  
            x[i] = Integer.valueOf(strcol[1]);// x坐标  
            y[i] = Integer.valueOf(strcol[2]);// y坐标  
        }  
        // 计算距离矩阵  
        // ,针对具体问题,距离计算方法也不一样,此处用的是att48作为案例,它有48个城市,距离计算方法为伪欧氏距离,最优值为10628  
        for (int i = 0; i < cityNum - 1; i++) {  
            distance[i][i] = 0; // 对角线为0  
            for (int j = i + 1; j < cityNum; j++) {  
                double rij = Math  
                        .sqrt(((x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j])  
                                * (y[i] - y[j])) / 10.0);  
                // 四舍五入,取整  
                int tij = (int) Math.round(rij);  
                if (tij < rij) {  
                    distance[i][j] = tij + 1;  
                    distance[j][i] = distance[i][j];  
                } else {  
                    distance[i][j] = tij;  
                    distance[j][i] = distance[i][j];  
                }  
            }  
        }  
        distance[cityNum - 1][cityNum - 1] = 0;  
  
        bestLength = Integer.MAX_VALUE;  
        bestTour = new int[cityNum + 1];  
        bestT = 0;  
        t = 0;  
  
        newPopulation = new int[scale][cityNum];  
        oldPopulation = new int[scale][cityNum];  
        fitness = new int[scale];  
        Pi = new float[scale];  
  
        random = new Random(System.currentTimeMillis());  
        /* 
         * for(int i=0;i<cityNum;i++) { for(int j=0;j<cityNum;j++) { 
         * System.out.print(distance[i][j]+","); } System.out.println(); } 
         */  
        // 初始化种群  
  
    }  
  
    // 初始化种群  
    void initGroup() {  
        int i, j, k;  
        // Random random = new Random(System.currentTimeMillis());  
        for (k = 0; k < scale; k++)// 种群数  
        {  
            oldPopulation[k][0] = random.nextInt(65535) % cityNum;  
            for (i = 1; i < cityNum;)// 染色体长度  
            {  
                oldPopulation[k][i] = random.nextInt(65535) % cityNum;  
                for (j = 0; j < i; j++) {  
                    if (oldPopulation[k][i] == oldPopulation[k][j]) {  
                        break;  
                    }  
                }  
                if (j == i) {  
                    i++;  
                }  
            }  
        }  
  
        /* 
         * for(i=0;i<scale;i++) { for(j=0;j<cityNum;j++) { 
         * System.out.print(oldPopulation[i][j]+","); } System.out.println(); } 
         */  
    }  
  
    public int evaluate(int[] chromosome) {  
        // 0123  
        int len = 0;  
        // 染色体,起始城市,城市1,城市2...城市n  
        for (int i = 1; i < cityNum; i++) {  
            len += distance[chromosome[i - 1]][chromosome[i]];  
        }  
        // 城市n,起始城市  
        len += distance[chromosome[cityNum - 1]][chromosome[0]];  
        return len;  
    }  
  
    // 计算种群中各个个体的累积概率,前提是已经计算出各个个体的适应度fitness[max],作为赌轮选择策略一部分,Pi[max]  
    void countRate() {  
        int k;  
        double sumFitness = 0;// 适应度总和  
  
        double[] tempf = new double[scale];  
  
        for (k = 0; k < scale; k++) {  
            tempf[k] = 10.0 / fitness[k];  
            sumFitness += tempf[k];  
        }  
  
        Pi[0] = (float) (tempf[0] / sumFitness);  
        for (k = 1; k < scale; k++) {  
            Pi[k] = (float) (tempf[k] / sumFitness + Pi[k - 1]);  
        }  
  
        /* 
         * for(k=0;k<scale;k++) { System.out.println(fitness[k]+" "+Pi[k]); } 
         */  
    }  
  
    // 挑选某代种群中适应度最高的个体,直接复制到子代中  
    // 前提是已经计算出各个个体的适应度Fitness[max]  
    public void selectBestGh() {  
        int k, i, maxid;  
        int maxevaluation;  
  
        maxid = 0;  
        maxevaluation = fitness[0];  
        for (k = 1; k < scale; k++) {  
            if (maxevaluation > fitness[k]) {  
                maxevaluation = fitness[k];  
                maxid = k;  
            }  
        }  
  
        if (bestLength > maxevaluation) {  
            bestLength = maxevaluation;  
            bestT = t;// 最好的染色体出现的代数;  
            for (i = 0; i < cityNum; i++) {  
                bestTour[i] = oldPopulation[maxid][i];  
            }  
        }  
  
        // System.out.println("代数 " + t + " " + maxevaluation);  
        // 复制染色体,k表示新染色体在种群中的位置,kk表示旧的染色体在种群中的位置  
        copyGh(0, maxid);// 将当代种群中适应度最高的染色体k复制到新种群中,排在第一位0  
    }  
  
    // 复制染色体,k表示新染色体在种群中的位置,kk表示旧的染色体在种群中的位置  
    public void copyGh(int k, int kk) {  
        int i;  
        for (i = 0; i < cityNum; i++) {  
            newPopulation[k][i] = oldPopulation[kk][i];  
        }  
    }  
  
    // 赌轮选择策略挑选  
    public void select() {  
        int k, i, selectId;  
        float ran1;  
        // Random random = new Random(System.currentTimeMillis());  
        for (k = 1; k < scale; k++) {  
            ran1 = (float) (random.nextInt(65535) % 1000 / 1000.0);  
            // System.out.println("概率"+ran1);  
            // 产生方式  
            for (i = 0; i < scale; i++) {  
                if (ran1 <= Pi[i]) {  
                    break;  
                }  
            }  
            selectId = i;  
            // System.out.println("选中" + selectId);  
            copyGh(k, selectId);  
        }  
    }  
  
    //进化函数,正常交叉变异  
    public void evolution() {  
        int k;  
        // 挑选某代种群中适应度最高的个体  
        selectBestGh();  
  
        // 赌轮选择策略挑选scale-1个下一代个体  
        select();  
  
        // Random random = new Random(System.currentTimeMillis());  
        float r;  
  
        // 交叉方法  
        for (k = 0; k < scale; k = k + 2) {  
            r = random.nextFloat();// /产生概率  
            // System.out.println("交叉率..." + r);  
            if (r < Pc) {  
                // System.out.println(k + "与" + k + 1 + "进行交叉...");  
                //OXCross(k, k + 1);// 进行交叉  
                OXCross1(k, k + 1);  
            } else {  
                r = random.nextFloat();// /产生概率  
                // System.out.println("变异率1..." + r);  
                // 变异  
                if (r < Pm) {  
                    // System.out.println(k + "变异...");  
                    OnCVariation(k);  
                }  
                r = random.nextFloat();// /产生概率  
                // System.out.println("变异率2..." + r);  
                // 变异  
                if (r < Pm) {  
                    // System.out.println(k + 1 + "变异...");  
                    OnCVariation(k + 1);  
                }  
            }  
  
        }  
    }  
  
    //进化函数,保留最好染色体不进行交叉变异  
    public void evolution1() {  
        int k;  
        // 挑选某代种群中适应度最高的个体  
        selectBestGh();  
  
        // 赌轮选择策略挑选scale-1个下一代个体  
        select();  
  
        // Random random = new Random(System.currentTimeMillis());  
        float r;  
  
        for (k = 1; k + 1 < scale / 2; k = k + 2) {  
            r = random.nextFloat();// /产生概率  
            if (r < Pc) {  
                OXCross1(k, k + 1);// 进行交叉  
                //OXCross(k,k+1);//进行交叉  
            } else {  
                r = random.nextFloat();// /产生概率  
                // 变异  
                if (r < Pm) {  
                    OnCVariation(k);  
                }  
                r = random.nextFloat();// /产生概率  
                // 变异  
                if (r < Pm) {  
                    OnCVariation(k + 1);  
                }  
            }  
        }  
        if (k == scale / 2 - 1)// 剩最后一个染色体没有交叉L-1  
        {  
            r = random.nextFloat();// /产生概率  
            if (r < Pm) {  
                OnCVariation(k);  
            }  
        }  
  
    }  
  
    // 类OX交叉算子  
    void OXCross(int k1, int k2) {  
        int i, j, k, flag;  
        int ran1, ran2, temp;  
        int[] Gh1 = new int[cityNum];  
        int[] Gh2 = new int[cityNum];  
        // Random random = new Random(System.currentTimeMillis());  
  
        ran1 = random.nextInt(65535) % cityNum;  
        ran2 = random.nextInt(65535) % cityNum;  
        // System.out.println();  
        // System.out.println("-----------------------");  
        // System.out.println("----"+ran1+"----"+ran2);  
  
        while (ran1 == ran2) {  
            ran2 = random.nextInt(65535) % cityNum;  
        }  
  
        if (ran1 > ran2)// 确保ran1<ran2  
        {  
            temp = ran1;  
            ran1 = ran2;  
            ran2 = temp;  
        }  
        // System.out.println();  
        // System.out.println("-----------------------");  
        // System.out.println("----"+ran1+"----"+ran2);  
        // System.out.println("-----------------------");  
        // System.out.println();  
        flag = ran2 - ran1 + 1;// 删除重复基因前染色体长度  
        for (i = 0, j = ran1; i < flag; i++, j++) {  
            Gh1[i] = newPopulation[k2][j];  
            Gh2[i] = newPopulation[k1][j];  
        }  
        // 已近赋值i=ran2-ran1个基因  
  
        for (k = 0, j = flag; j < cityNum;)// 染色体长度  
        {  
            Gh1[j] = newPopulation[k1][k++];  
            for (i = 0; i < flag; i++) {  
                if (Gh1[i] == Gh1[j]) {  
                    break;  
                }  
            }  
            if (i == flag) {  
                j++;  
            }  
        }  
  
        for (k = 0, j = flag; j < cityNum;)// 染色体长度  
        {  
            Gh2[j] = newPopulation[k2][k++];  
            for (i = 0; i < flag; i++) {  
                if (Gh2[i] == Gh2[j]) {  
                    break;  
                }  
            }  
            if (i == flag) {  
                j++;  
            }  
        }  
  
        for (i = 0; i < cityNum; i++) {  
            newPopulation[k1][i] = Gh1[i];// 交叉完毕放回种群  
            newPopulation[k2][i] = Gh2[i];// 交叉完毕放回种群  
        }  
  
        // System.out.println("进行交叉--------------------------");  
        // System.out.println(k1+"交叉后...");  
        // for (i = 0; i < cityNum; i++) {  
        // System.out.print(newPopulation[k1][i] + "-");  
        // }  
        // System.out.println();  
        // System.out.println(k2+"交叉后...");  
        // for (i = 0; i < cityNum; i++) {  
        // System.out.print(newPopulation[k2][i] + "-");  
        // }  
        // System.out.println();  
        // System.out.println("交叉完毕--------------------------");  
    }  
  
    // 交叉算子,相同染色体交叉产生不同子代染色体  
    public void OXCross1(int k1, int k2) {  
        int i, j, k, flag;  
        int ran1, ran2, temp;  
        int[] Gh1 = new int[cityNum];  
        int[] Gh2 = new int[cityNum];  
        // Random random = new Random(System.currentTimeMillis());  
  
        ran1 = random.nextInt(65535) % cityNum;  
        ran2 = random.nextInt(65535) % cityNum;  
        while (ran1 == ran2) {  
            ran2 = random.nextInt(65535) % cityNum;  
        }  
  
        if (ran1 > ran2)// 确保ran1<ran2  
        {  
            temp = ran1;  
            ran1 = ran2;  
            ran2 = temp;  
        }  
  
        // 将染色体1中的第三部分移到染色体2的首部  
        for (i = 0, j = ran2; j < cityNum; i++, j++) {  
            Gh2[i] = newPopulation[k1][j];  
        }  
  
        flag = i;// 染色体2原基因开始位置  
  
        for (k = 0, j = flag; j < cityNum;)// 染色体长度  
        {  
            Gh2[j] = newPopulation[k2][k++];  
            for (i = 0; i < flag; i++) {  
                if (Gh2[i] == Gh2[j]) {  
                    break;  
                }  
            }  
            if (i == flag) {  
                j++;  
            }  
        }  
  
        flag = ran1;  
        for (k = 0, j = 0; k < cityNum;)// 染色体长度  
        {  
            Gh1[j] = newPopulation[k1][k++];  
            for (i = 0; i < flag; i++) {  
                if (newPopulation[k2][i] == Gh1[j]) {  
                    break;  
                }  
            }  
            if (i == flag) {  
                j++;  
            }  
        }  
  
        flag = cityNum - ran1;  
  
        for (i = 0, j = flag; j < cityNum; j++, i++) {  
            Gh1[j] = newPopulation[k2][i];  
        }  
  
        for (i = 0; i < cityNum; i++) {  
            newPopulation[k1][i] = Gh1[i];// 交叉完毕放回种群  
            newPopulation[k2][i] = Gh2[i];// 交叉完毕放回种群  
        }  
    }  
  
    // 多次对换变异算子  
    public void OnCVariation(int k) {  
        int ran1, ran2, temp;  
        int count;// 对换次数  
  
        // Random random = new Random(System.currentTimeMillis());  
        count = random.nextInt(65535) % cityNum;  
  
        for (int i = 0; i < count; i++) {  
  
            ran1 = random.nextInt(65535) % cityNum;  
            ran2 = random.nextInt(65535) % cityNum;  
            while (ran1 == ran2) {  
                ran2 = random.nextInt(65535) % cityNum;  
            }  
            temp = newPopulation[k][ran1];  
            newPopulation[k][ran1] = newPopulation[k][ran2];  
            newPopulation[k][ran2] = temp;  
        }  
  
        /* 
         * for(i=0;i<L;i++) { printf("%d ",newGroup[k][i]); } printf("\n"); 
         */  
    }  
  
    public void solve() {  
        int i;  
        int k;  
  
        // 初始化种群  
        initGroup();  
        // 计算初始化种群适应度,Fitness[max]  
        for (k = 0; k < scale; k++) {  
            fitness[k] = evaluate(oldPopulation[k]);  
            // System.out.println(fitness[k]);  
        }  
        // 计算初始化种群中各个个体的累积概率,Pi[max]  
        countRate();  
        System.out.println("初始种群...");  
        for (k = 0; k < scale; k++) {  
            for (i = 0; i < cityNum; i++) {  
                System.out.print(oldPopulation[k][i] + ",");  
            }  
            System.out.println();  
            System.out.println("----" + fitness[k] + " " + Pi[k]);  
        }  
          
        for (t = 0; t < MAX_GEN; t++) {  
            //evolution1();  
            evolution();  
            // 将新种群newGroup复制到旧种群oldGroup中,准备下一代进化  
            for (k = 0; k < scale; k++) {  
                for (i = 0; i < cityNum; i++) {  
                    oldPopulation[k][i] = newPopulation[k][i];  
                }  
            }  
            // 计算种群适应度  
            for (k = 0; k < scale; k++) {  
                fitness[k] = evaluate(oldPopulation[k]);  
            }  
            // 计算种群中各个个体的累积概率  
            countRate();  
        }  
  
        System.out.println("最后种群...");  
        for (k = 0; k < scale; k++) {  
            for (i = 0; i < cityNum; i++) {  
                System.out.print(oldPopulation[k][i] + ",");  
            }  
            System.out.println();  
            System.out.println("---" + fitness[k] + " " + Pi[k]);  
        }  
  
        System.out.println("最佳长度出现代数:");  
        System.out.println(bestT);  
        System.out.println("最佳长度");  
        System.out.println(bestLength);  
        System.out.println("最佳路径:");  
        for (i = 0; i < cityNum; i++) {  
            System.out.print(bestTour[i] + ",");  
        }  
  
    }  
  
      
    /** 
     * @param args 
     * @throws IOException 
     */  
    public static void main(String[] args) throws IOException {  
        System.out.println("Start....");  
        GA ga = new GA(30, 48, 1000, 0.8f, 0.9f);  
        ga.init("c://data.txt");  
        ga.solve();  
    }  
  
}

参考:https://blog.csdn.net/tyhj_sf/article/details/53321527