예제 #1
0
def alt_fuzzy_TOPSIS(dm_data, weights, weight_method, score_method, *args):
    print "Peforming Fuzzy TOPSIS"
    """
    #get the decision matrix  
    # [[alt1, [critID, score], [critID, score], ... ], 
    #  [alt2, [critID, score], [critID, score], ... ], ... ]
    # scores in the form [a1, a2, a3] where mu(a1, a2, a3) = (0,1,0)
    raw_scores = getAvgFuzzyScores_Alt(input_file, score_method)
    
    #get fuzzy weights
    weights = getFuzzyWeights_Alt(input_file, weight_method)
    print "WEIGHTS:"
    for wr in weights: print wr
    """
    raw_scores = dm_data

    # sort raw scores by criteria ID
    for r in raw_scores:
        r1 = [r[0]]
        r1.extend(sorted(r[1:], key=lambda x: x[0]))
    print "RAW SCORES:"
    for r in raw_scores:
        print r

    #normalize the decision matrix
    norm_scores = raw_scores
    ss = ['sum_squares']
    for i in range(1, len(norm_scores[0])):
        ss_fzy = [0 for n in norm_scores[0][i][1]]
        for j in range(len(norm_scores)):  #sum the squares for each criteria

            if score_method == 'FT' or score_method == 'FZ':
                for k in range(len(ss_fzy)):
                    ss_fzy[k] = ss_fzy[k] + float(norm_scores[j][i][1][k])**2

        for f in ss_fzy:
            f = f**0.5  #take sqrt
        ss.append(ss_fzy)

    for i in range(1, len(norm_scores[0])):
        for j in range(
                len(norm_scores)):  #divide each score by the sum of squares
            if score_method == 'FT' or score_method == 'FZ':
                for k in range(len(norm_scores[j][i][1])):
                    norm_scores[j][i][1][
                        k] = norm_scores[j][i][1][k] / ss[i][-(k + 1)]

    print 'Normalized DM: '
    for r in norm_scores:
        print r

    #weight the normalized decision matrix
    for i in range(1, len(norm_scores[0])):
        for j in range(len(norm_scores)):
            for k in range(len(weights)):
                if weights[k][0] == norm_scores[j][i][0]:

                    if score_method == 'FT' and weight_method == 'FT':
                        norm_scores[j][i][1] = \
                        fuzzy.mult_FuzzyTri((norm_scores[j][i][1], weights[k][1]))

                    elif score_method == 'FZ' and weight_method == 'FT':
                        None

    print 'Weighted and Normalized DM: '
    for r in norm_scores:
        print r

    #get positive and negative ideal
    pos_ideals = ['A+']
    neg_ideals = ['A-']
    for i in range(1, len(norm_scores[0])):
        pos_ideals.append(norm_scores[0][i][1])  #start with first element
        neg_ideals.append(norm_scores[0][i][1])  #start with first element

    for i in range(1, len(norm_scores[0])):
        for j in range(len(norm_scores)):

            #check positive ideal
            d1 = fuzzy.dominance_FuzzyTri(pos_ideals[i], norm_scores[j][i][1])
            d2 = fuzzy.dominance_FuzzyTri(norm_scores[j][i][1], pos_ideals[i])
            print 'A:', pos_ideals[i], ' B:', norm_scores[j][i][
                1], '  d(A,B):', d1, '  d(B,A):', d2
            if d2 == 1.0 and d1 < 0.99: pos_ideals[i] = norm_scores[j][i][1]

            #check negative ideal
            d1 = fuzzy.dominance_FuzzyTri(neg_ideals[i], norm_scores[j][i][1])
            d2 = fuzzy.dominance_FuzzyTri(norm_scores[j][i][1], neg_ideals[i])
            if d1 == 1.0 and d2 < 0.99: neg_ideals[i] = norm_scores[j][i][1]

    #for p in pos_ideals: print p
    #for p in neg_ideals: print p

    #get fuzzy separation distances
    # for ideal (a1_i, a2_i, a3_i) fuzzy distance is
    # ( SUM((a1-a1_s)^2)^0.5, SUM((a2-a2_s)^2)^0.5, SUM((a3-a3_s)^2)^0.5 )
    pos_dist = []  #[alt1_dist, alt2_dist, ...]
    neg_dist = []  #[alt1_dist, alt2_dist, ...]

    for j in range(len(norm_scores)):
        S_pos = [0 for n in norm_scores[j][1][1]]
        S_neg = [0 for n in norm_scores[j][1][1]]
        for i in range(1, len(norm_scores[j])):

            if score_method == 'FT':
                S_pos = [S_pos[0] + (norm_scores[j][i][1][0] - pos_ideals[i][0])**2, \
                         S_pos[1] + (norm_scores[j][i][1][1] - pos_ideals[i][1])**2, \
                         S_pos[2] + (norm_scores[j][i][1][2] - pos_ideals[i][2])**2 ]
                S_neg = [S_neg[0] + (norm_scores[j][i][1][0] - neg_ideals[i][0])**2, \
                         S_neg[1] + (norm_scores[j][i][1][1] - neg_ideals[i][1])**2, \
                         S_neg[2] + (norm_scores[j][i][1][2] - neg_ideals[i][2])**2 ]

            elif score_method == 'FZ':
                None

        for a in S_pos:
            a = a**0.5  #take square root to get distance
        for a in S_neg:
            a = a**0.5  #take square root to get distance
        pos_dist.append(S_pos)
        neg_dist.append(S_neg)

    #print "Positive Separation:", pos_dist
    #print "Negative Separation:", neg_dist

    #get relative closeness
    rel_closeness = []
    for i in range(len(pos_dist)):
        rel_closeness.append([neg_dist[i][0]/(neg_dist[i][2]+pos_dist[i][2]), \
                              neg_dist[i][1]/(neg_dist[i][1]+pos_dist[i][1]), \
                              neg_dist[i][2]/(neg_dist[i][0]+pos_dist[i][0])])

    #print "Relative Closeness:"
    #for i in range(len(rel_closeness)): print 'Alt', i, ':', rel_closeness[i]

    #get rankings
    rankings = getFuzzyRanks(rel_closeness, score_method)
    #print 'Rankings:', rankings

    for i in range(len(rel_closeness)):
        for j in range(len(rel_closeness[i])):
            rel_closeness[i][j] = float(str(rel_closeness[i][j])[0:6])

    #plot results
    #labels = ['A'+str(i+1) for i in range(len(rel_closeness))]
    labels = ['Alt ' + x[0] for x in norm_scores]

    if score_method == 'FT':
        fig = plt.figure(figsize=(7, 6))
        a = fig.add_subplot(111)
        for n in rel_closeness:
            a.plot([n[0], n[1], n[2]], [0., 1., 0.], linewidth=2.5)
    if score_method == 'FZ':
        None

    a.set_title('Fuzzy TOPSIS')
    a.set_ylabel('Membership')
    a.set_xlabel('Relative Closeness')
    plt.legend(labels)

    #path = '/temp/' + strftime("FUZZY_TOPSIS1_%Y-%m-%d %H:%M:%S", gmtime()).replace(" ", "") + '.png'
    #fig.savefig(mainpath+path)

    return None
