如何使用python完成数学建模常见算法!

在数学建模中主流的编程语言是MATLAB,但随着python/R中数学软件包的不断完善,熟悉这两种编程语言的同学也可以快速数学建模的编程环节。后面我们将介绍几种常见数学建模算法的python实现,旨在展示python在本领域的强大威力。

1、问题描述

你希望通过几种常见算法的实现,了解python在数学建模中的能力。

2、解决方案

python除了丰富的原生数据结构外,拥有强大的第三方软件包支持,例如矩阵运算库Numpy,数据处理库Pandas、机器学习库Sklearn、深度学习库Tenserflow&Pytorch、科学计算库Scipy、图形绘制库matplotlib、网络算法库Networkx。此外几乎针对任何领域,都有第三方软件包的支持,这归功于python优秀的社区。使用者需要使用好pip这一软件包管理工具,发掘前人造好的轮子,尽量减少自己编程的难度。我们将在后面的问题讨论中介绍以下几种常用数学建模算法的python实现:

1.数据拟合算法
2.插值算法
3.线性规划算法

4.单源多宿最短路算法

3、问题讨论

我们的重点在于代码实现而非数学推导

1.数据拟合算法

我们这里介绍通过最小二乘法拟合线性函数

  1. #我们使用最小二乘法拟合一个三次函数,选取了5个参数

  2. importnumpyasnp

  3. importmatplotlib.pyplotasplt

  4. SAMPLE_NUM =100

  5. M =5

  6. x = np.arange(0, SAMPLE_NUM).reshape(SAMPLE_NUM,1) / (SAMPLE_NUM -1) *10

  7. y =2*x3+3*x2+x+1

  8. plt.plot(x, y,'bo')

  9. X = x

  10. foriinrange(2, M +1):

  11. X = np.column_stack((X, pow(x, i)))

  12. X = np.insert(X,0, [1],1)

  13. W=np.linalg.inv((X.T.dot(X))).dot(X.T).dot(y)

  14. y_estimate = X.dot(W)

  15. plt.plot(x, y_estimate,'r')

  16. plt.show()

国赛必备 | 了解如何使用python完成数学建模常见算法!

2.插值算法
我们使用几种常见的插值函数拟合上例中的三次函数
  1. importnumpyasnp

  2. fromscipyimportinterpolate

  3. importpylabaspl

  4. x=np.linspace(0,10,11)

  5. y=2*x3+3*x2+x+1

  6. xInset=np.linspace(0,10,101)

  7. pl.plot(x,y,"ro")

  8. forkindin["nearest","zero","slinear","quadratic","cubic"]:

  9. f=interpolate.interp1d(x,y,kind=kind)

  10. y_estimate=f(xInset)

  11. pl.plot(xInset,y_estimate,label=str(kind))

  12. pl.legend(loc="lower right")

  13. pl.show()

国赛必备 | 了解如何使用python完成数学建模常见算法!

3.线性规划算法
我们可以使用scipy库对目标函数进行线性规划
  1. importnumpyasnp

  2. fromscipy.optimizeimportminimize

  3. deffunc(x):

  4. return(2*x[0]*x[1]+2*x[0]-x[0]2+2*x[1]2+np.sin(x[0]))

  5. cons=({"type":"eq","fun":lambdax:np.array([x[0]3-x[1]]),"jac":lambdax:np.array([3*(x[0]2),-1.0])},{"type":"ineq","fun":lambdax:np.array([x[1]-1]),"jac":lambdax:np.array([0,1])})#定义函数的多个约束条件

  6. res=minimize(func,[-1.0,1.0],constraints=cons,method="SLSQP",options={"disp":True})

  7. print(res)

注意这里求解的为目标函数最小值,如果我们需要求解最大值则将func取负数即可。输出内容如图

国赛必备 | 了解如何使用python完成数学建模常见算法!

4.单源多宿最短路算法
我们介绍一下基于堆优化的dijkstra算法,这里的堆可以使用python内置的PriorityQueue实现。我们这里给出一个简单的堆实现:
  1. classDisNode:

  2. def__init__(self,node,dis):

  3. self.node=node

  4. self.dis=dis

  5. def__lt__(self, other):

  6. returnself.dis

  7. classDisPath:

  8. def__init__(self,end):

  9. self.end=end

  10. self.path=[self.end]

  11. self.dis=0

  12. def__str__(self):

  13. nodes=self.path.copy()

  14. return"->".join(list(map(str,nodes)))+" "+str(self.dis)

  15. classHeap:

  16. def__init__(self):

  17. self.size=0

  18. self.maxsize=10000

  19. self.elements=[0]*(self.maxsize+1)

  20. defisEmpty(self):

  21. returnself.size==0

  22. definsert(self,value):

  23. ifself.isEmpty():

  24. self.elements[1]=value

  25. else:

  26. index=self.size+1

  27. while(index!=1andvalue2]):

  28. self.elements[index]=self.elements[index//2]

  29. index=index//2

  30. self.elements[index]=value

  31. self.size+=1

  32. defpop(self):

  33. deleteElement=self.elements[1]

  34. self.elements[1]=self.elements[self.size]

  35. self.size-=1

  36. temp=self.elements[1]

  37. parent,child=1,2

  38. while(child<=self.size):

  39. ifchildandself.elements[child]>self.elements[child+1]:

  40. child+=1

  41. iftemp

  42. break

  43. else:

  44. self.elements[parent]=self.elements[child]

  45. parent=child

  46. child*=2

  47. self.elements[parent]=temp

  48. returndeleteElement

  49. defDijkstraWithHeap(nodes,start,GetNeighbors):

  50. dis=defaultdict(int)

  51. paths=defaultdict(DisPath)

  52. heap=Heap()

  53. visit=set()

  54. fornodeinnodes:

  55. dis[node]=sys.maxsize

  56. paths[node]=DisPath(node)

  57. dis[start]=0

  58. heap.insert(DisNode(start,0))

  59. while(notheap.isEmpty()):

  60. now=heap.pop().node

  61. ifnowinvisit:

  62. continue

  63. visit.add(now)

  64. paths[now].dis=dis[now]

  65. foredgeinGetNeighbors(now):

  66. end=edge.End

  67. ifdis[now]+edge.value

  68. dis[end]=dis[now]+edge.value

  69. paths[end].path=paths[now].path+[end]

  70. heap.insert(DisNode(end,dis[end]))

  71. returnpaths

通过堆优化的dijkstra算法的时间复杂度最低可以达到O(nlogm),上文给出的代码的时间复杂度为O(mlogm),但是胜在编码简单。此外还可以使用Networkx库进行求解,这里不再介绍。

【竞赛报名/项目咨询请加微信:mollywei007】

上一篇

美国中学生7大写作竞赛及写作活动盘点

下一篇

2022 iGEM国际基因工程机器竞赛组队报名中

你也可能喜欢

  • 暂无相关文章!

评论已经被关闭。

插入图片
Molly老师
留学行业8年服务经验,擅长初高中留学背景提升及英美留学规划。VX:mollywei007
返回顶部
Baidu
map