寻求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等。
-
Pyomo
-兼容多种求解器,涵盖AMPL、PICO、CBC、CPLEX、IPOPT和GLPK等,用于线性、二次、非线性规划问题的建模与解决。
-
pymoo
-提供多目标优化的Python库,适用于处理复杂优化问题的求解。
-
Gurobi
-高效能的线性、二次、整数规划求解器,适用于大尺度问题的优化。
-
GLPK
-开源线性规划求解器,支持线性规划、整数规划、混合整数规划等问题。
-
Python-MIP
-提供在Python中构建和解决混合整数线性规划问题的工具。内置COIN-OR线性规划求解器CLP和COIN-OR MIP求解器CBC,并支持Gurobi MIP求解器。
-
scipy.optimize
-SciPy库中的优化模块,适用于解决各类优化问题。
-
scikit-opt
-面向机器学习的优化库,适用于模型选择和超参数调整。
-
geatpy
-全局优化库,适用于解决复杂优化问题。
-
pyGAD
-适用于遗传算法的Python库,用于求解复杂优化问题。
-
gplearn
-集成学习库,用于遗传编程和符号回归。
-
DEAP
-适用于遗传算法的Python库,用于遗传编程和遗传算法。
-
ALGLIB
-跨平台数值分析和数据处理库,支持多种编程语言和操作系统。
-
FICO Xpress
-线性和二次规划求解器,支持连续或整数变量(MIP)的求解。
-
OpenMDAO
-多学科设计、分析和优化框架,适用于解决复杂工程问题。
-
CVXPY
-Python嵌入式的凸优化问题建模语言,用于构建和解决凸优化问题。
-
Advanced process monitor(APMonitor)
-大尺度问题求解器,适用于线性规划、整数规划、非线性规划、非线性混合整数规划、动态仿真、移动水平估计和非线性模型预测控制。
-
IMSL
-数值分析功能软件库,适用于C、Java、C#.NET和Fortran编程语言。
-
MIDACO
-基于进化计算的数值优化软件包,用于解决受约束的混合整数非线性(MINLP)问题。
其他
-可查阅相关文档和资源,获取更多信息。
以上所转载内容均来自于网络,不为其真实性负责,只为传播网络信息为目的,非商业用途,如有异议请及时联系btr2020@163.com,本人将予以删除。