比较有挑战的算法, 大神看过来

HelloBugs88 2017-07-12 05:41:51
7元1次方程算法求解
需求解未知数a,b,c,d,e,f,g

a+b+2*c+3*e+2*f = 随意给定数值 X

b+ 2*d +f + 3*g = 随意给定数值 Y

随意给定数值 X ,Y 请 求出 a,b ,c,d,e,f,g 的值 a,b,c,d,e,f,g 都大于或等于0

这种组合肯定会有很多种
第一步求解 : 计算出 a,b,c,d,e,f,g 的 可能值

第二步优化: 要求 a,b,c,d ,e,f ,g 的大小尽量比较接近
比如有以下两组结果都满足
1,2,2,1,3,0,2
1,0,0,0,0,0,8
那么选1,2,3,1,3,0,2 这个结果
...全文
603 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
yyfhz 2017-09-07
  • 打赏
  • 举报
回复
这个视abcdef为未知量,视X,Y为已知量,就是一个包含6个未知数的线性方程组,这类方程组是有通解的(可用高斯法求出通解表达式),正常状态下,应该是一个带有4个待定系数的向量。 然后的问题是怎么调整这些系数使得这个向量里的各个元素尽可能接近。视该向量为样本组,可考虑以方差最小化作为衡量作为是否足够接近的标准。这样的话,方差化简之后应该是一个4元2次方程。 想求出求这个方程的最小值是困难的,但是通过固定其中3个参数可以求出在此状态下第4个参数的“最合适值”,然后再去求第3个参数的“最合适值”...依次类推可以方便的求出一个系数解,然后反复迭代使得解尽可能优化,这样应该可以找到一组“次优解”
HelloBugs88 2017-08-04
  • 打赏
  • 举报
回复
leeky 非常感谢你的回复,写了这么多东西,实在辛苦了,我好好理解消化一下
leeky 2017-07-21
  • 打赏
  • 举报
回复
求MaxV[idx]值略有问题,如果你看得出就改一下,分把钟的事情 看不出就算了,因为主要的解都出来了
leeky 2017-07-21
  • 打赏
  • 举报