예제 #2
0
def alt_fuzzy_AHP1(data, weights, score_method, *args):
    # takes in inputs:
    #     data = [[critID, [alt1#, alt2#, alt3#, ...], 
    #                     [alt1/alt1, alt1/alt2, alt1/alt3, ...],
    #                     [alt2/alt1, alt2/alt2, alt2/alt3, ...],
    #                     ...]
    #             [critID, [alt1#, alt2#, alt3#, ...], 
    #                     [alt1/alt1, alt1/alt2, alt1/alt3, ...],
    #                     [alt2/alt1, alt2/alt2, alt2/alt3, ...],
    #                     ...]
    #           ]
    #     weights =  [[critID1, critWeight1], [critID2, critWeight2], ...]
    #
    #     score_method = 'FT': fuzzy triangular
    #                    'FZ': fuzzy trapezoidal

    # normalize alternative matrices by sum of columns
    #print 'Begininng Analytical Heirarchy Process...'
    #print 'Normalizing each Criterion comparison matrix...'
    alts = data[0][1]
    
    norm_data = []
    for i in range(len(data)):                  #parse each criteria matrix
        norm_matrix = [data[i][0], data[i][1]]  #init norm data matrix for criteria
        
        for j in range(2,len(data[i])):         #parse rows of comparison matrix
            norm_row = []                       #init norm data 
            
            for k in range(len(data[i][j])):    #parse columns of comparison matrix
                if score_method == 'FT':
                    row_sum = fuzzy.add_FuzzyTri(data[i][j1][k] for j1 in range(2,len(data[i])) ) 
                    norm_row.append( fuzzy.divide_FuzzyTri(data[i][j][k], row_sum ))  
                                                           #divide by sum of column
                if score_method == 'FZ':
                    pass
                
            norm_matrix.append(norm_row)        #append row to matrix
        norm_data.append(norm_matrix)
        
    #sum rows of normalized matrix into total score
    sums = []
    for i in range(len(norm_data)):             #for each criteria
        col = [norm_data[i][0]]                 #add criteria ID
        for j in range(len(alts)):              #for each alternative in same order
            total = fuzzy.add_FuzzyTri( norm_data[i][ norm_data[i][1].index(alts[j])+2] )
            count = len( norm_data[i][ norm_data[i][1].index(alts[j])+2] )
            col.append([t/count for t in total])
        sums.append(col)
    
    #sort weights (assume already normalized)
    #total = sum(w[1] for w in weights)# removed
    sorted_weights = []
    for s in sums: 
        for w in weights:
            if w[0] == s[0]: 
                sorted_weights.append(w[1]) #/total)#removed
                    
    #multiply columns by criteria weights and sum
    scores = []
    for j in range(len(alts)):
        weighted_scores = [] 
        for i in range(len(sums)):
            weighted_scores.append( fuzzy.mult_FuzzyTri([sorted_weights[i], sums[i][(j+1)]]) )
                #multiply weight * score
        score = fuzzy.add_FuzzyTri(weighted_scores)
        scores.append([alts[j], score])
        
    return scores    
