matlab: 如何从一些数据里知道是由哪些数据相加得出一个已知数

这里是引用
在这里插入图片描述

下面代码中,我不用相等作为约束条件是因为相等这个条件太严格,那个2552328.96本来也是四舍五入了的结果,计算的还有累加和后小数点应该也很多。

clc,clear all
%{
程序的设计思路是:
第一层循环:从35个数里面挑选n个数,n是从135的整数。
(这里面有一个技巧,把这35个数从小到大排列,然后从最小的数开始一个一个往上加,
可以发现加出目标数最少需要几个数;同样,从大到小一个一个加,可以发现加出目标数最多需要几个数,这样可以减少循环次数)

然后用b=combntns(a,i)函数找出在数组a中取出i个数的全部组合,求出的b是一个矩阵,每一行记录了一种i个数的组合。

第二层循环:用nchoosek(n,i)算出n个数中取i个数的组合有几种,在刚才算出的b矩阵中每一行分别与其和的误差计算,选取最小误差保存。
如果当前的i个数的组合均不能满足要求,则将i加一,继续考察i+1个数的组合情况

%}

load('data.mat')
% D = [2552328.96,12031346.27];
% L_D = length(D);
data=[3,2,1,5,4]';
D = [6,10];
L_D = length(D);
a=sort(data); %输入35个数,并自动从小到大排列
L_a = length(data);

result={};
for i=1:L_D
    result_i = {};
    dest=D(i) ;    %定义目标数x 
    %记录从小到大的和与从大到小的和
    suma=[0 0];
    %初始化加出目标数最多和最少需要几个数
    nmax=0;
    nmin=0;
    for j=1:L_a
        suma=[suma(1)+a(j) suma(2)+a(L_a+1-j)];
        if nmax==0 && suma(1)>=dest
            nmax=j;
        end
        if nmin==0 && suma(2)>=dest 
            nmin=j;
        end
        % 确定好后退出循环
        if nmax>0 && nmin>0
            break
        end
    end
    
    num=0;
    %把所有数字从大到小排列,发现至少要nmin个数,至多用nmax个数相加可以得到你要的数
%     for k=nmin:nmax 
    for k=5:L_a
        %矩阵b存储数组a中i个数的所有组合,一种组合存一行
        b=combntns(a,k);   
        %length(b)=nchoosek(n,k)代表在n个数中取k个的组合数n!/((n–k)! k!)
        min_E=Inf;
        min_E_n=-1;
        L_b=size(b)
        for n=1:L_b(1)  
            c=sum(b(n,:));
            %当找到符合条件的组合时,在主界面显示
            if abs(c-dest)<min_E
                min_E = abs(c-dest);
                min_E_n=n;
            end
        end
%         if min_E>5
%             continue
%         end
        num = num+1;
         % 序号存储
        temp=[];
        for m=1:length(b(min_E_n,:))
            temp(m)=find(data==b(min_E_n,m));
        end
        result_i{num}={k,min_E,sort(temp)};  
        % 画图
        plot(k,min_E,'*')
        pause(0.1)
        hold on 
    end
    result{i}=result_i;
    hold off
end

在这里插入图片描述

结果说明:假设从35个数中不重合的取出3个数,有6123种排列(二项式)。把每一种排列的累加和分别于目标和做差,找到最小的差值误差为0.98,假设它是由序号[1,4,6]这3个数累加的结果,其中序号1,4,6表示35个数据中第1,4,6个元素。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:游动-白 设计师:我叫白小胖 返回首页
评论

打赏作者

代码小白的成长

计算机网络PPT下载

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值