首页 > 优化技术 > 正文

寻求n阶乘的改进算法

这是我刚开始学习时编写的,现在已经弃用的"算法"。实际上,它根本算不上什么算法,仅仅是一个类的设计,而且实现并未完善。写到一半时,我发现自己的构思多么糟糕,就放弃了继续编写。该算法支持4294967295位的带符号和无符号整数。你可以将UBI_SIGNED取消定义以支持无符号整型,可能运行更快。我并没有计算过100000!是否超过这个范围,如果你需要计算,可以自己尝试一下,我没有那么多时间。

UBI代表无界整数

忘记提及了,你可以访问这个网站查看一个专门为理论上的"无限大"数设计的C++库:

apfloat意味着任意精度浮点数,这个人编写的算法非常出色,只能这样说。2.6亿位的π只需要几乎1秒多就能计算出来,算100W!也不在话下,使用了数论变换。如果你需要算法,可以去参考一下。另外:

实际上,"计算机编程艺术"第二卷"数值算法"中有许多关于这方面的介绍,我曾经匆匆浏览过几眼,但由于本人数学太差,看懂几乎是 impossible-_-~~。所以也只能作罢...

我编写的这个糟糕的代码计算乘法非常"慢",但计算加法还算可以。我曾经使用迭代法计算Fibonacci的第10W项似乎也只用了很短的时间(感觉不长,具体记不得了)。

计算了一个1000!,大约3秒左右:

402387260077093773543702433923003985719374864210714632543799910429938512398629020590204420848696940480047998861019719605863166687299480855890132382966994459099742450087073759918823627727188732519779505995276120874975462497043601418278094646496291056393887437886487337119181045825783647849977012476632889835955735432513185323957846307555740911426241747434934755342864657661166779739666882029120737914385371958824980812686783837455973174613608537953452422158659320192809087829730843139284403281231558611036976801357304216168747609675871348312025478589320767169132448426236131412508780208000261683151027341827977704784635868170164365024153998281265021301309276124489635992870511496497542199342216683256208213331871168115533615836546984046708975602900950537616475847728218967964624494516076535340819890138544248798495995331910172335555660213945039973628075013783761530712776192688034352625200158885351473316117021039681759215109077880193931781141945452572238655414610628921879602238389714760885062768629714667469756291123408243920816015378088989396451826324367161676217916890977991190375403127462228998800519544441428201218736174599264295658174662830295557029902432415318171621046583203678906117260158783520751516284225540265170483304226143974286933061690897968482590125458327168226458066527699586526822728070757813918588178896522081643483482599326604336766017699961283186078838615027946595513115655520360939881806121385586003014356945272242063446317975605946825731037900840243243846565724501440282188525247093506020929023136493273497565513958720559654228749774011413346962715422845862377387538230483865688976461927383814900140767310446640259899490222217659043399018860185665264850617997023561938970178600408118974999183112121229845901641921068884387121855646124960798722908519296819372388642614839657382291125024186649353144970137428519266498753372189406942814341185201580141233448280150513999429153830776445690907315243327828826986402789864321139083506217095002597389863554277196742822248757586765752344220207573630569498825087969281627538488633396900995982628095612145099487170124451646126037902930912088908694202851064018215439957168059418727489980942547421735824010636774059574178516082923013535808184009699637252423056085590370062427124341690900415369010593398383577793941097002775347202000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