예제 #3
0
def alt_fuzzy_TOPSIS(dm_data, weights, weight_method, score_method, *args):
    print "Peforming Fuzzy TOPSIS"
    
    """
    #get the decision matrix  
    # [[alt1, [critID, score], [critID, score], ... ], 
    #  [alt2, [critID, score], [critID, score], ... ], ... ]
    # scores in the form [a1, a2, a3] where mu(a1, a2, a3) = (0,1,0)
    raw_scores = getAvgFuzzyScores_Alt(input_file, score_method)
    
    #get fuzzy weights
    weights = getFuzzyWeights_Alt(input_file, weight_method)
    print "WEIGHTS:"
    for wr in weights: print wr
    """
    raw_scores = dm_data    
    
    # sort raw scores by criteria ID
    for r in raw_scores: 
        r1 = [r[0]]
        r1.extend(sorted(r[1:], key=lambda x: x[0]))
    print "RAW SCORES:"
    for r in raw_scores: print r
    

    #normalize the decision matrix
    norm_scores = raw_scores
    ss = ['sum_squares']
    for i in range(1,len(norm_scores[0])):
        ss_fzy = [0 for n in norm_scores[0][i][1]]
        for j in range(len(norm_scores)): #sum the squares for each criteria
        
            if score_method == 'FT' or score_method == 'FZ':
                for k in range(len(ss_fzy)):
                    ss_fzy[k] = ss_fzy[k] + float(norm_scores[j][i][1][k])**2
            
        for f in ss_fzy: f = f**0.5 #take sqrt
        ss.append(ss_fzy)
      
    for i in range(1,len(norm_scores[0])):
        for j in range(len(norm_scores)): #divide each score by the sum of squares
            if score_method == 'FT' or score_method == 'FZ':
                for k in range(len(norm_scores[j][i][1])):
                    norm_scores[j][i][1][k] = norm_scores[j][i][1][k] / ss[i][-(k+1)]
            
    print 'Normalized DM: '
    for r in norm_scores: print r
    
    #weight the normalized decision matrix
    for i in range(1,len(norm_scores[0])):
        for j in range(len(norm_scores)):
            for k in range(len(weights)):
                if weights[k][0] == norm_scores[j][i][0]:
                    
                    if score_method == 'FT' and weight_method == 'FT':
                        norm_scores[j][i][1] = \
                        fuzzy.mult_FuzzyTri((norm_scores[j][i][1], weights[k][1]))
                        
                    elif score_method == 'FZ' and weight_method == 'FT':
                        None
                    
    print 'Weighted and Normalized DM: '    
    for r in norm_scores: print r
    
    #get positive and negative ideal
    pos_ideals = ['A+']
    neg_ideals = ['A-']
    for i in range(1,len(norm_scores[0])): 
        pos_ideals.append(norm_scores[0][i][1]) #start with first element
        neg_ideals.append(norm_scores[0][i][1]) #start with first element
        
    for i in range(1,len(norm_scores[0])):   
        for j in range(len(norm_scores)):
            
            #check positive ideal
            d1 = fuzzy.dominance_FuzzyTri(pos_ideals[i], norm_scores[j][i][1])
            d2 = fuzzy.dominance_FuzzyTri(norm_scores[j][i][1], pos_ideals[i])
            print 'A:', pos_ideals[i], ' B:', norm_scores[j][i][1], '  d(A,B):', d1,  '  d(B,A):', d2 
            if d2 == 1.0 and d1 < 0.99: pos_ideals[i] = norm_scores[j][i][1]
            
            #check negative ideal
            d1 = fuzzy.dominance_FuzzyTri(neg_ideals[i], norm_scores[j][i][1])
            d2 = fuzzy.dominance_FuzzyTri(norm_scores[j][i][1], neg_ideals[i])
            if d1 == 1.0 and d2 < 0.99: neg_ideals[i] = norm_scores[j][i][1]
            
    #for p in pos_ideals: print p
    #for p in neg_ideals: print p
    
    #get fuzzy separation distances
    # for ideal (a1_i, a2_i, a3_i) fuzzy distance is 
    # ( SUM((a1-a1_s)^2)^0.5, SUM((a2-a2_s)^2)^0.5, SUM((a3-a3_s)^2)^0.5 )
    pos_dist = []           #[alt1_dist, alt2_dist, ...]
    neg_dist = []           #[alt1_dist, alt2_dist, ...]
    
    for j in range(len(norm_scores)):
        S_pos = [0 for n in norm_scores[j][1][1]]
        S_neg = [0 for n in norm_scores[j][1][1]]
        for i in range(1,len(norm_scores[j])):

            if score_method == 'FT':
                S_pos = [S_pos[0] + (norm_scores[j][i][1][0] - pos_ideals[i][0])**2, \
                         S_pos[1] + (norm_scores[j][i][1][1] - pos_ideals[i][1])**2, \
                         S_pos[2] + (norm_scores[j][i][1][2] - pos_ideals[i][2])**2 ]
                S_neg = [S_neg[0] + (norm_scores[j][i][1][0] - neg_ideals[i][0])**2, \
                         S_neg[1] + (norm_scores[j][i][1][1] - neg_ideals[i][1])**2, \
                         S_neg[2] + (norm_scores[j][i][1][2] - neg_ideals[i][2])**2 ]
                         
            elif score_method == 'FZ': None     
            
        for a in S_pos: a = a**0.5 #take square root to get distance
        for a in S_neg: a = a**0.5 #take square root to get distance
        pos_dist.append(S_pos)
        neg_dist.append(S_neg)
        
    #print "Positive Separation:", pos_dist
    #print "Negative Separation:", neg_dist
    
    #get relative closeness
    rel_closeness = []
    for i in range(len(pos_dist)):
        rel_closeness.append([neg_dist[i][0]/(neg_dist[i][2]+pos_dist[i][2]), \
                              neg_dist[i][1]/(neg_dist[i][1]+pos_dist[i][1]), \
                              neg_dist[i][2]/(neg_dist[i][0]+pos_dist[i][0])])
    
    #print "Relative Closeness:"
    #for i in range(len(rel_closeness)): print 'Alt', i, ':', rel_closeness[i]
    
    #get rankings
    rankings = getFuzzyRanks(rel_closeness, score_method)
    #print 'Rankings:', rankings
    
    for i in range(len(rel_closeness)):
        for j in range(len(rel_closeness[i])): 
            rel_closeness[i][j] = float(str(rel_closeness[i][j])[0:6])
    
    #plot results
    #labels = ['A'+str(i+1) for i in range(len(rel_closeness))]
    labels = ['Alt ' + x[0] for x in norm_scores]  
    
    if score_method == 'FT':
        fig = plt.figure(figsize=(7, 6))
        a = fig.add_subplot(111)
        for n in rel_closeness:
            a.plot([n[0], n[1], n[2]], [0.,1.,0.], linewidth=2.5)
    if score_method == 'FZ': 
        None
        
    a.set_title('Fuzzy TOPSIS')
    a.set_ylabel('Membership')
    a.set_xlabel('Relative Closeness')
    plt.legend(labels)
        
    #path = '/temp/' + strftime("FUZZY_TOPSIS1_%Y-%m-%d %H:%M:%S", gmtime()).replace(" ", "") + '.png'
    #fig.savefig(mainpath+path)
    
    return None