精华内容
下载资源
问答
  • 性能优化:反序列

    2020-11-28 19:36:27
    而在运行时需从磁盘读取序列化为原始对象类型,但这是非常非常耗时的操作。这种反序列化在调用Resource.load时发生。因此,场景开始时,你会发现有些场景加载时间会比较长,因为它们开始需要的加载资源太多,会...

    Unity有场景文件、预设体、ScriptableObject和各种资产类型(派生自ScriptObject)。当它们需要保存至磁盘时,需要转换为文本文件,Unity称之为“序列化文件”。而在运行时需从磁盘读取和反序列化为原始对象类型,但这是非常非常耗时的操作。这种反序列化在调用Resource.load时发生。因此,场景开始时,你会发现有些场景加载时间会比较长,因为它们开始需要的加载资源太多,会增加加载时间。另外,在运行时动态加载资源它们时,也可能会导致掉帧现象。因此,为了让玩家能快速进入游戏场景以及玩的过程中不出现卡顿掉帧的情况,我们需要对资源加载机制做如下优化处理:

    首先,让序列化对象尽可能合理的“小”。比如:把UI模块,切分成功能不同的UI子模块:活动,主界面,商场,邮箱等面板预设,玩家打开时,只需加载对应的面板预设。

    其次,异步加载序列化对象。可以通过Resource.LoadAsync()实现异步加载。这样可以把从磁盘读取的任务转移到工作线程上,从而减轻主线程的负担。这种加载方式,对于立即需要使用的资源来说不理想,它比较适用于可以“提前”加载“未来”需要使用的资源。

    其二,可以在内存中保存之前加载了的序列化对象。针对场景中需要频繁使用到的资源比较适用。这样避免了频繁地从磁盘读取它们。我们可以使用Resource.Unload()方法来手动卸载这些资源,以释放内存空间。说白了,就是牺牲内存来换取时间效率的方式。

    最后,将共享的数据移入ScriptObject对象中。将场景很多游戏对象都需要用到了数据如游戏的命中率、力量、帧率、用户数据、关卡数据等,将它们序列化到ScriptObject中,运行时加载然后共用。这样,那些游戏对象预设文件也不需要每个都需要存储这些共享数据,间接地可以减少场景加载地时间。

    展开全文
  • 首先,该问题可描述为:给出一个由n个数组成的序列seq[1..n],找出它的最长非递减非连续序列。即求最大的 m a1,a2……,am,使得a1希望新手能先将上面的题目描述读上两三遍,然后再往下看,以免因对题意模糊不清...

    最近在学习动态规划的对于研究同样问题的朋友有所帮助。

    首先,该问题可描述为:给出一个由n个数组成的序列seq[1..n],找出它的最长非递减非连续序列。即求最大的 m 和a1,a2……,am,使得a1

    希望新手能先将上面的题目描述读上两三遍,然后再往下看,以免因对题意模糊不清影响而理解。

    下面我就来讲两种用动态规划思想来解此题的方法,其中第一种是原始的方法,虽然比较容易理解,但是算法效率不高,时间复杂度为O(n^2),而第二种算法是在第一种算法基础上进行优化得到的,其时间复杂度为O(n log n),虽然算法效率得到了提高,但是算法的理解难度也变大了。

    先从简单的算法入手,首先我们用seq[1....n]表示要找最长子序列的序列,sub_seq[]就代表要找的最长子序列。和一般的用动态规划思想解决的问题一样,我们可以这样来分析问题,如果以seq[k]为尾元素的序列seq[1....k](1<=k

    基本思想明白了之后,就开始给该问题定义状态,我们定义一个数组dp[1....n]来表示状态,dp[i]的含义是序列seq[1.....i]的最长子序列的长度,好了,那么dp[k+1]可以这样来求,对seq[1...k]从前往后扫描,如果seq[i](1<= i <= k)小于等于seq[k+1],那么就比较dp[i]+1和dp[k+1](dp[k+1]初始化为一个很小的数)的大小,如果dp[i] + 1大的话,就把dp[i] +1赋给dp[k+1],因为seq[1....i]的最长子串的长度为dp[i],和seq[k+1]组合后可形成长度为dp[i]+1的子串。最后,dp[1.....n]都求出来以后,从dp[]中选出最大的值,就是序列seq[1...n]的最长子序列。如果不止要求长度,还要得到具体的子序列的话,可以用一个数组pre[]来保存上一个结点,dp[i]的含义就是seq[i]的上一个元素,这个不是这里讲的重点,就不多说了。下面给出的是代码。实现的时候用了很多STL中的东西,但是如果读者不了解STL的话,用基本的数组也可以实现。代码中的函数LNDSS就是用来求最长序列的。

    #include

    #include

    #include

    #include

    #include

    #include

    using namespace std;

    /*

    同态规划法求最长非递减非连续子序列

    状态转移方程:dp[i] = 1 + max{ dp[k] | k < i 并且 seq[k] <= seq[i] }

    时间复杂度:O(n lgn)

    */

    void LNDSS(vector& seq, vector& sub_seq)

    {

    vector dp(seq.size(), 0);//dp[i]的值代表以seq数组中的第i个元素为尾的非连续序列的 最大 长度

    vector pre(seq.size(), -1);//pre[i]的值代表在非连续序列中第i个元素的前一个元素的下标

    int i,j;

    for(i = 0; i < seq.size(); i ++)

    {

    for(j = 0; j < i; j ++)

    {

    if(seq[i] >= seq[j] && dp[j] + 1 > dp[i])

    {

    dp[i] = dp[j] + 1;

    pre[i] = j;

    }

    }

    }

    int tmp = max_element(dp.begin(), dp.end()) - dp.begin();

    do

    {

    sub_seq.push_back(seq[tmp]);

    tmp = pre[tmp];

    }while(-1 != tmp);

    reverse(sub_seq.begin(), sub_seq.end());

    }

    int main(void)

    {

    vector seq;

    int tmp;

    while(scanf("%d",&tmp), tmp)

    {

    seq.push_back(tmp);

    }

    vector sub_seq;

    LNDSS(seq, sub_seq);

    for(int i = 0; i < sub_seq.size(); i ++)

    {

    printf("%d\n", sub_seq[i]);

    }

    printf("\n");

    return 0;

    }

    好的,下面来讲第二种比较复杂的方法。这种方法的是深入分析了问题后得来的。再来回顾上一种方法,其实我们可以发现,上面在求每个状态dp[i]的时候,都必须遍dp[1...i-1]这i-1种状态,在动态规划的过程中要求n个状态,每个状态又要做i-1个动态转移操作,所以总共要做的基本操作个数是1+2+3+....+ (i-1) + (n -1),是一个等差级数,所以上面的算法时间规模是O(n^2)。那么如果要对算法进行优化的话,需要那个地方优化呢?我们可以这样分析,首先,求n个状态这一步很难再优化了,但是我们仍然可能在求状态的时候减少决策所产生的操作。第一种算法求每个状态,比如求dp[n]的时候要做n-1个状态转移操作,那么是不是可以只进行一次状态转移呢?其实第二种算法的优化就是这样的。

    在讲原理之前先把算法的大致操作给大家描述一下。你在求状态值dp[i]的时候,要是按照第一种方法,需要参考前面i-1个元素的状态值,但是其实前面的这i-1种状态值并不是都需要参考,有一些注定了对dp[i]这个状态值没有影响(至于为什么没有影响,下面会讨论)。第二种算法是这样的,给你一个类似于集合的容器set(可以用数组、栈、平衡树等实现),假如你在求状态值dp[i]的时候,这个容器里面存的东西就是你做状态转移时所需要参考的前面的状态,注意里面的状态个数要小于或者等于i-1。所以你要求的dp[i]取决于这个容器里面状态。这个容器里面的东西你可以先认为它们是一个个的结构体变量,结构体的里面的三个成员为①、seq[1...n]中某个元素的下标,不妨设为i,②序列seq[1...n]中第i个元素的值seq[i]。③序列seq[1...n]中第i个元素所对应的状态值dp[i]。请读者注意一下,并不是seq[1...n]中每个元素对应的状态值dp[i]都在set中。set中存放的元素值才是我们求状态值dp[i]的时候做决策需要参考的,一些不需要参考的前面已经求出的状态值不会出现在集合中(至于哪个dp[i]才是我们做决策时用到的,在下面会讲到),而且我们每求一个状态值dp[i],只需要在集合set中做复杂度为O(logn)的操作(至于怎么操作,下面讲),这样的话,算法的总体规模降为O(nlogn)。

    在算法的大体运行机制了解之后,我们分析算法的原理。来看这个特殊的集合set,在集合中任取两个元素,如第i个和第j个,(注意i、j的大小关系不定,任取)可知:如果seq[i] < seq[j] (再次提一下:i和j没有先后顺序),那么dp[i] >= dp[j]的情况不会出现,即dp[i] < dp[j],为什么呢?①因为如果dp[i] > dp[j] 那么在求dp[k]的时候,k > i > j,则dp[k]既可以从dp[i]转移,也可以选择从dp[j]转移,但是从dp[i]转移得到的dp[k]

    = dp[i] + 1,而从dp[j]转移得到的dp[k] = dp[j] + 1,但是dp[i] > dp[j],所以从dp[i]转移就可以,dp[j]根本没用处。②如果dp[i] = dp[j] ,那么dp[k]从dp[i] 转移和从dp[j]转移是一样的,所以dp[j]没有必要再set中。其实通过上面的分析,我们能够知道set里面的元素如果以seq[i]为主键按升序排好序的话,dp[i]也是升序的,这样就为我们做状态转移提供了一种大大提高效率的可能。

    接下来就是状态转移了,任意求一个状态值dp[k],在求dp[k]之前dp[1]、dp[2]、.....‘dp[k-1]都已经求好了,并且对dp[k]有影响的前面的状态都放到了集合set中。我们要求dp[k],其实就是求得如何和前面已经得到的字串进行结合得到最长的字串,首先前面得到的子串的最后一个元素必须小于等于seq[k],因为只有这样才可以和seq[k]组成一个以seq[k]为最后一个元素的非递减非连续子序列。而set里面的值是按dp值(也是按seq值)递增排列的,我们要找的最适合转移的状态就是set中最后一个不小于seq[k]的值(不妨设为q),所以dp[k]

    = dp[q] + 1;

    好了,下面就给大家奉上一段写的非常简练的代码,大家好好琢磨琢磨吧!!!因本人知识水平有限,所言难免有许多不正确的地方,还有很多没有说明白的地方,欢迎大家批评指正。如果有联系的必要的话可以加我的QQ: 774267423

    int LNDSS(int a[], int n)

    {

    int i, j, * b = new int[n + 1], ans = 0;

    b[ans] = - 0x3f3f3f3f;

    for(i = 0; i < n; i ++)

    {

    j = upper_bound(b, b + ans + 1, a[i]) - b;

    if(j > ans)

    b[++ans] = a[i];

    else if(a[i] < b[j])

    b[j] = a[i];

    }

    delete b;

    return ans;

    }

    这是第二种算法的参考资料,(如果我的你看不懂,可以看看这个试试)毛子青论文<>,一个最长子序列的算法

    展开全文
  • 快速的原理就是因为折半递归,所以初始pivot应该有个好一点的选择,这里在原序列左右中间序的值取中值作为pivot,位置仍然放置于左侧第一元素位置(交换)。 这就变成了工程优化的快速排序了 ————————...

    quicksort中,当n小于一定值时,排序效率就比直接插入排序底了,所以,此时就不要再递归下去了,直接插入排序好了;快速的原理就是因为折半递归,所以初始pivot应该有个好一点的选择,这里在原序列左右和中间序的值取中值作为pivot,位置仍然放置于左侧第一元素位置(交换)。

    这就变成了工程优化的快速排序了

    ——————————————————————————————————————————————————

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

    void insertsort(int arr[], int left, int right)
    {
    int temp, i, j;
    for (i=left+1; i<=right; i++)
    {
    if (arr[i]<arr[i-1])
    {
    temp = arr[i];
    for(j=i-1; j>=left&&temp<arr[j]; j--)
    {
    arr[j+1] = arr[j];
    }
    arr[j+1] = temp;
    }
    }
    }

    int partition(int arr[], int low, int high)
    {
    int i = low, j = high, pivot = arr[low];
    while (i<j)
    {
    while (i<j&&arr[j]>=pivot)
    {
    j--;
    }
    if (i<j)
    {
    arr[i] = arr[j];
    i++;
    while (i<j&&arr[i]<=pivot)
    {
    i++;
    }
    if (i<j)
    {
    arr[j] = arr[i];
    j--;
    }
    }
    }
    arr[i] = pivot;
    return i;
    }

    void swap(int arr[], int i, int j)
    {
    int temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
    }

    void median3_alignleft(int arr[], int left, int right)
    {
    int mid = (left+right)/2, k1, k2;
    if (arr[left]<=arr[mid])
    {
    k1 = left;
    k2 = mid;
    }
    else
    {
    k1 = mid;
    k2 = left;
    }
    if (arr[right]<arr[k1])
    {
    k2 = k1;
    }
    else if (arr[right]<arr[k2])
    {
    k2 = right;
    }
    if (k2!=left)
    {
    swap(arr, k2, left);
    }
    }

    void quicksort_insert(int arr[], int left, int right, int M)
    {
    if (right-left<=0)
    {
    return;
    }
    if (right-left+1<M)
    {
    insertsort(arr, left, right);
    }
    else
    {
    median3_alignleft(arr, left, right);
    int pivotpos = partition(arr, left, right);
    quicksort_insert(arr, left, pivotpos-1, M);
    quicksort_insert(arr, pivotpos+1, right, M);
    }
    }

    void main()
    {
    int arr[] = {99, 29, 17, 11, 36, 55, 47, 2, 3, 8, 12, 66};
    int len = sizeof(arr)/sizeof(int);

    quicksort_insert(arr, 0, len-1, 5);

    for(int i=0; i<len; i++)
    {
    printf("%d ", arr[i]);
    }

    printf("\n");
    }

     

    //result

    # ./sort
    2 3 8 11 12 17 29 36 47 55 66 99

     

    Finally:

    M可以固定取值5-25之间任意数

    这个可以作为自实现算法库来保留了,你的C工程里最好能有它。

    转载于:https://www.cnblogs.com/woodzcl/p/8042370.html

    展开全文
  • 灰色GM(1,1)预测方法仅针对累加生成满足近似指数特点的原始序列建立预测模型。为了拓宽传统灰色预测模型的应用范围,设计了通过优化初始条件提高灰色 GM(1,1)预测精度的新方法——DGM(1,1,c,β)模型。对满足...
  • 灰色GM(1,1)模型的初始条件对...然后,基于时间权重序列,对模拟序列与原始序列的误差平方进行加权;最后,求解最优问题,确定时间参数,从而建立优化模型.算例表明,所提出的优化模型具有可行性,可以有效地提高模型的精度.
  • 由Platt提出的序列最小最优化算法(SMO)可以高效的求解上述SVM问题,它把原始求解N个参数二次规划问题分解成很多个子二次规划问题分别求解,每个子问题只需要求解2个参数,方法类似于坐标上升,节省时间成本降低了...

    1998年,由Platt提出的序列最小最优化算法(SMO)可以高效的求解上述SVM问题,它把原始求解N个参数二次规划问题分解成很多个子二次规划问题分别求解,每个子问题只需要求解2个参数,方法类似于坐标上升,节省时间成本和降低了内存需求。每次启发式选择两个变量进行优化,不断循环,直到达到函数最优值。

    https://blog.csdn.net/m_buddy/article/details/52496538

    1. SMO SVM算法简述
      1.1 概述
    SVM(Support Vector Machine,SVM)算法既是支持适量机算法。算法的原始思想很简单,既是找到一个决策面使两类(本文以两类为例进行说明)分开,且这个决策面和两类之间的间隙尽可能的大。这样带来的好处就是泛化错误率低,能够很好地对两类的问题进行分类。
    因而,SVM算法的优点就是泛化错误率低,计算的开销不大,结果容易解释。缺点就是算法对参数的选择和核函数的选择敏感,原始的分类器适合二分类。
      1.2 原理
    我们定义决策面为:
     

    点到面的距离:

    在SVM算法中距离决策面近的点的g(x)的值为+1(对应类别X1)或是-1(对应类别X2),因而需要满足的条件为:

    公式中的X1和X2对应为两个类别,则公式(3)可以被写为:

    由于yi有正负对应上式3,则条件全为大于等于1的

    因而对于上述的二次优化问题可以有KKT条件,用拉格朗日方程的形式写出:

     

    则将公式(5)中的第一个、第二个式子带入到最后一个式子中,得到:

     

    则对(5)最后一个式子最大化,将(6)带入到(5)中的最后一个式子代数运算之后得到的等价的优化为:

     

    则通过解上诉的方程组,得到决策面的系数,就可以作为以后的分类使用了。但是上述的方法具有缺陷,它是对应下面分布的情况的,在这样的情况中,能够直接找到一个决策面。但是对于接下来的一种分布情况就不适用了(图片来源于度娘)

     

    1.2 情况2

    先来看一下这里分析的分类情况(图片来源于网络):

    在这样的分布情况下就出现了3中可能的情况,(1)位于分离段以外并且正确分类的数据;(2)落在分离段内部,但是正确分类了的数据;(3)被错误分类的数据。因而原来的原始约束条件就写为了:

    因而,对于情况(1)这里定义的偏移量为0了;情况(2)偏移量就大于0且小于1;情况(3)偏移量大于0。这里引入了偏移量(松弛变量)增加了变量的个数,但是SVM算法的目的是使得分类间隔尽可能大,同时保持偏移量大于0的数据尽可能少。 则原来的最小化函数J就变成了:

     

    其中I(x)是0-1的阶跃函数,但是区间为大于等于0。引入了偏移量之后的推导也是跟之前情况的推导是类似的,则最后得到的优化函数为:

    2. Platt的SMO算法
      2.1 SMO方法
    SMO方法是将原来SVM的二次规划问题转化为固定大小的二次规划子问题。因为SVM算法需要遵循公式(10)中限制条件1,所以SMO方法选择两个λ进行优化。在SMO方法中使用启发式的方法选择两个λ,这样选取会极大加速算法的收敛速度,做过对比证明要比随机的撞天婚方法快很多很多。这是论文中SMO方法更新λ的部分(偷下懒截出来仅供交流),在该论文的2.2节介绍了循环的条件,读者可以下载论文下来进行阅读。 

    https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/smo-book.pdf

     

    # -*- coding: utf-8 -*-
    """
    Created on Sun Jul 22 20:22:19 2018

    @author: wzy
    """
    import matplotlib.pyplot as plt
    import numpy as np
    import random

    """
    函数说明:读取数据

    Parameters:
        fileName - 文件名
        
    Returns:
        dataMat - 数据矩阵
        labelMat - 数据标签

    Modify:
        2018-07-23
    """
    def loadDataSet(fileName):
        # 数据矩阵
        dataMat = []
        # 标签向量
        labelMat = []
        # 打开文件
        fr = open(fileName)
        # 逐行读取
        for line in fr.readlines():
            # 去掉每一行首尾的空白符,例如'\n','\r','\t',' '
            # 将每一行内容根据'\t'符进行切片
            lineArr = line.strip().split('\t')
            # 添加数据(100个元素排成一行)
            dataMat.append([float(lineArr[0]), float(lineArr[1])])
            # 添加标签(100个元素排成一行)
            labelMat.append(float(lineArr[2]))
        return dataMat, labelMat


    """
    函数说明:随机选择alpha_j

    Parameters:
        i - alpha
        m - alpha参数个数
        
    Returns:
        j - 返回选定的数字

    Modify:
        2018-07-23
    """
    def selectJrand(i, m):
        j = i
        while(j == i):
            # uniform()方法将随机生成一个实数,它在[x, y)范围内
            j = int(random.uniform(0, m))
        return j


    """
    函数说明:修剪alpha

    Parameters:
        aj - alpha值
        H - alpha上限
        L - alpha下限
        
    Returns:
        aj - alpha值

    Modify:
        2018-07-23
    """
    def clipAlpha(aj, H, L):
        if aj > H:
            aj = H
        if L > aj:
            aj = L
        return aj


    """
    函数说明:简化版SMO算法

    Parameters:
        dataMatIn - 数据矩阵
        classLabels - 数据标签
        C - 松弛变量
        toler - 容错率
        maxIter - 最大迭代次数
        
    Returns:
        None

    Modify:
        2018-07-23
    """
    def smoSimple(dataMatIn, classLabels, C, toler, maxIter):
        # 转换为numpy的mat矩阵存储(100,2)
        dataMatrix = np.mat(dataMatIn)
        # 转换为numpy的mat矩阵存储并转置(100,1)
        labelMat = np.mat(classLabels).transpose()
        # 初始化b参数,统计dataMatrix的维度,m:行;n:列
        b = 0
        # 统计dataMatrix的维度,m:100行;n:2列
        m, n = np.shape(dataMatrix)
        # 初始化alpha参数,设为0
        alphas = np.mat(np.zeros((m, 1)))
        # 初始化迭代次数
        iter_num = 0
        # 最多迭代maxIter次
        while(iter_num < maxIter):
            alphaPairsChanged = 0
            for i in range(m):
                # 步骤1:计算误差Ei
                # multiply(a,b)就是个乘法,如果a,b是两个数组,那么对应元素相乘
                # .T为转置
                fxi = float(np.multiply(alphas, labelMat).T * (dataMatrix * dataMatrix[i, :].T)) + b
                # 误差项计算公式
                Ei = fxi - float(labelMat[i])
                # 优化alpha,设定一定的容错率
                if((labelMat[i] * Ei < -toler) and (alphas[i] < C)) or ((labelMat[i] * Ei > toler) and (alphas[i] > 0)):
                    # 随机选择另一个alpha_i成对比优化的alpha_j
                    j = selectJrand(i, m)
                    # 步骤1,计算误差Ej
                    fxj = float(np.multiply(alphas, labelMat).T * (dataMatrix * dataMatrix[j, :].T)) + b
                    # 误差项计算公式
                    Ej = fxj - float(labelMat[j])
                    # 保存更新前的alpha值,使用深拷贝(完全拷贝)A深层拷贝为B,A和B是两个独立的个体
                    alphaIold = alphas[i].copy()
                    alphaJold = alphas[j].copy()
                    # 步骤2:计算上下界H和L
                    if(labelMat[i] != labelMat[j]):
                        L = max(0, alphas[j]  -alphas[i])
                        H = min(C, C + alphas[j] - alphas[i])
                    else:
                        L = max(0, alphas[j] + alphas[i] - C)
                        H = min(C, alphas[j] + alphas[i])
                    if(L == H):
                        print("L == H")
                        continue
                    # 步骤3:计算eta
                    eta = 2.0 * dataMatrix[i, :] * dataMatrix[j, :].T - dataMatrix[i, :] * dataMatrix[i, :].T - dataMatrix[j, :] * dataMatrix[j, :].T
                    if eta >= 0:
                        print("eta>=0")
                        continue
                    # 步骤4:更新alpha_j
                    alphas[j] -= labelMat[j] * (Ei - Ej) / eta
                    # 步骤5:修剪alpha_j
                    alphas[j] = clipAlpha(alphas[j], H, L)
                    if(abs(alphas[j] - alphaJold) < 0.00001):
                        print("alpha_j变化太小")
                        continue
                    # 步骤6:更新alpha_i
                    alphas[i] += labelMat[j] * labelMat[i] * (alphaJold - alphas[j])
                    # 步骤7:更新b_1和b_2
                    b1 = b - Ei - labelMat[i] * (alphas[i] - alphaIold) * dataMatrix[i, :] * dataMatrix[i, :].T - labelMat[j] * (alphas[j] - alphaJold) * dataMatrix[j, :] * dataMatrix[i, :].T
                    b2 = b - Ej - labelMat[i] * (alphas[i] - alphaIold) * dataMatrix[i, :] * dataMatrix[j, :].T - labelMat[j] * (alphas[j] - alphaJold) * dataMatrix[j, :] * dataMatrix[j, :].T
                    # 步骤8:根据b_1和b_2更新b
                    if(0 < alphas[i] < C):
                        b = b1
                    elif(0 < alphas[j] < C):
                        b = b2
                    else:
                        b = (b1 + b2) / 2.0
                    # 统计优化次数
                    alphaPairsChanged += 1
                    # 打印统计信息
                    print("第%d次迭代 样本:%d, alpha优化次数:%d" % (iter_num, i, alphaPairsChanged))
            # 更新迭代次数
            if(alphaPairsChanged == 0):
                iter_num += 1
            else:
                iter_num = 0
            print("迭代次数:%d" % iter_num)
        return b, alphas
                    

    """
    函数说明:计算w

    Returns:
        dataMat - 数据矩阵
        labelMat - 数据标签
        alphas - alphas值
        
    Returns:
        w - 直线法向量

    Modify:
        2018-07-24
    """
    def get_w(dataMat, labelMat, alphas):
        alphas, dataMat, labelMat = np.array(alphas), np.array(dataMat), np.array(labelMat)
        # 我们不知道labelMat的shape属性是多少,
        # 但是想让labelMat变成只有一列,行数不知道多少,
        # 通过labelMat.reshape(1, -1),Numpy自动计算出有100行,
        # 新的数组shape属性为(100, 1)
        # np.tile(labelMat.reshape(1, -1).T, (1, 2))将labelMat扩展为两列(将第1列复制得到第2列)
        # dot()函数是矩阵乘,而*则表示逐个元素相乘
        # w = sum(alpha_i * yi * xi)
        w = np.dot((np.tile(labelMat.reshape(1, -1).T, (1, 2)) * dataMat).T, alphas)
        return w.tolist()


    """
    函数说明:分类结果可视化

    Returns:
        dataMat - 数据矩阵
        w - 直线法向量
        b - 直线截距
        
    Returns:
        None

    Modify:
        2018-07-23
    """
    def showClassifer(dataMat, w, b):
        # 正样本
        data_plus = []
        # 负样本
        data_minus = []
        for i in range(len(dataMat)):
            if labelMat[i] > 0:
                data_plus.append(dataMat[i])
            else:
                data_minus.append(dataMat[i])
        # 转换为numpy矩阵
        data_plus_np = np.array(data_plus)
        # 转换为numpy矩阵
        data_minus_np = np.array(data_minus)
        # 正样本散点图(scatter)
        # transpose转置
        plt.scatter(np.transpose(data_plus_np)[0], np.transpose(data_plus_np)[1], s=30, alpha=0.7)
        # 负样本散点图(scatter)
        plt.scatter(np.transpose(data_minus_np)[0], np.transpose(data_minus_np)[1], s=30, alpha=0.7)
        # 绘制直线
        x1 = max(dataMat)[0]
        x2 = min(dataMat)[0]
        a1, a2 = w
        b = float(b)
        a1 = float(a1[0])
        a2 = float(a2[0])
        y1, y2 = (-b - a1 * x1) / a2, (-b - a1 * x2) / a2
        plt.plot([x1, x2], [y1, y2])
        # 找出支持向量点
        # enumerate在字典上是枚举、列举的意思
        for i, alpha in enumerate(alphas):
            # 支持向量机的点
            if(abs(alpha) > 0):
                x, y = dataMat[i]
                plt.scatter([x], [y], s=150, c='none', alpha=0.7, linewidth=1.5, edgecolors='red')
        plt.show()


    if __name__ == '__main__':
        dataMat, labelMat = loadDataSet('testSet.txt')
        b, alphas = smoSimple(dataMat, labelMat, 0.6, 0.001, 40)
        w = get_w(dataMat, labelMat, alphas)
        showClassifer(dataMat, w, b)
        

     

    展开全文
  • @[TOC](最长公共子序列问题(Longest Common ...注意:一个子序列和子字符串不同,前者并不需要连续的原始序列。例如:对于“ABCD”和“AEFC”,它们的最长公共子序列(LCS)是“AC”,长度为2。 解答 有两个序列S和T...
  • 使用RNN解决NLP中序列标注问题的通用优化思路

    万次阅读 多人点赞 2016-02-23 19:11:46
    /* 版权声明:可以任意转载,转载时请标明文章原始出处作者信息 .*/    author: 张俊林     (想更系统地学习深度学习知识?请参考:深度学习枕边书) 序列标注问题应该说是自然语言处理中最...
  • 对于非线性约束最优化问题,序列二次规划内点法是两类非常重要的算法,也是大规模问题的利器。序列二次规划方法将原始问题分解为一系列二次规划问题逐步求解;内点法将将约束添加到目标函数中转换为一系列无约束...
  • 我们提出了时间日志树(TL-Tree),这是一种新颖的不平衡级联结构,它利用了可用的闪存容量,同时利用时间序列属性作为优化内存能源约束的主要功能。 大量的实验表明TL-Tree具有利用闪存容量时间局部性来支持...
  • 在本文中,我们提出了时间日志树(TL-Tree)-一种新颖的不平衡级联结构,该结构利用了可用的闪存容量,同时将时间序列属性作为优化内存能量限制。 大量的实验表明TL树能够利用闪存容量时间局部性来支持传感器...
  • 1)的灰导数出发,利用向前差商向后差商的加权平均值作为GM(1,1)的灰导数白化值, 并给出了加权系数λ的具体表达式,进而建立了优化灰导数后适用于原始序列为非齐次指数律的GM(1,1)模型,且证明了此模型具有白指数律...
  • 在前一篇文章中,我们给出了感知器逻辑...我们使用广义拉格朗日函数,将目标函数限制条件写到一起,然后证明了原始问题能够转化成对偶问题来求解。并且使用KKT条件将对偶问题化简,得到下面的问题(以非线性可...
  • /*版权声明:可以任意转载,转载时请标明文章原始出处作者信息.*/ author:张俊林 序列标注问题应该说是自然语言处理中最常见的问题,而且很可能是最...
  • 首先运用能克服传统EMD算法中模态混叠现 象的EEMD算法, 按原始时间序列信号的构成特点将其分解到不同尺度, 然后对不同尺度序列采用 C-C方法重构相空间, 在相空间中运用基于混合核函数的KPCR方法构建预测函数....
  • 下图中的三个图中描述的时间序列分别是原始的价格数据,以及做了差分(比如一步的差分其实就是今天的价格昨天的价格相减再除以昨天的价格),以及对原始数据取对数然后再差分的时间序列的图。 之所以这样处理...
  • 随着互联网规模应用的扩大,网络数据流量呈现出复杂多分形性的特点,针对这个特性,构建了基于小波分析ARMA模型的网络流量预测模型,用Mallat算法将原始流量数据分解为4个分层数据,对各层数据用ARMA模型进行预测,再...
  • 求上升子序列最大原始n^2的算法优化,是对内层for循环优化。 内层for循环求的是 dp[ i ] = max ( dp[ 1 ] ......dp[ i-1 ] ) ; 可以看出是区间 查询最大值。理论上线段树 log n 查询时间, 修改也是单点修改 ...
  • 基因组数据库保存了海量的原始数据。人类基因本身就有接近 30 亿个 DNA 碱基对。为了查遍所有数据并找到其中有意义的关系,分子生物学家们越来越依赖于高效的计算机科学字符串算法。本文将介绍三个这方面的算法,...
  • 首先对原始序列建立GM(1,1) 幂模型以描述系统行为的总体趋势; 然后利用傅立叶级数提取模型的残差序列所包含的周期性振荡规律, 并以二者之构成新的时间响应函数; 最后以平均误差最小化为目标, 建立非线性优化模型...
  • 互相关算法在多传感器测量仪器中有重要用途,FFT算法可以用于加速互相关计算,尤其在序列点数较大的时候,FFT计算互相关的...根据参与互相关的两个原始信号都是实数序列的特点,进一步优化计算流程,显著降低了计算量。
  • 本文以相对误差平方最小为目标优化 GM(1,1)模型,分别对初始条件初始点进行优化,给出优化的计算公式,并证明在原始序列相对误差平方最小的准则下,初始条件优化和初始点优化是统一的.实例表明运用优化公式与数值...
  • LinDB借鉴了TSDB的许多最佳实践,并根据时间序列数据的特征实现了一些优化。 与为InfluxDB编写大量的Continuous-Query不同,LinDB在创建数据库后自动以特定的间隔支持汇总。 而且,LinDB对于分布式时间序列数据的...
  • 23(5) IO文件切割合并-对象的序列化 导语: 可以说整个下午都在玩伊苏7,挺好玩的,现在也没心情打代码,先把代码弄成mk格式的html 实现了Serializable接口。详细描述了该接口的作用序列号的作用 读取配置文件...

空空如也

空空如也

1 2 3 4 5 ... 9
收藏数 177
精华内容 70
关键字:

优化序列和原始序列