美文网首页
[算法] 中位数和第i个顺序统计量

[算法] 中位数和第i个顺序统计量

作者: 舒也ella | 来源:发表于2018-10-31 11:21 被阅读0次

基础算法

  1. 最大值或最小值

单求最大或最小时间O(n),但同时找到最大值和最小值并不需要O(2n),成对比较(一次比较当前两数大小,将记录最小值和当前小值比,记录最大值和当前大值比)可将4次比较减为3次,时间O(\frac{3}{2}n)

  1. 求第i个顺序统计量

使用快排的partition,但根据返回的q值的位置q-p+1与i比较,递归调用划分的一边继续求解(快排需要处理划分的两边)
用random partition思想期望时间O(n),最坏情况O(n^2)
优化:
先分组再partition可实现最坏O(n)(算法导论9.3)

应用

中位数问题延伸:

中位数实际上是一组数中各变量与其距离绝对值之和最小的点。
例如输油管道问题、带权中位数问题

partition思想延伸:

用partition思想可以将许多算法时间上限由排序时间O(n \lg n)所限制但实际上并不需要对所有元素的两两相对位置进行排序的算法进行改进,将时间降为O(n)
例如分数背包优化、求两个有序数组的中位数

分数背包优化 O(n)时间

应用partition函数根据随机选择的某位置的物品的单位重量的价值将物品列表划分为三部分::W_L中的物品单位重量的价值大于划分点,W_M中物品单位重量的价值等于划分点,W_R中物品单位重量的价值小于等于划分点(不需要生成新的三个子集合,使用数组下标控制下述处理即可)。

  1. W_L>W,则不放入任何物品,递归求解物品集合W_L和背包重量W时的解决方案;

  2. W_L<=W,则把W_L中的物品全部放入背包,并尽可能放入W_M中的物品;

​ a. 若W_G+W_M>=W,则在尽可能多得放入W_G, W_M集合的物品后算法结束;

​ b. 若W_G+W_M<W,则在W_G, W_M集合的物品全部放入后,递归求解物品集合W_R和背包重量W - W_L - W_M时的解决方案。

与快速排序的排序主方法不同的是,此次我们并不需要对划分点左右两侧都递归调用求解,而只需要根据剩余容量进行判断单侧递归调用求解即可,时间复杂度T(n) <= T(n/2) + O(n), T(n) = O(n)。实现代码如下:

typedef struct item{
    int v;
    int w;
} item;

double calcVPW(item a){
    return a.v / (double)a.w;
}

void swapItem(item& a, item& b){
    item tmp = a;
    a = b;
    b = tmp;
    return;
}

int partition(vector<item>& A, int p, int r) {
    double x = calcVPW(A[r]);
    int i = p-1;
    for (int j = p; j < r; j++) {
        if (calcVPW(A[j]) > x) {
            i++;
            swapItem(A[i], A[j]);
        }
    }
    swapItem(A[i+1], A[r]);
    return i+1;
}

// 设背包总容量为W
double fracKnapsack (vector<item>& A, int W, int p, int r){
    int q = partition(A, p, r);
    double resValue = 0.0;
    int currentW = 0.0;
    int sumWL = 0.0;
    double sumVL = 0.0;
    for (int i = p; i < q; i++){
        sumWL += A[i].w;
        sumVL += A[i].v;
    }
    if(sumWL > W){
        return fracKnapsack(A, W, p, q-1);
    } else {
        resValue += sumVL;
        currentW += sumWL;
        if (currentW + A[q].w <= W) {
            currentW += A[q].w;
            resValue += A[q].v;
            return fracKnapsack(A, W - currentW, q+1, r);
        } else {
            int leftW = W - currentW;
            resValue += A[q].v / (double)A[q].w * leftW;
            return resValue;
        }
    }
}

相关文章

  • [算法] 中位数和第i个顺序统计量

    基础算法 最大值或最小值 单求最大或最小时间,但同时找到最大值和最小值并不需要,成对比较(一次比较当前两数大小,将...

  • 中位数和顺序统计量

    算法导论中文第三版Chapter 9 一些概念 顺序统计量:在n元素集合中,第i个顺序统计量是该集合中第i小的元素...

  • 算法导论阅读笔记6-中位数和顺序统计量

    在一个由n个元素组成的集合中,第i个顺序统计量是该集合中第i小的元素。例如,在一个元素集合中,最小值是第1个顺序统...

  • 算法学习01_顺序统计量

    本篇源至于《算法导论》第9章学习笔记,记录关于顺序统计量的学习实践。 概念 顺序统计量 在一个由n个元素组成的集合...

  • [小撒学算法]顺序统计量

    小撒是一只好学的小鸭子,这天,小撒在学习算法 顺序统计量(order statistic) 在一个数组中,第i个数...

  • 章节六:中位数和顺序统计学

    在一个由n个元素组成的集合中,第i个顺序统计量(order statistic)是该集合中第i小的元素。本节我们将...

  • 算法-寻找顺序统计量

    结论 假设所有元素都是互异的,使用RANDOMIZED-SELECT算法可在期望为线性时间内找到任一顺序统计量,特...

  • 排序算法

    常见的排序算法 性能比较 直接插入排序 思路:取数组中第i(i >= 1)个元素和第i-1个元素对比,若第i个元素...

  • 算法导论-排序和顺序统计量

    排序算法 输入:一个n个数的序列。 输出:输入序列的一个排列(重排)

  • 2019-02-20

    <1>顺序表的插入操作 代码:Insert_Sq(l,i,x) 完整算法 <2>顺序表的删除操作: Delete_...

网友评论

      本文标题:[算法] 中位数和第i个顺序统计量

      本文链接:https://www.haomeiwen.com/subject/uiootqtx.html