【问题标题】:Splitting a vector into vectors of different length将向量拆分为不同长度的向量
【发布时间】:2014-07-16 15:12:05
【问题描述】:

我想将一个包含 90 个数组的向量拆分为 5 个不同长度的向量。每个向量的长度是根据这样的归一化长度确定的:

nl=[0.1642 .1516 .1259 .5583] 

因此每个向量的长度为

length=90*[0.1642 .1516 .1259 .5583]

但是这些长度不是整数,如果我尝试四舍五入,长度将不等于 90,由于四舍五入的错误,它可能是 89、90、91 甚至 92。 如果有人可以帮助我为此编写代码,我将不胜感激。

【问题讨论】:

  • 你可以按照你说的对长度进行四舍五入(最好使用fix/floor),最后如果它们的总和不为90,只需将剩余的元素添加到最后一个bin .. 我认为histc 也可以在这里提供帮助。
  • 你说你想要 5 个向量,但你的长度向量只有 4 个成员。

标签: matlab vector


【解决方案1】:

这是一个众所周知的问题,只是使用了不同的术语。想象一下选举,nl 是选票,你有 90 个席位要分配。

你会发现几十种算法,我会使用 D'Hondt 方法。

Matlab 中的实现可用here,用于一些理论背景检查wikipedia

【讨论】:

    【解决方案2】:

    我的幼稚实现:

    % some normalized lengths
    len = rand(1,4);
    len = len ./ sum(len);
    
    % convert to integers (round towards zeros)
    d = fix(len.*90);
    
    % fix the count by adding remaning elements to the last bin
    d(end) = d(end) + (90-sum(d));
    
    % sanity check
    assert(sum(d)==90)
    

    编辑:

    这是使用HISTC 的更好解决方案:

    edges = cumsum(len.*90);
    [counts,idx] = histc(1:90, [0 edges(1:end-1) Inf]);
    counts(end) = [];
    

    现在counts 包含每个 bin 中的元素数量,idx 包含 90 个元素中每个元素的 bin 索引。


    警告:上述两种方法在极端情况下可能会给出不太理想的分割。有关示例,请参阅@Daniel 的 cmets..

    【讨论】:

    • 请注意,这可能与预期的“公平”分布相去甚远。例如:len=[2;ones(88,1);.1];
    • 干得好,这是一个很好的反例:) 它分配了[1,0,...,0,89],这是完全错误的!我使用 HISTC 的第二种方法怎么样?我用那个例子得到[1,1,...,1,1]..
    • 显然对于这种极端情况,我建议使用您提到的比例“投票分配”方案!
    • len=[1.005,repmat([.99,1.01],[1,44]),0.995]./90; 我希望counts=ones(1,90) 但问题中没有定义最佳解决方案。
    • @Daniel:你又一次击败了我的代码 :) HISTC 方法给了我[1,0,2,0,2,...,0,2,1],这并不理想。嗯,现在我想我应该删除我的答案,因为它不能很好地处理这些极端情况......
    猜你喜欢
    • 1970-01-01
    • 2013-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-18
    • 2021-09-27
    • 2021-10-03
    相关资源
    最近更新 更多