def reduce_data(data_in, out_type): """ reduce the list of expert alternative data (min, max) to some usable scores in a decision matrix (except the AHS data reductions) [[alt1, [critID, score], [critID, score], ... ], [alt2, [critID, score], [critID, score], ... ], ... ] Example: Fuzzy tri scores in the form [a1, a2, a3] where mu(a1, a2, a3) = (0,1,0) out_types: 'AVG' - average all mins and maxs and take the average (return 1 value) 'AVG_RANGE' - returns the average min and averae max 'FUZZ_TRI_1' - return fuzzy triangular (avg min, avg, avg max) for (0, 1, 0) 'FUZZ_TRAP_1' - returns a fuzzy trapezoidal number (min, avg min, avg max, max) for (0,1,1,0) 'FUZZ_TRAP_2' - returns a fuzzy trapezoidal number (avg min, max(min), min(max), avg max) for (0,1,1,0) 'FUZZ_TRAP_UNI' - returns a fuzzy trapezoidal number (avg min, avg min, avg max, avg max) for (0,1,1,0) 'AHP_CRISP' - get Analytical Hierarchy Process (comparison) matricies from expert's scores (ratio of avgerages) 'AHP_RANGE' - get Analytical Hierarchy Process (comparison) matricies from expert's scores (range by avg_min/avg_max - avg_max/avg_min) 'AHP_RANGE_LARGE' - get Analytical Hierarchy Process (comparison) matricies from expert's scores (range by min(min)/max(max) - max(max)/min(min)) 'AHP_FUZZY_TRI_1' - get Analytical Hierarchy Process (comparison) matricies from expert's scores (same as FUZZ_TRI_1) 'AHP_FUZZY_TRAP_1' - get Analytical Hierarchy Process (comparison) matricies from expert's scores (same as FUZZ_TRAP_1) 'AHP_FUZZY_TRAP_2' - get Analytical Hierarchy Process (comparison) matricies from expert's scores (same as FUZZ_TRAP_2) 'AHP_FUZZY_TRAP_UNI' - get Analytical Hierarchy Process (comparison) matricies from expert's scores (same as FUZZ_TRAP_3) """ #get number of alts: crit_count = len(data_in) alt_count = len(data_in[0]) #actually number of alts + 1 as they start at index 1 print crit_count, 'Criteria found; ', alt_count-1, 'Alternatives found' #maximum ranges from existing ratios mm_ranges = [] for i in range(crit_count): max1 = max([max([x3[1] for x3 in x2[1:]]) for x2 in data_in[i][1:]]) #get max eval for criteria min1 = min([min([x3[0] for x3 in x2[1:]]) for x2 in data_in[i][1:]]) #get min eval for criteria #range1 = max1/min1 - min1/max1 mm_ranges.append( [min1/max1, max1/min1] ) #get minimum and maximum ratios #translate to this range out_mm = [1./9., 9.0] def scale_ratio(inratio, in_range, out_range=out_mm): if inratio < 1: out = min(out_range) + (inratio-min(in_range)) * \ (1.0 - min(out_range)) / (1.0 - min(in_range)) #print 'in:', inratio, ' in_R:', in_range, ' out_R:', out_range, ' min:', out return out if inratio > 1: out = 1.0 + (inratio - 1.0) * (max(out_range) - 1.0) / (max(in_range) - 1.0) #print 'in:', inratio, ' in_R:', in_range, ' out_R:', out_range, ' max:', out return out else: return 1.0 data_out = [] #-------------------------------------------------------------------------- # average all mins and maxs and take the average (return 1 value) if out_type == 'AVG': for i in range(1,alt_count): alt_scores = [data_in[0][i][0]] for j in range(crit_count): all_scores = data_in[j][i][1:len(data_in[j][i])] avg = sum([sum(x)/2.0 for x in all_scores])/ \ len([sum(x) for x in all_scores]) alt_scores.append([data_in[j][0], avg]) data_out.append(alt_scores) #-------------------------------------------------------------------------- # returns the average min and averae max if out_type == 'AVG_RANGE': for i in range(1,alt_count): alt_scores = [data_in[0][i][0]] for j in range(crit_count): all_scores = data_in[j][i][1:len(data_in[j][i])] avgs = [sum([x[0] for x in all_scores])/len(all_scores), \ sum([x[1] for x in all_scores])/len(all_scores)] alt_scores.append([data_in[j][0], avgs]) data_out.append(alt_scores) #-------------------------------------------------------------------------- # return fuzzy triangular (avg min, avg, avg max) for (0, 1, 0) if out_type == 'FUZZ_TRI_1': for i in range(1,alt_count): alt_scores = [data_in[0][i][0]] for j in range(crit_count): all_scores = data_in[j][i][1:len(data_in[j][i])] avgs = [sum([x[0] for x in all_scores])/len(all_scores), \ sum([sum(x)/2.0 for x in all_scores])/ \ len([sum(x) for x in all_scores]), \ sum([x[1] for x in all_scores])/len(all_scores)] alt_scores.append([data_in[j][0], avgs]) data_out.append(alt_scores) #-------------------------------------------------------------------------- # returns a fuzzy trapezoidal number (min, avg min, avg max, max) for (0,1,1,0) if out_type == 'FUZZ_TRAP_1': for i in range(1,alt_count): alt_scores = [data_in[0][i][0]] for j in range(crit_count): all_scores = data_in[j][i][1:len(data_in[j][i])] avgs = [min([x[0] for x in all_scores]), sum([x[0] for x in all_scores])/len(all_scores), sum([x[1] for x in all_scores])/len(all_scores), max([x[1] for x in all_scores])] alt_scores.append([data_in[j][0], avgs]) data_out.append(alt_scores) #-------------------------------------------------------------------------- # returns a fuzzy trapezoidal number (avg min, max(min), min(max), avg max) for (0,1,1,0) if out_type == 'FUZZ_TRAP_2': for i in range(1,alt_count): alt_scores = [data_in[0][i][0]] for j in range(crit_count): all_scores = data_in[j][i][1:len(data_in[j][i])] avgs = [sum([x[0] for x in all_scores])/len(all_scores), max([x[0] for x in all_scores]), min([x[1] for x in all_scores]), sum([x[1] for x in all_scores])/len(all_scores)] avgs.sort() alt_scores.append([data_in[j][0], avgs]) data_out.append(alt_scores) #-------------------------------------------------------------------------- # returns a fuzzy trapezoidal number (avg min, avg min, avg max, avg max) for (0,1,1,0) if out_type == 'FUZZ_TRAP_UNI': for i in range(1,alt_count): alt_scores = [data_in[0][i][0]] for j in range(crit_count): all_scores = data_in[j][i][1:len(data_in[j][i])] avgs = [sum([x[0] for x in all_scores])/len(all_scores), sum([x[0] for x in all_scores])/len(all_scores), sum([x[1] for x in all_scores])/len(all_scores), sum([x[1] for x in all_scores])/len(all_scores)] alt_scores.append([data_in[j][0], avgs]) data_out.append(alt_scores) #-------------------------------------------------------------------------- # get Analytical Hierarchy Process (comparison) matricies from expert's scores (ratio of avgerages) # 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, ...], # ...] # ] if out_type == 'AHP_CRISP': data_out = [] for i in range(crit_count): #for each criteria comp_matrix = [data_in[i][0]] #init comparison matrix with critID alt_nums = [] for j in range(1,alt_count): alt_nums.append(data_in[i][j][0]) comp_matrix.append(alt_nums) for j in range(1,alt_count): #for each alternative comp_row = [] all_scores1 = data_in[i][j][1:len(data_in[i][j])] avg1 = sum([sum(x)/2.0 for x in all_scores1])/ \ len([sum(x) for x in all_scores1]) #get avg score of 1st alt for k in range(1,alt_count): all_scores2 = data_in[i][k][1:len(data_in[i][k])] avg2 = sum([sum(x)/2.0 for x in all_scores2])/ \ len([sum(x) for x in all_scores2]) #get avg score of 2nd alt if j == k: #catch for alt1 = alt2 comp_row.append(1.) else: ratio = scale_ratio((avg1/avg2), mm_ranges[i], out_range=out_mm) comp_row.append(ratio) comp_matrix.append(comp_row) data_out.append(comp_matrix) #-------------------------------------------------------------------------- # get Analytical Hierarchy Process (comparison) matricies from expert's scores (ratio of avgerages) # 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, ...], # ...] # ] if out_type == 'AHP_RANGE': data_out = [] for i in range(crit_count): comp_matrix = [data_in[i][0]] #init comparison matrix with critID alt_nums = [] for j in range(1,alt_count): alt_nums.append(data_in[i][j][0]) comp_matrix.append(alt_nums) for j in range(1,alt_count): comp_row = [] all_scores1 = data_in[i][j][1:len(data_in[i][j])] avg_min1 = sum([x[0] for x in all_scores1])/ \ len([x[0] for x in all_scores1]) #get average minimum score avg_max1 = sum([x[1] for x in all_scores1])/ \ len([x[1] for x in all_scores1]) #get average maximum score for k in range(1,alt_count): all_scores2 = data_in[i][k][1:len(data_in[i][k])] avg_min2 = sum([x[0] for x in all_scores2])/ \ len([x[0] for x in all_scores2]) #get average minimum score avg_max2 = sum([x[1] for x in all_scores2])/ \ len([x[1] for x in all_scores2]) #get average maximum score if j == k: #catch for alt1 = alt2 comp_row.append([1.,1.]) else: ratios = [avg_min1/avg_max2, avg_max1/avg_min2] for l in range(len(ratios)): ratios[l] = scale_ratio(ratios[l], mm_ranges[i], out_range=out_mm) comp_row.append(ratios) comp_matrix.append(comp_row) data_out.append(comp_matrix) #-------------------------------------------------------------------------- # get Analytical Hierarchy Process (comparison) matricies from expert's scores (ratio of avgerages) # 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, ...], # ...] # ] if out_type == 'AHP_RANGE_LARGE': data_out = [] for i in range(crit_count): comp_matrix = [data_in[i][0]] #init comparison matrix with critID alt_nums = [] for j in range(1,alt_count): alt_nums.append(data_in[i][j][0]) comp_matrix.append(alt_nums) for j in range(1,alt_count): comp_row = [] all_scores1 = data_in[i][j][1:len(data_in[i][j])] avg_min1 = min([x[0] for x in all_scores1]) #get minimum of minimum scores avg_max1 = max([x[1] for x in all_scores1]) #get maximum of maximum score for k in range(1,alt_count): all_scores2 = data_in[i][k][1:len(data_in[i][k])] avg_min2 = min([x[0] for x in all_scores2]) #get average minimum score avg_max2 = max([x[1] for x in all_scores2]) #get average maximum score if j == k: #catch for alt1 = alt2 comp_row.append([1.,1.]) else: ratios = [avg_min1/avg_max2, avg_max1/avg_min2] for l in range(len(ratios)): ratios[l] = scale_ratio(ratios[l], mm_ranges[i], out_range=out_mm) comp_row.append(ratios) comp_matrix.append(comp_row) data_out.append(comp_matrix) #-------------------------------------------------------------------------- # get Analytical Hierarchy Process (comparison) matricies from expert's scores (ratio of avgerages) # 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, ...], # ...] # ] if out_type == 'AHP_FUZZ_TRI_1': data_out = [] for i in range(crit_count): comp_matrix = [data_in[i][0]] #init comparison matrix with critID alt_nums = [] for j in range(1,alt_count): alt_nums.append(data_in[i][j][0]) comp_matrix.append(alt_nums) for j in range(1,alt_count): comp_row = [] all_scores1 = data_in[i][j][1:len(data_in[i][j])] scores1 = [sum([x[0] for x in all_scores1])/len(all_scores1), \ sum([sum(x)/2.0 for x in all_scores1])/ \ len([sum(x) for x in all_scores1]), \ sum([x[1] for x in all_scores1])/len(all_scores1)] #get fuzzy tri scores (min, avg, max) for 1st alt for k in range(1,alt_count): all_scores2 = data_in[i][k][1:len(data_in[i][k])] scores2 = [sum([x[0] for x in all_scores2])/len(all_scores2), \ sum([sum(x)/2.0 for x in all_scores2])/ \ len([sum(x) for x in all_scores2]), \ sum([x[1] for x in all_scores2])/len(all_scores2)] #get fuzzy tri scores (min, avg, max) for 2nd alt if j == k: #catch for alt1 = alt2 comp_row.append([1.,1.,1.]) else: ratios = fuzzy.divide_FuzzyTri(scores1,scores2) for l in range(len(ratios)): ratios[l] = scale_ratio(ratios[l], mm_ranges[i], out_range=out_mm) comp_row.append(ratios) comp_matrix.append(comp_row) data_out.append(comp_matrix) #-------------------------------------------------------------------------- # get Analytical Hierarchy Process (comparison) matricies from expert's scores (ratio of avgerages) # 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, ...], # ...] # ] if out_type == 'AHP_FUZZ_TRAP_1': data_out = [] for i in range(crit_count): comp_matrix = [data_in[i][0]] #init comparison matrix with critID alt_nums = [] for j in range(1,alt_count): alt_nums.append(data_in[i][j][0]) comp_matrix.append(alt_nums) for j in range(1,alt_count): comp_row = [] all_scores1 = data_in[i][j][1:len(data_in[i][j])] scores1 = [min([x[0] for x in all_scores1]), sum([x[0] for x in all_scores1])/len(all_scores1), sum([x[1] for x in all_scores1])/len(all_scores1), max([x[1] for x in all_scores1])] #get fuzzy tri scores (min, avg, max) for 1st alt for k in range(1,alt_count): all_scores2 = data_in[i][k][1:len(data_in[i][k])] scores2 = [min([x[0] for x in all_scores2]), sum([x[0] for x in all_scores2])/len(all_scores2), sum([x[1] for x in all_scores2])/len(all_scores2), max([x[1] for x in all_scores2])] #get fuzzy tri scores (min, avg, max) for 2nd alt if j == k: #catch for alt1 = alt2 comp_row.append([1.,1.,1.]) else: ratios = fuzzy.divide_FuzzyTrap(scores1,scores2) for l in range(len(ratios)): ratios[l] = scale_ratio(ratios[l], mm_ranges[i], out_range=out_mm) comp_row.append(ratios) comp_matrix.append(comp_row) data_out.append(comp_matrix) #-------------------------------------------------------------------------- # get Analytical Hierarchy Process (comparison) matricies from expert's scores (ratio of avgerages) # 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, ...], # ...] # ] if out_type == 'AHP_FUZZ_TRAP_2': data_out = [] for i in range(crit_count): comp_matrix = [data_in[i][0]] #init comparison matrix with critID alt_nums = [] for j in range(1,alt_count): alt_nums.append(data_in[i][j][0]) comp_matrix.append(alt_nums) for j in range(1,alt_count): comp_row = [] all_scores1 = data_in[i][j][1:len(data_in[i][j])] scores1 = [sum([x[0] for x in all_scores1])/len(all_scores1), max([x[0] for x in all_scores1]), min([x[1] for x in all_scores1]), sum([x[1] for x in all_scores1])/len(all_scores1)] scores1.sort() #get fuzzy tri scores (min, avg, max) for 1st alt for k in range(1,alt_count): all_scores2 = data_in[i][k][1:len(data_in[i][k])] scores2 = [sum([x[0] for x in all_scores2])/len(all_scores2), max([x[0] for x in all_scores2]), min([x[1] for x in all_scores2]), sum([x[1] for x in all_scores2])/len(all_scores2)] scores2.sort() #get fuzzy tri scores (min, avg, max) for 2nd alt if j == k: #catch for alt1 = alt2 comp_row.append([1.,1.,1.]) else: ratios = fuzzy.divide_FuzzyTrap(scores1,scores2) for l in range(len(ratios)): ratios[l] = scale_ratio(ratios[l], mm_ranges[i], out_range=out_mm) comp_row.append(ratios) comp_matrix.append(comp_row) data_out.append(comp_matrix) #-------------------------------------------------------------------------- # get Analytical Hierarchy Process (comparison) matricies from expert's scores (ratio of avgerages) # 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, ...], # ...] # ] if out_type == 'AHP_FUZZ_TRAP_UNI': #(use a box trapezoidal score [avg min, avg min, avg max, avg, max] to mimic the uniform probabilistic data_out = [] for i in range(crit_count): comp_matrix = [data_in[i][0]] #init comparison matrix with critID alt_nums = [] for j in range(1,alt_count): alt_nums.append(data_in[i][j][0]) comp_matrix.append(alt_nums) for j in range(1,alt_count): comp_row = [] all_scores1 = data_in[i][j][1:len(data_in[i][j])] scores1 = [sum([x[0] for x in all_scores1])/len(all_scores1), sum([x[0] for x in all_scores1])/len(all_scores1), sum([x[1] for x in all_scores1])/len(all_scores1), sum([x[1] for x in all_scores1])/len(all_scores1)] scores1.sort() #get fuzzy tri scores (min, avg, max) for 1st alt for k in range(1,alt_count): all_scores2 = data_in[i][k][1:len(data_in[i][k])] scores2 = [sum([x[0] for x in all_scores2])/len(all_scores2), sum([x[0] for x in all_scores2])/len(all_scores2), sum([x[1] for x in all_scores2])/len(all_scores2), sum([x[1] for x in all_scores2])/len(all_scores2)] scores2.sort() #get fuzzy tri scores (min, avg, max) for 2nd alt if j == k: #catch for alt1 = alt2 comp_row.append([1.,1.,1.]) else: ratios = fuzzy.divide_FuzzyTrap(scores1,scores2) for l in range(len(ratios)): ratios[l] = scale_ratio(ratios[l], mm_ranges[i], out_range=out_mm) comp_row.append(ratios) comp_matrix.append(comp_row) data_out.append(comp_matrix) #-------------------------------------------------------------------------- #-------------------------------------------------------------------------- #-------------------------------------------------------------------------- return data_out
def alt_fuzzy_AHP3(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 = NOT USED! #sort the data matrices by criteria ID data.sort(key = lambda row: row[0]) # modify matrix to create trapezoidal numbers: #accepts fuzzy numbers up to lenth of 4 (crisp, range, triangular, trapezoidal) #remove criteria ids and alt IDs and just retain data crits = [d[0] for d in data] #saving in case needed alt_IDs = data[0][1] comp_matrices = [] for i in range(len(data)): #parse each criteria matrix matrix = [] for j in range(2,len(data[i])): #parse rows of comparison matrix mat_row = [[1,1,1,1] for j1 in range(2,len(data[i]))] for k in range(len(data[i][j])): #parse columns of comparison matrix if len(data[i][j][k]) == 4: mat_row[k] = data[i][j][k] elif len(data[i][j][k]) == 3: mat_row[k] = [data[i][j][k][0], data[i][j][k][1], \ data[i][j][k][1], data[i][j][k][2]] elif len(data[i][j][k]) == 2: mat_row[k] = [data[i][j][k][0], data[i][j][k][0], \ data[i][j][k][1], data[i][j][k][1]] elif len(data[i][j][k]) == 1: mat_row[k] = [data[i][j][k][0], data[i][j][k][0], \ data[i][j][k][0], data[i][j][k][0]] matrix.append(mat_row) comp_matrices.append(matrix) #for c in comp_matrices: # print "NEW CRIT" # for c1 in c: print c1 #get computing the normalized value of row sums (i.e. fuzzy synthetic extent) #by fuzzy arithmetic operations: for i in range(len(comp_matrices)): S_i = [None for r in comp_matrices[i]] #row sums for j in range(len(comp_matrices[i])): S_i[j] = fuzzy.add_FuzzyTrap(comp_matrices[i][j]) mat_total = fuzzy.add_FuzzyTrap(S_i) #matrix total (for normalization) S_i = [fuzzy.divide_FuzzyTrap(s,mat_total) for s in S_i] #normalize row sums #get degrees of possibility S_i > all other S """ #sort and normalize weights weights.sort(key = lambda row: row[0]) #change weights to fuzzy trapezoidal numbers for i in range(len(weights)): if len(weights[i][1]) == 4: pass elif len(weights[i][1]) == 3: weights[i][1] = [weights[i][1][0], weights[i][1][1], weights[i][1][1], weights[i][1][2]] elif len(weights[i][1]) == 2: weights[i][1] = [weights[i][1][0], weights[i][1][0], weights[i][1][1], weights[i][1][1]] elif len(weights[i][1]) == 1: weights[i][1] = [weights[i][1], weights[i][1], weights[i][1], weights[i][1]] #don't normalize weights #q = max(max(w[1]) for w in weights) #for i in range(len(weights)): # for j in range(len(weights[i][1])): # weights[i][1][j] = weights[i][1][j] / q #multiply prority vectors by criteria weights and sum #return in structure [[altID1, score1], [altID2, score2], ...] #where each score if a fuzzy number (a,b,c,d) scores = [] for j in range(len(alt_IDs)): scores.append([alt_IDs[j], fuzzy.add_FuzzyTrap(fuzzy.mult_FuzzyTrap([weights[i][1], p_vectors[i][j]]) \ for i in range(len(weights)))]) """ return None
def alt_fuzzy_AHP2(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 = NOT USED! #sort the data matrices by criteria ID data.sort(key = lambda row: row[0]) # modify matrix to create trapezoidal numbers: #accepts fuzzy numbers up to lenth of 4 (crisp, range, triangular, trapezoidal) #remove criteria ids and alt IDs and just retain data crits = [d[0] for d in data] #saving in case needed alt_IDs = data[0][1] comp_matrices = [] for i in range(len(data)): #parse each criteria matrix matrix = [] for j in range(2,len(data[i])): #parse rows of comparison matrix mat_row = [[1,1,1,1] for j1 in range(2,len(data[i]))] for k in range(len(data[i][j])): #parse columns of comparison matrix if len(data[i][j][k]) == 4: mat_row[k] = data[i][j][k] elif len(data[i][j][k]) == 3: mat_row[k] = [data[i][j][k][0], data[i][j][k][1], \ data[i][j][k][1], data[i][j][k][2]] elif len(data[i][j][k]) == 2: mat_row[k] = [data[i][j][k][0], data[i][j][k][0], \ data[i][j][k][1], data[i][j][k][1]] elif len(data[i][j][k]) == 1: mat_row[k] = [data[i][j][k][0], data[i][j][k][0], \ data[i][j][k][0], data[i][j][k][0]] matrix.append(mat_row) comp_matrices.append(matrix) #for c in comp_matrices: # print "NEW CRIT" # for c1 in c: print c1 #get geometric mean of each row in each matrix p_vectors = [] for i in range(len(comp_matrices)): priority_vector = [None for x in comp_matrices[i]] matrix_sum = [0.,0.,0.,0.] #sum row geometric means for j in range(len(comp_matrices[i])): row_product = fuzzy.mult_FuzzyTrap(comp_matrices[i][j]) #multiply all the row elements geom_mean = [x**(1.0/len(comp_matrices[i][j])) for x in row_product] #get geometric mean priority_vector[j] = geom_mean #create priority vector of row geometric means matrix_sum = fuzzy.add_FuzzyTrap([matrix_sum, geom_mean]) #add to matrix sum priority_vector = [fuzzy.divide_FuzzyTrap(pv, matrix_sum) \ for pv in priority_vector] p_vectors.append(priority_vector) #sort and normalize weights weights.sort(key = lambda row: row[0]) #change weights to fuzzy trapezoidal numbers for i in range(len(weights)): if len(weights[i][1]) == 4: pass elif len(weights[i][1]) == 3: weights[i][1] = [weights[i][1][0], weights[i][1][1], weights[i][1][1], weights[i][1][2]] elif len(weights[i][1]) == 2: weights[i][1] = [weights[i][1][0], weights[i][1][0], weights[i][1][1], weights[i][1][1]] elif len(weights[i][1]) == 1: weights[i][1] = [weights[i][1], weights[i][1], weights[i][1], weights[i][1]] #don't normalize weights #q = max(max(w[1]) for w in weights) #for i in range(len(weights)): # for j in range(len(weights[i][1])): # weights[i][1][j] = weights[i][1][j] / q #multiply prority vectors by criteria weights and sum #return in structure [[altID1, score1], [altID2, score2], ...] #where each score if a fuzzy number (a,b,c,d) scores = [] for j in range(len(alt_IDs)): scores.append([alt_IDs[j], fuzzy.add_FuzzyTrap(fuzzy.mult_FuzzyTrap([weights[i][1], p_vectors[i][j]]) \ for i in range(len(weights)))]) return scores
def reduce_data(data_in, out_type): """ reduce the list of expert alternative data (min, max) to some usable scores in a decision matrix (except the AHS data reductions) [[alt1, [critID, score], [critID, score], ... ], [alt2, [critID, score], [critID, score], ... ], ... ] Example: Fuzzy tri scores in the form [a1, a2, a3] where mu(a1, a2, a3) = (0,1,0) out_types: 'AVG' - average all mins and maxs and take the average (return 1 value) 'AVG_RANGE' - returns the average min and averae max 'FUZZ_TRI_1' - return fuzzy triangular (avg min, avg, avg max) for (0, 1, 0) 'FUZZ_TRAP_1' - returns a fuzzy trapezoidal number (min, avg min, avg max, max) for (0,1,1,0) 'FUZZ_TRAP_2' - returns a fuzzy trapezoidal number (avg min, max(min), min(max), avg max) for (0,1,1,0) 'FUZZ_TRAP_UNI' - returns a fuzzy trapezoidal number (avg min, avg min, avg max, avg max) for (0,1,1,0) 'AHP_CRISP' - get Analytical Hierarchy Process (comparison) matricies from expert's scores (ratio of avgerages) 'AHP_RANGE' - get Analytical Hierarchy Process (comparison) matricies from expert's scores (range by avg_min/avg_max - avg_max/avg_min) 'AHP_RANGE_LARGE' - get Analytical Hierarchy Process (comparison) matricies from expert's scores (range by min(min)/max(max) - max(max)/min(min)) 'AHP_FUZZY_TRI_1' - get Analytical Hierarchy Process (comparison) matricies from expert's scores (same as FUZZ_TRI_1) 'AHP_FUZZY_TRAP_1' - get Analytical Hierarchy Process (comparison) matricies from expert's scores (same as FUZZ_TRAP_1) 'AHP_FUZZY_TRAP_2' - get Analytical Hierarchy Process (comparison) matricies from expert's scores (same as FUZZ_TRAP_2) 'AHP_FUZZY_TRAP_UNI' - get Analytical Hierarchy Process (comparison) matricies from expert's scores (same as FUZZ_TRAP_3) """ #get number of alts: crit_count = len(data_in) alt_count = len( data_in[0]) #actually number of alts + 1 as they start at index 1 print crit_count, 'Criteria found; ', alt_count - 1, 'Alternatives found' #maximum ranges from existing ratios mm_ranges = [] for i in range(crit_count): max1 = max([max([x3[1] for x3 in x2[1:]]) for x2 in data_in[i][1:]]) #get max eval for criteria min1 = min([min([x3[0] for x3 in x2[1:]]) for x2 in data_in[i][1:]]) #get min eval for criteria #range1 = max1/min1 - min1/max1 mm_ranges.append([min1 / max1, max1 / min1]) #get minimum and maximum ratios #translate to this range out_mm = [1. / 9., 9.0] def scale_ratio(inratio, in_range, out_range=out_mm): if inratio < 1: out = min(out_range) + (inratio-min(in_range)) * \ (1.0 - min(out_range)) / (1.0 - min(in_range)) #print 'in:', inratio, ' in_R:', in_range, ' out_R:', out_range, ' min:', out return out if inratio > 1: out = 1.0 + (inratio - 1.0) * (max(out_range) - 1.0) / (max(in_range) - 1.0) #print 'in:', inratio, ' in_R:', in_range, ' out_R:', out_range, ' max:', out return out else: return 1.0 data_out = [] #-------------------------------------------------------------------------- # average all mins and maxs and take the average (return 1 value) if out_type == 'AVG': for i in range(1, alt_count): alt_scores = [data_in[0][i][0]] for j in range(crit_count): all_scores = data_in[j][i][1:len(data_in[j][i])] avg = sum([sum(x)/2.0 for x in all_scores])/ \ len([sum(x) for x in all_scores]) alt_scores.append([data_in[j][0], avg]) data_out.append(alt_scores) #-------------------------------------------------------------------------- # returns the average min and averae max if out_type == 'AVG_RANGE': for i in range(1, alt_count): alt_scores = [data_in[0][i][0]] for j in range(crit_count): all_scores = data_in[j][i][1:len(data_in[j][i])] avgs = [sum([x[0] for x in all_scores])/len(all_scores), \ sum([x[1] for x in all_scores])/len(all_scores)] alt_scores.append([data_in[j][0], avgs]) data_out.append(alt_scores) #-------------------------------------------------------------------------- # return fuzzy triangular (avg min, avg, avg max) for (0, 1, 0) if out_type == 'FUZZ_TRI_1': for i in range(1, alt_count): alt_scores = [data_in[0][i][0]] for j in range(crit_count): all_scores = data_in[j][i][1:len(data_in[j][i])] avgs = [sum([x[0] for x in all_scores])/len(all_scores), \ sum([sum(x)/2.0 for x in all_scores])/ \ len([sum(x) for x in all_scores]), \ sum([x[1] for x in all_scores])/len(all_scores)] alt_scores.append([data_in[j][0], avgs]) data_out.append(alt_scores) #-------------------------------------------------------------------------- # returns a fuzzy trapezoidal number (min, avg min, avg max, max) for (0,1,1,0) if out_type == 'FUZZ_TRAP_1': for i in range(1, alt_count): alt_scores = [data_in[0][i][0]] for j in range(crit_count): all_scores = data_in[j][i][1:len(data_in[j][i])] avgs = [ min([x[0] for x in all_scores]), sum([x[0] for x in all_scores]) / len(all_scores), sum([x[1] for x in all_scores]) / len(all_scores), max([x[1] for x in all_scores]) ] alt_scores.append([data_in[j][0], avgs]) data_out.append(alt_scores) #-------------------------------------------------------------------------- # returns a fuzzy trapezoidal number (avg min, max(min), min(max), avg max) for (0,1,1,0) if out_type == 'FUZZ_TRAP_2': for i in range(1, alt_count): alt_scores = [data_in[0][i][0]] for j in range(crit_count): all_scores = data_in[j][i][1:len(data_in[j][i])] avgs = [ sum([x[0] for x in all_scores]) / len(all_scores), max([x[0] for x in all_scores]), min([x[1] for x in all_scores]), sum([x[1] for x in all_scores]) / len(all_scores) ] avgs.sort() alt_scores.append([data_in[j][0], avgs]) data_out.append(alt_scores) #-------------------------------------------------------------------------- # returns a fuzzy trapezoidal number (avg min, avg min, avg max, avg max) for (0,1,1,0) if out_type == 'FUZZ_TRAP_UNI': for i in range(1, alt_count): alt_scores = [data_in[0][i][0]] for j in range(crit_count): all_scores = data_in[j][i][1:len(data_in[j][i])] avgs = [ sum([x[0] for x in all_scores]) / len(all_scores), sum([x[0] for x in all_scores]) / len(all_scores), sum([x[1] for x in all_scores]) / len(all_scores), sum([x[1] for x in all_scores]) / len(all_scores) ] alt_scores.append([data_in[j][0], avgs]) data_out.append(alt_scores) #-------------------------------------------------------------------------- # get Analytical Hierarchy Process (comparison) matricies from expert's scores (ratio of avgerages) # 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, ...], # ...] # ] if out_type == 'AHP_CRISP': data_out = [] for i in range(crit_count): #for each criteria comp_matrix = [data_in[i][0]] #init comparison matrix with critID alt_nums = [] for j in range(1, alt_count): alt_nums.append(data_in[i][j][0]) comp_matrix.append(alt_nums) for j in range(1, alt_count): #for each alternative comp_row = [] all_scores1 = data_in[i][j][1:len(data_in[i][j])] avg1 = sum([sum(x)/2.0 for x in all_scores1])/ \ len([sum(x) for x in all_scores1]) #get avg score of 1st alt for k in range(1, alt_count): all_scores2 = data_in[i][k][1:len(data_in[i][k])] avg2 = sum([sum(x)/2.0 for x in all_scores2])/ \ len([sum(x) for x in all_scores2]) #get avg score of 2nd alt if j == k: #catch for alt1 = alt2 comp_row.append(1.) else: ratio = scale_ratio((avg1 / avg2), mm_ranges[i], out_range=out_mm) comp_row.append(ratio) comp_matrix.append(comp_row) data_out.append(comp_matrix) #-------------------------------------------------------------------------- # get Analytical Hierarchy Process (comparison) matricies from expert's scores (ratio of avgerages) # 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, ...], # ...] # ] if out_type == 'AHP_RANGE': data_out = [] for i in range(crit_count): comp_matrix = [data_in[i][0]] #init comparison matrix with critID alt_nums = [] for j in range(1, alt_count): alt_nums.append(data_in[i][j][0]) comp_matrix.append(alt_nums) for j in range(1, alt_count): comp_row = [] all_scores1 = data_in[i][j][1:len(data_in[i][j])] avg_min1 = sum([x[0] for x in all_scores1])/ \ len([x[0] for x in all_scores1]) #get average minimum score avg_max1 = sum([x[1] for x in all_scores1])/ \ len([x[1] for x in all_scores1]) #get average maximum score for k in range(1, alt_count): all_scores2 = data_in[i][k][1:len(data_in[i][k])] avg_min2 = sum([x[0] for x in all_scores2])/ \ len([x[0] for x in all_scores2]) #get average minimum score avg_max2 = sum([x[1] for x in all_scores2])/ \ len([x[1] for x in all_scores2]) #get average maximum score if j == k: #catch for alt1 = alt2 comp_row.append([1., 1.]) else: ratios = [avg_min1 / avg_max2, avg_max1 / avg_min2] for l in range(len(ratios)): ratios[l] = scale_ratio(ratios[l], mm_ranges[i], out_range=out_mm) comp_row.append(ratios) comp_matrix.append(comp_row) data_out.append(comp_matrix) #-------------------------------------------------------------------------- # get Analytical Hierarchy Process (comparison) matricies from expert's scores (ratio of avgerages) # 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, ...], # ...] # ] if out_type == 'AHP_RANGE_LARGE': data_out = [] for i in range(crit_count): comp_matrix = [data_in[i][0]] #init comparison matrix with critID alt_nums = [] for j in range(1, alt_count): alt_nums.append(data_in[i][j][0]) comp_matrix.append(alt_nums) for j in range(1, alt_count): comp_row = [] all_scores1 = data_in[i][j][1:len(data_in[i][j])] avg_min1 = min([x[0] for x in all_scores1 ]) #get minimum of minimum scores avg_max1 = max([x[1] for x in all_scores1 ]) #get maximum of maximum score for k in range(1, alt_count): all_scores2 = data_in[i][k][1:len(data_in[i][k])] avg_min2 = min([x[0] for x in all_scores2 ]) #get average minimum score avg_max2 = max([x[1] for x in all_scores2 ]) #get average maximum score if j == k: #catch for alt1 = alt2 comp_row.append([1., 1.]) else: ratios = [avg_min1 / avg_max2, avg_max1 / avg_min2] for l in range(len(ratios)): ratios[l] = scale_ratio(ratios[l], mm_ranges[i], out_range=out_mm) comp_row.append(ratios) comp_matrix.append(comp_row) data_out.append(comp_matrix) #-------------------------------------------------------------------------- # get Analytical Hierarchy Process (comparison) matricies from expert's scores (ratio of avgerages) # 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, ...], # ...] # ] if out_type == 'AHP_FUZZ_TRI_1': data_out = [] for i in range(crit_count): comp_matrix = [data_in[i][0]] #init comparison matrix with critID alt_nums = [] for j in range(1, alt_count): alt_nums.append(data_in[i][j][0]) comp_matrix.append(alt_nums) for j in range(1, alt_count): comp_row = [] all_scores1 = data_in[i][j][1:len(data_in[i][j])] scores1 = [sum([x[0] for x in all_scores1])/len(all_scores1), \ sum([sum(x)/2.0 for x in all_scores1])/ \ len([sum(x) for x in all_scores1]), \ sum([x[1] for x in all_scores1])/len(all_scores1)] #get fuzzy tri scores (min, avg, max) for 1st alt for k in range(1, alt_count): all_scores2 = data_in[i][k][1:len(data_in[i][k])] scores2 = [sum([x[0] for x in all_scores2])/len(all_scores2), \ sum([sum(x)/2.0 for x in all_scores2])/ \ len([sum(x) for x in all_scores2]), \ sum([x[1] for x in all_scores2])/len(all_scores2)] #get fuzzy tri scores (min, avg, max) for 2nd alt if j == k: #catch for alt1 = alt2 comp_row.append([1., 1., 1.]) else: ratios = fuzzy.divide_FuzzyTri(scores1, scores2) for l in range(len(ratios)): ratios[l] = scale_ratio(ratios[l], mm_ranges[i], out_range=out_mm) comp_row.append(ratios) comp_matrix.append(comp_row) data_out.append(comp_matrix) #-------------------------------------------------------------------------- # get Analytical Hierarchy Process (comparison) matricies from expert's scores (ratio of avgerages) # 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, ...], # ...] # ] if out_type == 'AHP_FUZZ_TRAP_1': data_out = [] for i in range(crit_count): comp_matrix = [data_in[i][0]] #init comparison matrix with critID alt_nums = [] for j in range(1, alt_count): alt_nums.append(data_in[i][j][0]) comp_matrix.append(alt_nums) for j in range(1, alt_count): comp_row = [] all_scores1 = data_in[i][j][1:len(data_in[i][j])] scores1 = [ min([x[0] for x in all_scores1]), sum([x[0] for x in all_scores1]) / len(all_scores1), sum([x[1] for x in all_scores1]) / len(all_scores1), max([x[1] for x in all_scores1]) ] #get fuzzy tri scores (min, avg, max) for 1st alt for k in range(1, alt_count): all_scores2 = data_in[i][k][1:len(data_in[i][k])] scores2 = [ min([x[0] for x in all_scores2]), sum([x[0] for x in all_scores2]) / len(all_scores2), sum([x[1] for x in all_scores2]) / len(all_scores2), max([x[1] for x in all_scores2]) ] #get fuzzy tri scores (min, avg, max) for 2nd alt if j == k: #catch for alt1 = alt2 comp_row.append([1., 1., 1.]) else: ratios = fuzzy.divide_FuzzyTrap(scores1, scores2) for l in range(len(ratios)): ratios[l] = scale_ratio(ratios[l], mm_ranges[i], out_range=out_mm) comp_row.append(ratios) comp_matrix.append(comp_row) data_out.append(comp_matrix) #-------------------------------------------------------------------------- # get Analytical Hierarchy Process (comparison) matricies from expert's scores (ratio of avgerages) # 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, ...], # ...] # ] if out_type == 'AHP_FUZZ_TRAP_2': data_out = [] for i in range(crit_count): comp_matrix = [data_in[i][0]] #init comparison matrix with critID alt_nums = [] for j in range(1, alt_count): alt_nums.append(data_in[i][j][0]) comp_matrix.append(alt_nums) for j in range(1, alt_count): comp_row = [] all_scores1 = data_in[i][j][1:len(data_in[i][j])] scores1 = [ sum([x[0] for x in all_scores1]) / len(all_scores1), max([x[0] for x in all_scores1]), min([x[1] for x in all_scores1]), sum([x[1] for x in all_scores1]) / len(all_scores1) ] scores1.sort() #get fuzzy tri scores (min, avg, max) for 1st alt for k in range(1, alt_count): all_scores2 = data_in[i][k][1:len(data_in[i][k])] scores2 = [ sum([x[0] for x in all_scores2]) / len(all_scores2), max([x[0] for x in all_scores2]), min([x[1] for x in all_scores2]), sum([x[1] for x in all_scores2]) / len(all_scores2) ] scores2.sort() #get fuzzy tri scores (min, avg, max) for 2nd alt if j == k: #catch for alt1 = alt2 comp_row.append([1., 1., 1.]) else: ratios = fuzzy.divide_FuzzyTrap(scores1, scores2) for l in range(len(ratios)): ratios[l] = scale_ratio(ratios[l], mm_ranges[i], out_range=out_mm) comp_row.append(ratios) comp_matrix.append(comp_row) data_out.append(comp_matrix) #-------------------------------------------------------------------------- # get Analytical Hierarchy Process (comparison) matricies from expert's scores (ratio of avgerages) # 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, ...], # ...] # ] if out_type == 'AHP_FUZZ_TRAP_UNI': #(use a box trapezoidal score [avg min, avg min, avg max, avg, max] to mimic the uniform probabilistic data_out = [] for i in range(crit_count): comp_matrix = [data_in[i][0]] #init comparison matrix with critID alt_nums = [] for j in range(1, alt_count): alt_nums.append(data_in[i][j][0]) comp_matrix.append(alt_nums) for j in range(1, alt_count): comp_row = [] all_scores1 = data_in[i][j][1:len(data_in[i][j])] scores1 = [ sum([x[0] for x in all_scores1]) / len(all_scores1), sum([x[0] for x in all_scores1]) / len(all_scores1), sum([x[1] for x in all_scores1]) / len(all_scores1), sum([x[1] for x in all_scores1]) / len(all_scores1) ] scores1.sort() #get fuzzy tri scores (min, avg, max) for 1st alt for k in range(1, alt_count): all_scores2 = data_in[i][k][1:len(data_in[i][k])] scores2 = [ sum([x[0] for x in all_scores2]) / len(all_scores2), sum([x[0] for x in all_scores2]) / len(all_scores2), sum([x[1] for x in all_scores2]) / len(all_scores2), sum([x[1] for x in all_scores2]) / len(all_scores2) ] scores2.sort() #get fuzzy tri scores (min, avg, max) for 2nd alt if j == k: #catch for alt1 = alt2 comp_row.append([1., 1., 1.]) else: ratios = fuzzy.divide_FuzzyTrap(scores1, scores2) for l in range(len(ratios)): ratios[l] = scale_ratio(ratios[l], mm_ranges[i], out_range=out_mm) comp_row.append(ratios) comp_matrix.append(comp_row) data_out.append(comp_matrix) #-------------------------------------------------------------------------- #-------------------------------------------------------------------------- #-------------------------------------------------------------------------- return data_out