Stable Marrige--稳定婚姻问题

来源:互联网 发布:八千湘女嫁新疆知乎 编辑:程序博客网 时间:2024/05/16 11:12

Stable Marrige

算法第一次作业!!
part1:暴力求解,遍历所有可能组合,输出一对stable的
part2:普通的通过preferences list求解
part3:第二问基础上加上cost

其实第一问好像跑不出来的,时间复杂度无穷大(捂脸),不过后来我知道了用全排列搞出所有组合

package pro;/** * Class to implement Stable Matching algorithms */import java.io.BufferedReader;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.InputStreamReader;import java.util.ArrayList;import java.util.LinkedList;import java.util.Queue;import java.util.Random;public class Assignment1 {    // Part1: Implement a Brute Force Solution    public static ArrayList<Integer> stableMatchBruteForce(Preferences preferences) {            ArrayList<ArrayList<Integer>> prof_list=preferences.getProfessors_preference();        ArrayList<ArrayList<Integer>> stu_list=preferences.getStudents_preference();        int prof_length=preferences.getProfessors_preference().size();        int stu_length=preferences.getStudents_preference().size();        //random arraylist        ArrayList<Integer> p_match=randomMatching(prof_length);        ArrayList<Integer> s_match=new ArrayList<Integer>();        for(int i=0;i<prof_length;i++) {        s_match.add(p_match.indexOf(i));                }                 if(ifStable(p_match,s_match,preferences)) {            p_match=randomMatching(prof_length);            s_match=new ArrayList<Integer>();            for(int i=0;i<prof_length;i++) {            s_match.add(p_match.indexOf(i));                    }                 }                return p_match;//prof opt    }    // Part2: Implement Gale-Shapley Algorithm,    public static ArrayList<Integer> stableMatchGaleShapley(Preferences preferences) {            ArrayList<ArrayList<Integer>> prof_list=preferences.getProfessors_preference();            ArrayList<ArrayList<Integer>> stu_list=preferences.getStudents_preference();            int prof_length=preferences.getProfessors_preference().size();        int stu_length=preferences.getStudents_preference().size();        //save the status of whether they`re matched,and initialize         ArrayList<Integer> prof_match=new ArrayList<Integer>();        ArrayList<Integer> stu_match=new ArrayList<Integer>();        for(int i=0;i<prof_length;i++) {            prof_match.add(-1);            stu_match.add(-1);        }        Queue<Integer> q=new LinkedList();        for(int i=0;i<prof_length;i++) {            q.offer(i);//insert element in the end, position 0 saves professor 1        }        //traverse prof,until empty        Integer prof_num=0;        while((prof_num=q.poll())!=null) {            for(int i=0;i<prof_length;i++) {//i presents the number of stu in prof_num`s list            int stu_num=prof_list.get(prof_num).get(i);//output i student  stu_num:1-4            //judge if student has been matched                         if((stu_match.get(stu_num-1))==-1) {//if stu not matched                stu_match.set(stu_num-1, prof_num);//stu`s match is prof                prof_match.set(prof_num, stu_num-1);                                break;            }else if(stu_list.get(stu_num-1).indexOf(prof_num+1)<stu_list.get(stu_num-1).indexOf(stu_match.get(stu_num-1)+1))  {                             prof_match.set(stu_match.get(stu_num-1), -1);                            int temp=stu_match.get(stu_num-1);                            stu_match.set(stu_num-1, prof_num);//stu`s new matching                            prof_match.set(prof_num, stu_num-1);//prof`s matching                           q.add(temp);//previous professor no matching                        break;                                              }        }                   }               return prof_match;    }    public static ArrayList<Integer> stableMatchGaleShapley_Student(Preferences preferences) {        ArrayList<ArrayList<Integer>> prof_list=preferences.getProfessors_preference();        ArrayList<ArrayList<Integer>> stu_list=preferences.getStudents_preference();        int prof_length=preferences.getProfessors_preference().size();        int stu_length=preferences.getStudents_preference().size();    //save the status of whether they`re matched,and initialize     ArrayList<Integer> prof_match=new ArrayList<Integer>();    ArrayList<Integer> stu_match=new ArrayList<Integer>();    for(int i=0;i<prof_length;i++) {        prof_match.add(-1);        stu_match.add(-1);    }    Queue<Integer> q=new LinkedList();    for(int i=0;i<prof_length;i++) {        q.offer(i);//insert element in the end, position 0 saves professor 1    }    //traverse prof,until empty    Integer stu_num=0;    while((stu_num=q.poll())!=null) {        for(int i=0;i<prof_length;i++) {//i presents the number of stu in prof_num`s list        int prof_num=stu_list.get(stu_num).get(i);//output i student  stu_num:1-4        //judge if student has been matched                     if((prof_match.get(prof_num-1))==-1) {//if stu not matched            prof_match.set(prof_num-1, stu_num);//stu`s match is prof            stu_match.set(stu_num, prof_num-1);                             break;        }else if(prof_list.get(prof_num-1).indexOf(stu_num+1)<prof_list.get(prof_num-1).indexOf(prof_match.get(prof_num-1)+1))  {                         stu_match.set(prof_match.get(prof_num-1), -1);                        int temp=prof_match.get(prof_num-1);                        prof_match.set(prof_num-1, stu_num);//stu`s new matching                        stu_match.set(stu_num, prof_num-1);//prof`s matching                       q.add(temp);//previous professor no matching                    break;                                          }    }               }           return stu_match;}    // Part3: Matching with Costs    public static ArrayList<Cost> stableMatchCosts(Preferences preferences) {        //creat cost list and initialize it        ArrayList<Cost> cost_list=new ArrayList<Cost>();        ArrayList<ArrayList<Integer>> prof_list=preferences.getProfessors_preference();    ArrayList<ArrayList<Integer>> stu_list=preferences.getStudents_preference();    int prof_length=preferences.getProfessors_preference().size();    int stu_length=preferences.getStudents_preference().size();    //save the status of whether they`re matched,and initialize     ArrayList<Integer> prof_match=new ArrayList<Integer>();    ArrayList<Integer> stu_match=new ArrayList<Integer>();    for(int i=0;i<prof_length;i++) {        prof_match.add(-1);        stu_match.add(-1);    }    Queue<Integer> q=new LinkedList();    for(int i=0;i<prof_length;i++) {        q.offer(i);//insert element in the end    }    Integer prof_num=0;    while((prof_num=q.poll())!=null) {//prof_num:0-3        for(int i=0;i<prof_length;i++) {//i presents the number of stu in prof_num`s list        int stu_num=prof_list.get(prof_num).get(i)-1;//output i student        //judge if student has been matched        if((stu_match.get(stu_num))==-1) {//if stu not matched            stu_match.set(stu_num, prof_num);//stu`s match is prof            prof_match.set(prof_num, stu_num);            //calculate cost to stu            int index=CostElement(cost_list,prof_num);//prof`s index                    if(index==10){                                                  Cost cost1=new Cost(prof_num, stu_num,i,stu_list.get(stu_num).indexOf(prof_num+1));                        cost_list.add(cost1);                    }else {                        Cost cost2=new Cost(prof_num, stu_num,i,stu_list.get(stu_num).indexOf(prof_num+1));                        cost_list.set(index, cost2);                    }            break;        }else if(stu_list.get(stu_num).indexOf(prof_num+1)<stu_list.get(stu_num).indexOf(stu_match.get(stu_num)+1)){                    prof_match.set(stu_match.get(stu_num), -1);//prvious prof has no matching                        int temp=stu_match.get(stu_num);                    stu_match.set(stu_num, prof_num);//stu`s new matching                        prof_match.set(prof_num, stu_num);//prof`s matching                    q.add(temp);//previous professor no matching                    int index=CostElement(cost_list,prof_num);//prof`s index                        if(index==10){                                                      Cost cost1=new Cost(prof_num, stu_num,i,stu_list.get(stu_num).indexOf(prof_num+1));                            cost_list.add(cost1);                        }else {                            Cost cost2=new Cost(prof_num, stu_num,i,stu_list.get(stu_num).indexOf(prof_num+1));                            cost_list.set(index, cost2);                        }                    break;                 }        }        }    return cost_list;    }    public static int CostElement(ArrayList<Cost> co,int p) {            int i=0;             while(i<co.size()) {                 if((co.get(i).getIndexOfProfessor())==p) {                     return i;                 }                 i++;             }        return 10;    }    //create an matching list randomly    public static ArrayList<Integer> randomMatching(int num){        ArrayList<Integer> matching=new ArrayList<Integer> ();        Random rd=new Random();        int[] index=new int[num];        for(int i=0;i<num;i++) {            index[i]=i;        }        int n=num;        for(int i=0;i<num;i++) {            int select=rd.nextInt(n);//don`t contain n            matching.add(index[select]);//prof`s matching list            //swap select number and last number            index[select]=index[n-1];            n--;        }            return matching;    }    public static boolean ifStable(ArrayList<Integer> p_match,ArrayList<Integer> s_match, Preferences preferences) {          int prof_length=p_match.size();          for(int i=0;i<prof_length;i++) { //i represents prof              ArrayList<Integer> prof_list=preferences.getProfessors_preference().get(i);              //traverse the student prof i prefers              for(int j=0;j<prof_length;j++) { //student j                  if(prof_list.indexOf(j)<prof_list.indexOf(p_match.get(i))) {                  //whether the student prefers the prof                  ArrayList<Integer> stu_list=preferences.getStudents_preference().get(j);                      //if student j prefers i than his spouse                  if(stu_list.indexOf(i+1)<stu_list.indexOf(s_match.get(j)+1))                           return false;                          //else student prefer his spouse                  }              }          }              return true;//when cannot find a stable matching    }}