• 数学建模练习之1选拔问题


    题目:

    一年一度的全国大学生数学建模竞赛是高等院校的重要赛事。由于竞赛场地、经费等原因,不是所有想参加竞赛的人都能被录用。为了能够选拔出真正优秀的同学代表学校参加竞赛,数学建模指导教师需要投入大量的精力,但是每年在参赛的时候还是有很多不如意之处:有的学生言过其实,有的队员之间合作不默契,影响了数学建模的成绩。
    数学建模需要学生具有较好的数学基础知识、良好的编程能力、较强的写作能力、良好的团队合作精神,同时还要求具有一定的创新能力。
    在这里插入图片描述**问:**根据上表中信息,建立建模队员选拔的数学模型,要求从9名同学中选择6名组成2队参加竞赛,使得这两个参赛队有较好的竞技水平,要求模型具有可推广性。

    明确问题:问题叫我们从9个人里面选6个人【并且这6个人要分为2组,每一组要有较好的竞技水平】
    再次审题: 1.题目要求各方面都需要较良好,所以首先要考虑综合水平最强的。2.搭配3人一组,这三人要有所特质,取长补短。
    分析:本题建立层次分析模型,逐一算出各方案层、准则层,然后做出决断选出最优秀的6个人;之后在这6个人里面,根据每个人的优势进行组队。为了便于计算,我就只选取了数学成绩、写作能力、编程能力这三个特征来作为优势度的选取。最后算出每个人的每个特征的相对本人自己的其它特征的相对优势,然后根据相对优势进行三三搭配,每个人的优势都得到发挥,要是出现几个人的相对优势最高的都出现在同一项特征里面,则选取次高的特征作为分组参考;
    模型优缺点分析:使用层次分析模型会涉及人为的打相对优势权重【其实、我看来,经验的判断也属于人为的,因为经验是前人或者你自己积累出来的】;这里采取经验的赋予权重,也就是如果这个人的某项比另一项特征高分,则对于这个人来说,高分项比较重要。

    代码实现:

    【基于anaconda python3.7 注释包含在代码中】

    # -*- coding: utf-8 -*-
    # @Time    : 2019/5/22 14:41
    # @Author  : data mining
    # @File    : AHP.py
    import numpy as np
    import numpy.matlib
    import heapq
    
    
    class AHP:
        #所研究数据
        arry = np.array([[98,90,87,76,90,83,79,88,94],
                         ['','','','','','','','',''],
                         [78,90,69,96,84,96,82,79,95],
                         ['','','','','','','','',''],
                         ['','','','','','','','','']])
        resxx = []
        # res1 = []
        def __init__(self):
            self.resxx = self.resxx
            self.arry1 = np.copy(self.arry)  #备用
            self.arry2 = np.copy(self.arry)
    
        def get_matrixA(self,data1,data2):  #获得准则层 判别矩阵A
            matrix = np.matlib.ones((len(data1),len(data2)))  #生成以1填充的矩阵
            matrix = np.asarray(matrix)
            #交叉比较
            for i in range(0,len(data1)):
                    for j in range(0, len(data2)):
                        if data1[i] - data2[j] == 4:
                            matrix[i][j] = 4.0
                        elif data1[i] - data2[j] == 3:
                            matrix[i][j] = 5.0
                        elif data1[i] - data2[j] == 2:
                            matrix[i][j] = 3.0
                        elif data1[i] - data2[j] == 1:
                            matrix[i][j] = 2.0
                        elif data1[i] - data2[j] == 0:
                            matrix[i][j] = 1.0
                        elif data1[i] - data2[j] == -4:
                            matrix[i][j] = 1 / 4
                        elif data1[i] - data2[j] == -3:
                            matrix[i][j] = 1 / 5
                        elif data1[i] - data2[j] == -2:
                            matrix[i][j] = float(str(1 / 3)[:4])
                        elif data1[i] - data2[j] == -1:
                            matrix[i][j] = 1 / 2
            matrixA = np.asmatrix(matrix)
            print("matrixA:")
            print(matrixA)
            return matrixA  #判别矩阵A
    
        def get_matrixB(self,data1,data2): #获得方案层 判别矩阵B
            matrix = np.matlib.ones((9,9))
            matrix = np.asarray(matrix)
            if type(data1[0]) is float:
                for i in range(0, len(data1)):
                    for j in range(0, len(data2)):
                        if i == j:
                            matrix[i][j] = 1.0
                        else:
                            if data1[i] == data2[j]:
                                matrix[i][j] = 1.0
                            elif data1[i] > data2[j]: ##行大于列
                                if (data1[i]-data2[j]) <=2:
                                    matrix[i][j] = 1.0
                                elif 3<=(data1[i]-data2[j]) <5:
                                    matrix[i][j] = 2.0
                                elif 5<=(data1[i]-data2[j]) <6:
                                    matrix[i][j] = 3.0
                                elif 6<=(data1[i]-data2[j]) <8:
                                    matrix[i][j] = 4.0
                                else:
                                    matrix[i][j] = 5.0
    
                            elif data1[i] < data2[j]:  #行小于列
                                if (data1[i] - data2[j])>= -3:
                                    matrix[i][j] = 1.0
                                elif -5 <(data1[i]-data2[j]) <-3:
                                    matrix[i][j] = float(str(1/3)[:4])
                                else:
                                    matrix[i][j] = 1/5
            else:
                for i in range(0, len(data1)):
                    for j in range(0, len(data2)):
                        if i == j:
                            matrix[i][j] = str(1.0)
                        else:
                            if data1[i] == data2[j]:
                                matrix[i][j] = str(1.0)
                            elif data1[i]=='' and data2[j]=='':
                                matrix[i][j] = str(3.0)
                            elif data1[i]=='' and data2[j]=='':
                                matrix[i][j] = str(5.0)
                            elif data1[i]=='' and data2[j]=='':
                                matrix[i][j] = str(9.0)
                            elif data1[i]=='' and data2[j]=='':
                                matrix[i][j] = str(str(1/3)[:4])
                            elif data1[i]=='' and data2[j]=='':
                                matrix[i][j] = str(4.0)
                            elif data1[i]=='' and data2[j]=='':
                                matrix[i][j] = str(7.0)
                            elif data1[i]=='' and data2[j]=='':
                                matrix[i][j] = str(1/5)
                            elif data1[i]=='' and data2[j]=='':
                                matrix[i][j] = str(1/4)
                            elif data1[i]=='' and data2[j]=='':
                                matrix[i][j] = str(3.0)
                            elif data1[i]=='' and data2[j]=='':
                                matrix[i][j] = str(str(1/9)[:4])
                            elif data1[i]=='' and data2[j]=='':
                                matrix[i][j] = str(str(1/7)[:4])
                            elif data1[i]=='' and data2[j]=='':
                                matrix[i][j] = str(str(1/3)[:4])
    
                matrix = np.asarray(matrix,dtype=float)
            matrixB = np.asmatrix(matrix)
            return matrixB #判别矩阵B
    
        def getA_function(self): #准则层判别矩阵 5*5
            abilityList = [5,4,3,2,1]
            matrixA = AHP.get_matrixA(self,data1=abilityList,data2=abilityList) # 判别矩阵
            VectorA,RootA = AHP.get_Vector_Root(self,matrixA)
            print("
    A:")
            print("VectorA:
    ", VectorA)
            print("RootA:
    ", RootA)
            return VectorA,RootA
    
        def get_Vector_Root(self,dataArray):  #特征根和特征向量
            dataArray = np.asarray(dataArray)
            dataCenter = np.copy(dataArray)
            # dataCenter按列求和
            columnMatrixCenter = dataCenter.sum(axis=0)
            for i in range(1, len(dataArray) + 1):  # dataCenter列向量归一化
                dataCenter[:, i - 1:i] = dataCenter[:, i - 1:i] * (1 / columnMatrixCenter[i - 1])
            # dataCenter行向量求和
            linedataCenter = np.asarray(np.asmatrix(np.asarray(dataCenter.sum(axis=1))).T)
            # linedataCenter按列求和  【只有一列求和了】
            columnLinedataCenter = linedataCenter.sum(axis=0)
            for i in range(1, len(linedataCenter)):  # linedataCenter列向量归一化
                linedataCenter[:, i - 1:i] = linedataCenter[:, i - 1:i] * (1 / columnLinedataCenter)
            vector = linedataCenter  # 特征向量
            root = dataArray @ vector
            sumi = 0
            for i in range(0,len(dataArray)):
                sumi += root[i] / vector[i]
            Rootmax = (1 / len(dataArray)) * sumi  #最大特征根
            return vector, Rootmax
    
        def getB_function(self):  #计算方案层 判别矩阵  Value特征根  Vector特征向量   #B1~B5矩阵 9*9
            mathTrixB = AHP.get_matrixB(self,data1=list(map(float,list(self.arry2[0]))),data2=list(map(float,list(self.arry2[0]))))
    
            mathVectorB,mathRootBmax = AHP.get_Vector_Root(self,mathTrixB)
            print("
    math:")
            print("mathVectorB:
    ", mathVectorB)
            print("mathRootBmax:
    ", mathRootBmax)
            writeTrixB = AHP.get_matrixB(self, data1=list(self.arry2[1]), data2=list(self.arry2[1]))
    
            writeVectorB, writeRootBmax = AHP.get_Vector_Root(self, writeTrixB)
            print("
    write:")
            print("writeVectorB:
    ", writeVectorB)
            print("writeRootBmax:
    ", writeRootBmax)
            codeTrixB = AHP.get_matrixB(self,data1=list(map(float,list(self.arry2[2]))),data2=list(map(float,list(self.arry2[2]))))
    
            codeVectorB, codeRootBmax = AHP.get_Vector_Root(self, codeTrixB)
            print("
    code:")
            print("codeVectorB:
    ", codeVectorB)
            print("codeRootBmax:
    ", codeRootBmax)
            teamTrixB = AHP.get_matrixB(self,data1=list(self.arry2[3]),data2=list(self.arry2[3]))
    
            teamVectorB,teamRootBmax = AHP.get_Vector_Root(self, teamTrixB)
            print("
    team:")
            print("teamVectorB:
    ", teamVectorB)
            print("teamRootBmax:
    ", teamRootBmax)
            createTrixB = AHP.get_matrixB(self,data1=list(self.arry2[4]),data2=list(self.arry2[4]))
    
            createVectorB, createRootBmax = AHP.get_Vector_Root(self, createTrixB)
            print("
    create:")
            print("createVectorB:
    ", createVectorB)
            print("createRootBmax:
    ", createRootBmax)
            rootB = [mathRootBmax,writeRootBmax,codeRootBmax,teamRootBmax,createRootBmax]
            vectorB = [mathVectorB,writeVectorB,codeVectorB,teamVectorB,createVectorB]
            # root 特征根
            #vector 特征向量
            return rootB,vectorB
    
        def CR(self,vector,root): #计算一致性比率CR和一致性指标CI
            # n = len(array)  5的时候n = 1.12   9的时候n = 1.45【查表得知】
            if(len(vector)==5):
                RI=1.12
                CI = (root-len(vector)) / (len(vector)-1)
                CR = CI/RI
            else:
                RI = 1.45
                CI = (root - len(vector)) / (len(vector) - 1)
                CR = CI / RI
            return CR,CI
    
        def judge_choose(self):
            VectorA,RootA = AHP.getA_function(self)
            CRA,CIA = AHP.CR(self,VectorA,RootA)  #通过检测
            print("CRA",CRA)
            print("CIA",CIA)
            listRootB, listVectorB = AHP.getB_function(self)
            list_CRB = [] #通过检测
            list_CIB = []
            for i in range(0,5):
                CR,CI = AHP.CR(self,listVectorB[i],listRootB[i])
                list_CRB.append(CR)
                list_CIB.append(CI)
            # print("准则层判别矩阵的CR: ",CRA,"
    方案层判别矩阵的CR:",list_CRB)
            list_CR = list_CRB.copy()
            list_CR.append(CRA)
            print("B1~B5: CR:
    ", list_CRB)
            print("B1~B5:  CI: 
    ", list_CIB)
            testList = []
            for i in list_CR:
                if i[0]<0.1:
                    testList.append(1)
            # 所有判别矩阵的CR都小于0.1,不一致性程度在容许范围内,此时特征向量作为权向量。
            # self.resxx = []
            if sum(testList) == 6:
                    self.arry = np.hstack([listVectorB[0], listVectorB[1]])
                    for i in range(2,5):
                        self.arry = np.hstack([self.arry, listVectorB[i]])
                    # 选人
                    reslute = [] #存储人的序号 的列表
                    for i in range(0,9):
                        reslute.append((self.arry@VectorA)[i][0])
                    self.res1 = list(map(reslute.index, heapq.nlargest(6, reslute)))
                    self.resxx = [i+1 for i in self.res1]
    
    
            else:
                pass
            self.res1 = self.res1
            print("选中的人的矩阵行号:",self.res1)
            print("被命运选中的人",self.resxx)
            return self.resxx,self.res1
    
        def grouping(self):
            chooseNum,res = AHP.judge_choose(self)
            self.arry1 = np.asarray(np.asmatrix(self.arry1).T)
            self.target = np.vstack([self.arry1[res[0]],self.arry1[res[1]]])
            for i in range(2,6):
                self.target = np.vstack([self.target,self.arry1[res[i]]])
            self.target = np.asarray(np.asmatrix(self.target))[:,:3]
            for i in range(0,len(self.target)):
                for j in range(0,len(self.target[i])):
                    if self.target[i][j] == '':
                        self.target[i][j] = '95'
                    elif self.target[i][j] == '':
                        self.target[i][j] = '85'
                    elif self.target[i][j] == '':
                        self.target[i][j] = '75'
                    elif self.target[i][j] == '':
                        self.target[i][j] = '65'
            self.target = np.asarray(self.target,dtype=float)
            cmean = self.target.mean(axis=0) #按列求均值
            cstd = self.target.std(axis=0) #求标准差
            relative_adv = (self.target-cmean)/cstd  #相对优势
            print("相对优势矩阵:
    ",relative_adv)
    
            relative_adv_Max = np.max(relative_adv, axis=1)  #按行
            maxAdv = []
            for i in range(0,len(relative_adv_Max)):
                maxAdv.append(float(relative_adv_Max[i]))
            # print("各人最大相对优势:
    ", maxAdv)
            position = []
            relative_adv_matrix = np.asmatrix(relative_adv)
            for value in range(0,len(maxAdv)):
                index = np.argwhere(relative_adv_matrix == maxAdv[value])
                if value == 3:
                    position.append(index[2])
                elif value == 4:
                    position.append(index[3])
                else:
                    position.append(index)
            print("各人的最大相对优势在矩阵中的坐标:
    ",np.asarray(position).reshape(6,1))
    
            self.group = []
            for i in range(0,len(chooseNum)):
                self.group.append([chooseNum[i],self.target[i]])
            print("被选中的6人的分数
    ",np.asarray(self.group))
            allList = [] #在满足条件下,所有可能分组
            firstList = []
            secondList = []
            manTime = []
            chooseOne = chooseNum.copy()
            chooseTWo = chooseNum.copy()
            for i in range(1,4):
                #0-1 1-2 2-3
                if i == 1:
                    coumIndex = np.argwhere(relative_adv_matrix == float(np.max(relative_adv[:, i - 1:i], axis=0)[0]))
                    manTime.append(coumIndex[0][0])
                    firstList.append(chooseNum[int(coumIndex[0][0])])  #添加第几号人
                    chooseOne.remove(chooseOne[int(coumIndex[0][0])])
                    secondList.append(chooseNum[int(coumIndex[0][0])])  # 添加第几号人
                    chooseTWo.remove(chooseTWo[int(coumIndex[0][0])])
    
                elif i == 2:
                    coumIndex = np.argwhere(relative_adv_matrix == float(np.max(relative_adv[:, i - 1:i], axis=0)[0]))
                    coumIndex2 = coumIndex
    
                    i = 3
                    coumIndex3 = np.argwhere(relative_adv_matrix == float(np.max(relative_adv[:, i - 1:i], axis=0)[0]))
                    manTime.append(coumIndex3[0][0])
                    firstList.append(chooseNum[int(coumIndex3[0][0])])
                    chooseOne.remove(chooseOne[int(coumIndex3[0][0])-1])
                    secondList.append(chooseNum[int(coumIndex3[0][0])])
                    chooseTWo.remove(chooseTWo[int(coumIndex3[0][0]) - 1])
                    for j in range(0, len(coumIndex2)):
                        if coumIndex2[j][0] == manTime[0]:
                            pass
                        elif coumIndex2[j][0] == manTime[1]:
                            pass
                        else:
                            if coumIndex2[j][0] == 3:
                                firstList.append(chooseNum[int(coumIndex2[j][0])])
                                chooseOne.remove(chooseOne[int(coumIndex2[0][0])-3])
                                allList.append((firstList,chooseOne))
    
                            if coumIndex2[j][0] == 4:
                                secondList.append(chooseNum[int(coumIndex2[j][0])])
                                chooseTWo.remove(chooseTWo[int(coumIndex2[0][0]) - 2])
                                allList.append((secondList, chooseTWo))
    
                elif i == 3:
                    pass
            return allList
    
    
    
        def main(self):
            chooseGroup = AHP.grouping(self)
            for i in range(0,len(chooseGroup)):
                print("第{}种有效的分组:".format(i+1),chooseGroup[0])
    
    
    
    if __name__ == '__main__':
        a = AHP()
        a.main()
        print("【查RI表得知】:")
        print("RI: n=5的时候 RI5=1.12 ; n=9的时候 RI9=1.45")

    分组结果:请粘贴代码运行

  • 相关阅读:
    TClientDataSet[6]: 读取 TClientDataSet 中的图片数据
    TClientDataSet[2]: Data、XMLData
    TClientDataSet[5]: 读取数据
    TClientDataSet[1]: 浏览测试数据
    TClientDataSet[3]: 手动建立数据集
    从哪查找当前程序所有可用的环境变量?
    使用多窗体时, 关于节约内存和加快启动速度的思考与尝试
    一句话获取文件的最新修改时间
    用 SuperObject 解析淘宝上的 Json 数据 回复 "macrolen" 的问题
    “生气”的经典解释
  • 原文地址:https://www.cnblogs.com/chenruhai/p/12464221.html
Copyright © 2020-2023  润新知