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
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
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