```cpp

void Initialize(string str);

short StringCompare(const string& lhs, const string& rhs)const;

cmp_result UBICompare(const UBI& lhs, const UBI& rhs)const;

ifndef UBI_SIGNED

void ValidateValue(const string& str)const

{

if(str[0]=='-')

throw domain_error

("Attempt to initialize or assign a negative value"\n"to a number that is positive.");

}

endif

public:

UBI(size_type digit= 20);

UBI(const char c_str, size_type digit= 20);

UBI(const string& str, size_type digit= 20);

UBI(const UBI& UBI);

UBI operator+(const UBI& rhs)const;

UBI operator-(const UBI& rhs)const;

UBI operator(const UBI& rhs)const;

UBI operator/(const UBI& rhs)const;

const UBI& operator=(const UBI& rhs);

const UBI& operator+=(const UBI& rhs);

const UBI& operator-=(const UBI& rhs);

const UBI& operator*=(const UBI& rhs);

const UBI& operator/=(const UBI& rhs);

string ToString()const;

void Clear();

private:

mem_type mem;

ifdef UBI_SIGNED

bool isSigned;

bool IsSigned()const;

mutable bool mutex;

endif

};

UBI::UBI(size_type digit)

{

ifdef UBI_SIGNED

isSigned= false;

mutex= false;

endif

mem.reserve(digit);

}

void UBI::Initialize(string str)

{

if(str[0]=='-')

str.erase(0, 1);

int i;

for(i= str.size()- 1; i-1>= 0; i-= 2)

{

mem.push_back(MakeByte(LoByte(str[i]), LoByte(str[i-1])));

}

if(i== 0)mem.push_back(MakeByte(LoByte(str[0]), 0));

}

short UBI::StringCompare(const string& lhs, const string& rhs)const

{

if(lhs.size()> rhs.size())

return 1;

else if(lhs.size()< rhs.size())

return-1;

else if(lhs> rhs)

return 1;

else if(lhs< rhs)

return-1;

return 0;

}

UBI::cmp_result UBI::UBICompare(const UBI& lhs, const UBI& rhs)const

{

string sLhs(lhs.ToString());

string sRhs(rhs.ToString());

if(StringCompare(sLhs, sRhs)== 0)

return make_pair(&lhs,&lhs);

ifdef UBI_SIGNED

if(sLhs[0]=='-')sLhs.erase(0, 1);

if(sRhs[0]=='-')sRhs.erase(0, 1);

endif

const UBI small=

StringCompare(sLhs, sRhs)==-1?

this:&rhs;

const UBI big=

&rhs== small?

this:&rhs;

return make_pair(small, big);

}

ifdef UBI_SIGNED

bool inline UBI::IsSigned()const

{

return isSigned;

}

endif

UBI::UBI(const char* c_str, size_type digit)

{

ifdef UBI_SIGNED

isSigned=*c_str=='-'? true: false;

mutex= false;

else

ValidateValue(string(c_str));

endif

if(string(c_str).size()> digit)

mem.reserve(string(c_str).size());

else

mem.reserve(digit);

Initialize(string(c_str));

}

UBI::UBI(const string& str, size_type digit)

{

ifdef UBI_SIGNED

isSigned= str[0]=='-'? true: false;

mutex= false;

else

ValidateValue(str);

endif

if(str.size()> digit)

mem.reserve(str.size());

else

mem.reserve(digit);

Initialize(str);

}

UBI::UBI(const UBI& UBI): mem(UBI.mem)

{

ifdef UBI_SIGNED

isSigned= UBI.isSigned;

mutex= false;

endif

}

const UBI& UBI::operator=(const UBI& rhs)

{

if(this==&rhs)return*this;

mem.assign(rhs.mem.begin(), rhs.mem.end());

ifdef UBN_SIGNED

isSigned= rhs.isSigned;

endif

returnthis;

}

UBI UBI::operator+(const UBI& rhs)const

{

if(mem.empty()|| mem.size()== 1&& mem[0]== 0x0)

return rhs;

if(rhs.mem.empty()|| rhs.mem.size()== 1&& rhs.mem[0]== 0x0)

returnthis;

ifdef UBI_SIGNED

if(!mutex)

{

if(isSigned&&!rhs.isSigned||!isSigned&& rhs.isSigned)

{

mutex= true;

return*this- rhs;

}

}else

mutex= false;

endif

cmp_result result(UBICompare(*this, rhs));

byte prevHiRemain= 0;

size_type smallSize= SMALL(result)->mem.size();

UBI tempUBI;

for(size_type i= 0; i< BIG(result)->mem.size();++i)

{

byte tempHi=

HiByte(BIG(result)->mem[i])+

(i< smallSize? HiByte(SMALL(result)->mem[i]): 0)

+ prevHiRemain;

byte tempLo=

LoByte(BIG(result)->mem[i])+

(i< smallSize? LoByte(SMALL(result)->mem[i]): 0);

prevHiRemain= 0;

if(tempHi> 9)

{

tempLo+= tempHi/ 10;

tempHi= tempHi% 10;

}

if(tempLo> 9)

{

prevHiRemain= tempLo/ 10;

tempLo= tempLo% 10;

}

tempUBI.mem.push_back(MakeByte(tempHi, tempLo));

}

if(prevHiRemain!= 0)

tempUBI.mem.push_back(MakeByte(prevHiRemain, 0));

ifdef UBI_SIGNED

tempUBI.isSigned= this->isSigned? true: false;

endif

return tempUBI;

}

const UBI& UBI::operator+=(const UBI& rhs)

{

returnthis=this+ rhs;

}

UBI UBI::operator-(const UBI& rhs)const

{

ifdef UBI_SIGNED

if(!mutex)

{

if(!isSigned&& rhs.isSigned|| isSigned&&!rhs.isSigned)

{

mutex= true;

return*this+ rhs;

}

}else

mutex= false;

endif

cmp_result result(UBICompare(*this, rhs));

cmp_result 结果(UBICmp(*this, 右边));

if(小(result) == 大(result))

return UBI("0");

byte 前次高位借位= 0;

size_type 小尺寸= 小(result)->内存.size();

UBI 临时UBI;

for(size_type i= 0; i< 大(result)->内存.size();++i)

{

diff_byte 临时高位=

高位字节(大(result)->内存[i])-

(i< 小尺寸? 高位字节(小(result)->内存[i]): 0)

- 前次高位借位;

diff_byte 临时低位=

低位字节(大(result)->内存[i])-

(i< 小尺寸? 低位字节(小(result)->内存[i]): 0);

前次高位借位= 0;

if(临时高位< 0)

{

临时低位-= 1;

临时高位= 10+ 临时高位;

}

if(临时低位< 0)

{

前次高位借位= 1;

临时低位+= 10;

}

临时UBI.mem.push_back(制作字节(临时高位, 临时低位));

}

ifdef UBI_SIGNED

if(this== 大(result)&& this->isSigned||

this== 小(result)&&!this->isSigned)

临时UBI.isSigned= true;

endif

return 临时UBI;

}

UBI UBI::运算符(const UBI& 右边)const

{

if(this->mem[mem.size()-1]== 0|| 右边.mem[右边.mem.size()-1]== 0)

return UBI("0");

if(this->mem.size()== 1&& this->mem[0]== 0x10)

return 右边;

if(右边.mem.size()== 1&& 右边.mem[0]== 0x10)

return this;

cmp_result 结果(UBICmp(this, 右边));

UBI 临时UBI;

for(size_type i= 0, k= 0; i< 小(result)->mem.size();++i)

{

byte 小高位= 高位字节(小(result)->mem[i]);

byte 小低位= 低位字节(小(result)->mem[i]);

byte 前次低位余数= 0;

UBI 高;

for(size_type j= 0; j< 大(result)->mem.size();++j)

{

byte 临时高位= 小高位 高位字节(大(result)->mem[j])+ 前次低位余数;

byte 临时低位= 小高位 低位字节(大(result)->mem[j]);

前次低位余数= 0;

if(临时高位> 9)

{

临时低位+= 临时高位/ 10;

临时高位%= 10;

}

if(临时低位> 9)

{

前次低位余数= 临时低位/ 10;

临时低位%= 10;

}

高.mem.push_back(制作字节(临时高位, 临时低位));

}

if(前次低位余数!= 0)

{

高.mem.push_back(制作字节(前次低位余数, 0));

前次低位余数= 0;

}

if(k> 0)

{

string _10(高.ToString());

_10.resize(_10.size()+k,'0');

高= UBI(_10);

}

++k;

临时UBI+= 高;

UBI 低位;

for(size_type j= 0; j< 大(result)->mem.size();++j)

{

byte 临时高位= 小低位 高位字节(大(result)->mem[j])+ 前次低位余数;

byte 临时低位= 小低位 低位字节(大(result)->mem[j]);

前次低位余数= 0;

if(临时高位> 9)

{

临时低位+= 临时高位/ 10;

临时高位%= 10;

}

if(临时低位> 9)

{

前次低位余数= 临时低位/ 10;

临时低位%= 10;

}

低位.mem.push_back(制作字节(临时高位, 临时低位));

}

if(前次低位余数!= 0)

{

低位.mem.push_back(制作字节(前次低位余数, 0));

前次低位余数= 0;

}

if(k> 0)

{

string _10(低位.ToString());

_10.resize(_10.size()+k,'0');

低位= UBI(_10);

}

++k;

临时UBI+= 低位;

}

return 临时UBI;

}

string UBI::转换成字符串()const

{

if(mem.empty()|| mem.size()== 1&& mem[0]== 0)

return string("0");

string 临时;

临时.reserve(mem.size()2);

ifdef UBI_SIGNED

if(isSigned)

临时.push_back('-');

endif

int i= mem.size()-1;

while(mem[i]== 0&& i> 0)--i;

for(; i>= 0;--i)

{

临时.push_back(低位字节(mem[i])+'0');

临时.push_back(高位字节(mem[i])+'0');

}

unsigned 零= 临时.find_first_of("0");

ifdef UBI_SIGNED

if(零== 0|| 临时[0]=='-'&& 零== 1)

临时.erase(零, 1);

else

if(零== 0)

临时.erase(零, 1);

endif

return 临时;

}

void UBI::清空()

{

ifdef UBI_SIGNED

isSigned= false;

endif

mem.clear();

}

template

T 词汇转换(U u)

{

stringstream sstrm;

sstrm<< u;

T t;

sstrm>> t;

return t;

}

int main()

{

UBI a("1");

for(int i= 2; i<= 1000;++i)

{

a= a* 词汇转换(i);

}

cout<< a.转换成字符串();

}

24个运筹学优化算法包汇总

运筹学优化算法包汇总

运筹学优化算法包在解决复杂问题时起着关键作用,以下总结了24个主要的运筹学优化算法包,包括其特性、应用领域和适用场景,以供研究与实践之用。

1. pySOT

-专注于优化计算成本高昂的黑盒目标函数,具有连续变量或整数变量。适用于边界约束明确且边界范围有限的场景。对于计算成本较低的问题可能效果不佳。

2. GEKKO

-一个Python库,用于处理混合整数和微分代数方程,结合大规模求解器进行线性、二次、非线性和混合整数规划。适用于参数回归、数据协调、实时优化、动态仿真和非线性预测控制等领域。

3. OR-Tools

-一个开源软件,专注于组合优化问题,寻找最佳解决方案。适用于在大量可能解决方案中寻找最优解的问题,如路径规划、调度、资源分配等。

4. CPLEX

-一个线性和二次规划求解器,支持连续变量或整数变量(MIP)的求解。适用于大规模问题的线性和二次规划优化。

5. MiniZinc

-一个用于整数和实数的约束优化和决策问题语言。模型不规定求解方法,可以转换为适合不同求解器的形式,如约束规划、混合整数线性规划或布尔满足性求解器。

6. Pulp

-一个开源Python软件包,用于建立和求解线性和混合整数规划问题。支持多种求解器,如GLPK、COIN-OR CLP/CBC、CPLEX、GUROBI等。

-开源Python软件库,适用于构建和解决线性和混合整数规划问题。兼容多种求解器,例如GLPK、COIN-OR CLP/CBC、CPLEX、GUROBI等。

  1. Pyomo

    -兼容多种求解器,涵盖AMPL、PICO、CBC、CPLEX、IPOPT和GLPK等,用于线性、二次、非线性规划问题的建模与解决。

  2. pymoo

    -提供多目标优化的Python库,适用于处理复杂优化问题的求解。

  3. Gurobi

    -高效能的线性、二次、整数规划求解器,适用于大尺度问题的优化。

  4. GLPK

    -开源线性规划求解器,支持线性规划、整数规划、混合整数规划等问题。

  5. Python-MIP

    -提供在Python中构建和解决混合整数线性规划问题的工具。内置COIN-OR线性规划求解器CLP和COIN-OR MIP求解器CBC,并支持Gurobi MIP求解器。

  6. scipy.optimize

    -SciPy库中的优化模块,适用于解决各类优化问题。

  7. scikit-opt

    -面向机器学习的优化库,适用于模型选择和超参数调整。

  8. geatpy

    -全局优化库,适用于解决复杂优化问题。

  9. pyGAD

    -适用于遗传算法的Python库,用于求解复杂优化问题。

  10. gplearn

    -集成学习库,用于遗传编程和符号回归。

  11. DEAP

    -适用于遗传算法的Python库,用于遗传编程和遗传算法。

  12. ALGLIB

    -跨平台数值分析和数据处理库,支持多种编程语言和操作系统。

  13. FICO Xpress

    -线性和二次规划求解器,支持连续或整数变量(MIP)的求解。

  14. OpenMDAO

    -多学科设计、分析和优化框架,适用于解决复杂工程问题。

  15. CVXPY

    -Python嵌入式的凸优化问题建模语言,用于构建和解决凸优化问题。

  16. Advanced process monitor(APMonitor)

    -大尺度问题求解器,适用于线性规划、整数规划、非线性规划、非线性混合整数规划、动态仿真、移动水平估计和非线性模型预测控制。

  17. IMSL

    -数值分析功能软件库,适用于C、Java、C#.NET和Fortran编程语言。

  18. MIDACO

    -基于进化计算的数值优化软件包,用于解决受约束的混合整数非线性(MINLP)问题。

其他

-可查阅相关文档和资源,获取更多信息。

以上所转载内容均来自于网络,不为其真实性负责,只为传播网络信息为目的,非商业用途,如有异议请及时联系btr2020@163.com,本人将予以删除。

猜你喜欢
文章评论已关闭!
picture loss