回复
试过X=160,Y=120,解太多了! 下面给两个实例: 一、X=6,Y=5的解: 开始…… 1、0,0,0,1,0,3,0, 2、0,0,2,2,0,1,0, 3、0,1,1,2,1,0,0, 4、0,2,1,1,0,1,0, 5、0,3,0,1,1,0,0, 6、0,4,0,0,0,1,0, 7、1,0,0,2,1,1,0, 8、1,1,0,1,0,2,0, 9、1,1,2,2,0,0,0, 10、1,3,1,1,0,0,0, 11、1,5,0,0,0,0,0, 12、2,0,1,2,0,1,0, 13、2,1,0,2,1,0,0, 14、2,2,0,1,0,1,0, 15、3,1,1,2,0,0,0, 16、3,3,0,1,0,0,0, 17、4,0,0,2,0,1,0, 18、5,1,0,2,0,0,0, 完成! 二、X=12,Y=20的解为: 开始…… 1、0,0,0,7,0,6,0, 2、0,0,0,10,4,0,0, 3、0,0,1,9,2,2,0, 4、0,0,2,8,0,4,0, 5、0,0,3,10,2,0,0, 6、0,0,4,9,0,2,0, 7、0,0,6,10,0,0,0, 8、0,1,0,9,3,1,0, 9、0,1,1,8,1,3,0, 10、0,1,3,9,1,1,0, 11、0,2,0,8,2,2,0, 12、0,2,1,7,0,4,0, 13、0,2,2,9,2,0,0, 14、0,2,3,8,0,2,0, 15、0,2,5,9,0,0,0, 16、0,3,0,7,1,3,0, 17、0,3,2,8,1,1,0, 18、0,4,0,6,0,4,0, 19、0,4,1,8,2,0,0, 20、0,4,2,7,0,2,0, 21、0,4,4,8,0,0,0, 22、0,5,1,7,1,1,0, 23、0,6,0,7,2,0,0, 24、0,6,1,6,0,2,0, 25、0,6,3,7,0,0,0, 26、0,7,0,6,1,1,0, 27、0,8,0,5,0,2,0, 28、0,8,2,6,0,0,0, 29、0,10,1,5,0,0,0, 30、0,12,0,4,0,0,0, 31、1,0,0,8,1,4,0, 32、1,0,1,10,3,0,0, 33、1,0,2,9,1,2,0, 34、1,0,4,10,1,0,0, 35、1,1,0,7,0,5,0, 36、1,1,1,9,2,1,0, 37、1,1,2,8,0,3,0, 38、1,1,4,9,0,1,0, 39、1,2,0,9,3,0,0, 40、1,2,1,8,1,2,0, 41、1,2,3,9,1,0,0, 42、1,3,0,8,2,1,0, 43、1,3,1,7,0,3,0, 44、1,3,3,8,0,1,0, 45、1,4,0,7,1,2,0, 46、1,4,2,8,1,0,0, 47、1,5,0,6,0,3,0, 48、1,5,2,7,0,1,0, 49、1,6,1,7,1,0,0, 50、1,7,1,6,0,1,0, 51、1,8,0,6,1,0,0, 52、1,9,0,5,0,1,0, 53、2,0,0,9,2,2,0, 54、2,0,1,8,0,4,0, 55、2,0,2,10,2,0,0, 56、2,0,3,9,0,2,0, 57、2,0,5,10,0,0,0, 58、2,1,0,8,1,3,0, 59、2,1,2,9,1,1,0, 60、2,2,0,7,0,4,0, 61、2,2,1,9,2,0,0, 62、2,2,2,8,0,2,0, 63、2,2,4,9,0,0,0, 64、2,3,1,8,1,1,0, 65、2,4,0,8,2,0,0, 66、2,4,1,7,0,2,0, 67、2,4,3,8,0,0,0, 68、2,5,0,7,1,1,0, 69、2,6,0,6,0,2,0, 70、2,6,2,7,0,0,0, 71、2,8,1,6,0,0,0, 72、2,10,0,5,0,0,0, 73、3,0,0,10,3,0,0, 74、3,0,1,9,1,2,0, 75、3,0,3,10,1,0,0, 76、3,1,0,9,2,1,0, 77、3,1,1,8,0,3,0, 78、3,1,3,9,0,1,0, 79、3,2,0,8,1,2,0, 80、3,2,2,9,1,0,0, 81、3,3,0,7,0,3,0, 82、3,3,2,8,0,1,0, 83、3,4,1,8,1,0,0, 84、3,5,1,7,0,1,0, 85、3,6,0,7,1,0,0, 86、3,7,0,6,0,1,0, 87、4,0,0,8,0,4,0, 88、4,0,1,10,2,0,0, 89、4,0,2,9,0,2,0, 90、4,0,4,10,0,0,0, 91、4,1,1,9,1,1,0, 92、4,2,0,9,2,0,0, 93、4,2,1,8,0,2,0, 94、4,2,3,9,0,0,0, 95、4,3,0,8,1,1,0, 96、4,4,0,7,0,2,0, 97、4,4,2,8,0,0,0, 98、4,6,1,7,0,0,0, 99、4,8,0,6,0,0,0, 100、5,0,0,9,1,2,0, 101、5,0,2,10,1,0,0, 102、5,1,0,8,0,3,0, 103、5,1,2,9,0,1,0, 104、5,2,1,9,1,0,0, 105、5,3,1,8,0,1,0, 106、5,4,0,8,1,0,0, 107、5,5,0,7,0,1,0, 108、6,0,0,10,2,0,0, 109、6,0,1,9,0,2,0, 110、6,0,3,10,0,0,0, 111、6,1,0,9,1,1,0, 112、6,2,0,8,0,2,0, 113、6,2,2,9,0,0,0, 114、6,4,1,8,0,0,0, 115、6,6,0,7,0,0,0, 116、7,0,1,10,1,0,0, 117、7,1,1,9,0,1,0, 118、7,2,0,9,1,0,0, 119、7,3,0,8,0,1,0, 120、8,0,0,9,0,2,0, 121、8,0,2,10,0,0,0, 122、8,2,1,9,0,0,0, 123、8,4,0,8,0,0,0, 124、9,0,0,10,1,0,0, 125、9,1,0,9,0,1,0, 126、10,0,1,10,0,0,0, 127、10,2,0,9,0,0,0, 128、12,0,0,10,0,0,0, 完成!
leeky 2017-07-21
  • 打赏
  • 举报
