TOPSIS (Technique for Order Preference by Similarity to an Ideal Solution )法是C.L.Hwang和K.Yoon于1981年首次提出,TOPSIS法根据有限个评价对象与理想化目标的接近程度进行排序的方法,是在现有的对象中进行相对优劣的评价。TOPSIS法是一种逼近于理想解的排序法,该方法只要求各效用函数具有单调递增(或递减)性就行。TOPSIS法是多目标决策分析中一种常用的有效方法,又称为优劣解距离法。
其基本原理,是通过检测评价对象与最优解、最劣解的距离来进行排序,若评价对象最靠近最优解同时又最远离最劣解,则为最好;否则不为最优。其中最优解的各指标值都达到各评价指标的最优值。最劣解的各指标值都达到各评价指标的最差值。
(引:https://baike.baidu.com/item/TOPSIS法/3094166?fr=aladdin)
主类:
javapackage p;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Scanner;
public class Topsis {
public final static int D = 6;//指标数
public final static double[] weight={9,7,7,8,6,5}; //各指标权重
public static int T = 0;
private static Scanner s;
public static void main(String[] args) {
List<Alternative> al =new LinkedList<Alternative>();
//从文件录入数据
try(BufferedReader br=new BufferedReader( new FileReader("data2.txt"))){
String tmp=null;
while((tmp=br.readLine())!=null){
s = new Scanner(tmp);
double[] data=new double[D];
String num=s.next();
for(int i=0;i<D;i++){
data[i]=s.nextDouble();
}
al.add(new Alternative(num,data));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
double x[]=new double[D],y[]=new double[D];
for(int i=0;i<D;i++){
x[i]=0;
y[i]=0;
}
for(Alternative a:al){
for(int i=0;i<D;i++){
x[i]+=Math.pow(a.attribute[i],2);
}
}
for(int i=0;i<D;i++){
x[i]=Math.sqrt(x[i]);
}
for(Alternative a:al){
for(int i=0;i<D;i++){
a.attribute[i]=a.attribute[i]/x[i];
}
a.weighted();
}
//计算正负理想解
for(int i=0;i<D;i++){
for(Alternative a:al){
a.comp=i;
}
x[i]=Collections.max(al).attribute[i];
y[i]=Collections.min(al).attribute[i];
}
Alternative best = new Alternative("",x);
Alternative worse = new Alternative("",y);
//计算正负理想解的距离、贴进度
ListIterator<Alternative> it = al.listIterator();
while(it.hasNext()){
Alternative t=it.next();
t.bestdis=0;
for(int j=0;j<D;j++){
t.bestdis+=Math.pow(t.attribute[j]-best.attribute[j],2);
}
t.bestdis=Math.sqrt(t.bestdis);
}
it = al.listIterator();
while(it.hasNext()){
Alternative t=it.next();
t.worsedis=0;
for(int j=0;j<D;j++){
t.worsedis+=Math.pow(t.attribute[j]-worse.attribute[j],2);
}
t.worsedis=Math.sqrt(t.worsedis);
t.c=t.worsedis/(t.worsedis+t.bestdis);
}
//按照贴进度排序
Collections.sort(al,new Comparator<Alternative>(){
public int compare(Alternative a1, Alternative a2){
return a2.c>a1.c?1:-1;
}
});
for(Alternative a:al){
System.out.println(a.num+" "+a.c);
}
}
}
决策类
package p;
public class Alternative implements Comparable<Alternative>{
int comp;
String num;
double[] attribute=new double[Topsis.D]; //指标
double bestdis,worsedis,c; //与正、负理想解的欧式距离,c为贴进度
public Alternative(String num,double[] d) {
this.num=num;
for(int i=0;i<Topsis.D;i++){
this.attribute[i]=d[i];
}
}
public void weighted(){ //赋权
for(int i=0;i<Topsis.D;i++){
this.attribute[i]*=Topsis.weight[i];
}
}
public int compareTo(Alternative a) {
return (int) (this.attribute[comp]-a.attribute[comp]);
}
}
文件输入示例(data.txt):
Alice 5 4 4 4 4 4
Bob 4 4 4 4 4 5
C 3 4 5 6 7 8
输出示例:
C 0.5655129205733348
Alice 0.42799645672055653
Bob 0.28646921021227667