回复
我把求解过程给你弄出来,你自己搞优化解。 优化解的定义尚不清,尽管如此,既然能求解,得优化解很容易的了,在求解过程中就可以比较哪个优,然后把解留下来。 使用递归调用,测试了有数万组解及百万组解以上的实例,占用内存很小,但是较耗时, 我这个算法已经在两处做了优化:1是解中各值最大值限制;2是计算过程中比较局部和;可优化的空间应当不大了。
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    lblX: TLabel;
    Label1: TLabel;
    edtX: TEdit;
    edtY: TEdit;
    lblCnt: TLabel;
    chkDetail: TCheckBox;
    btnCalcu: TButton;
    mmo1: TMemo;
    procedure btnCalcuClick(Sender: TObject);
  private
    procedure CalcuIDX( tyerID : Integer);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  K1 : array[1..7] of Integer = (1,1,2,0,3,2,0);  //式1系数
  K2 : array[1..7] of Integer = (0,1,0,2,0,1,3);  //式2系数
  MaxV : array[1..7] of Integer;   // 结果 最大取值
  Value : array[1..7] of Integer;  // 结果(a,b,c,d,e,f,g)
  xV : Integer;
  yV : Integer;
  RsltCnt : Integer;  //解 组数

implementation

{$R *.dfm}

function GetDivValue (sum , Cnt : Integer) : Integer;
begin
  if Cnt = 0 then
  Cnt := 1;

  Result := sum div Cnt;
end;

procedure TForm1.CalcuIDX( tyerID : Integer);
var
  idx : Integer;
  tmpSum1 ,tmpSum2 : Integer;
  sRslt : string;
begin
  Application.ProcessMessages();
  tmpSum1 := 0;
  tmpSum2 := 0;
  for idx := 1 to  tyerID - 1 do
    begin
      tmpSum1 := tmpSum1 + K1[idx] * Value[idx];
      tmpSum2 := tmpSum2 + K2[idx] * Value[idx];
    end;
  if (tmpSum1 > xV)  or (tmpSum2 > yV) then
  Exit;

  if (tyerID = 7 )  then
  begin
    tmpSum1 := tmpSum1 + K1[7] * Value[7];
    tmpSum2 := tmpSum2 + K2[7] * Value[7];

    if (tmpSum1 = xV)  and (tmpSum2 = yV) then
    begin
      Inc( RsltCnt);
      if not chkDetail.Checked then
        lblCnt.Caption := IntToStr(RsltCnt)
      else
      begin
        sRslt := IntToStr(RsltCnt) + '、';
        for idx := 1 to 7 do
          sRslt := sRslt + IntToStr(Value[idx]) + ',';
        mmo1.Lines.Add(sRslt);  
      end;
    end;
    
  end
  else
  for idx := 0 to MaxV[tyerID] do
    begin
      Value[tyerID] := idx;
      CalcuIDX(tyerID+1);
    end;
end;

procedure TForm1.btnCalcuClick(Sender: TObject);
var
  idx : Integer;
  tmpV1 : Integer;
  tmpV2 : Integer;
begin
  xV := StrToInt(edtX.Text);
  yV := StrToInt(edtY.Text);

  for idx  := 1 to 7 do
    begin
      tmpV1 := GetDivValue(xV,K1[idx]) ;
      tmpV2 := GetDivValue(yV,K2[idx]) ;
      //从两者中取一个最小的值作为结果上限
      if (tmpV1 > tmpV2) then
        MaxV[idx] := tmpV2
        else
        MaxV[idx] := tmpV1;
    end;

    mmo1.Lines.Clear;
    lblCnt.Caption := '0';
    mmo1.Lines.Add('开始……');
    RsltCnt := 0;
    CalcuIDX(1);
    mmo1.Lines.Add('完成!');
end;

end.
leeky 2017-07-13
  • 打赏
  • 举报
回复
肯定有个前提:非负整数吧?
HelloBugs88 2017-07-13
  • 打赏
  • 举报
回复
a,b,c,d,e,f,g 都大于或等于0

33,008

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