代码续......

GraphEntry类

 
  
  1. class GraphEntry {  
  2.     private ArrayList<Integer> list;  
  3.     private int line;  
  4.     private int info;  
  5.       
  6.     public GraphEntry(){  
  7.         list = new ArrayList<Integer>();  
  8.     }  
  9.       
  10.     public void addLine(int line){  
  11.         this.line |= line;  
  12.     }  
  13.       
  14.     public int getLine(){  
  15.         return line;  
  16.     }  
  17.     public void setInfo(int info){  
  18.         this.info = info;  
  19.     }  
  20.       
  21.     public int getInfo(){  
  22.         return info;  
  23.     }  
  24.     public void insertItem(int id){  
  25.         list.add(id);  
  26.     }  
  27.           
  28.     public int getItem(int index){  
  29.         int id = list.get(index);  
  30.         return id;  
  31.     }  
  32.       
  33.     public int size(){  
  34.         return list.size();  
  35.     }  
  36. }  

TableEntry类

 
  
  1. class TableEntry {  
  2.     private boolean known;  
  3.     private int dist;  
  4.     private int path;  
  5.       
  6.     public void setKnown(boolean flag){  
  7.         known = flag;  
  8.     }  
  9.       
  10.     public boolean getKnown(){  
  11.         return known;  
  12.     }  
  13.       
  14.     public void setDist(int dist){  
  15.         this.dist = dist;  
  16.     }  
  17.       
  18.     public int getDist(){  
  19.         return dist;  
  20.     }  
  21.       
  22.     public void setPath(int path){  
  23.         this.path = path;  
  24.     }  
  25.       
  26.     public int getPath(){  
  27.         return path;  
  28.     }  
  29. }  

核心类:

 
  
  1. class PathSearch {  
  2.  
  3.     private Hashtable<Integer, String> mHashTable1;  
  4.     private Hashtable<String, Integer> mHashTable2;   
  5.     private GraphEntry graph[];  
  6.     private TableEntry table[];  
  7.     private int vertexNum;   
  8.     private String beginStation;  
  9.     private int beginVertex;  
  10.     private String endStation;  
  11.     private int endVertex;  
  12.     private String mResult;  
  13.     private ArrayList<Integer> mPath;  
  14.  
  15.     /** construct function */ 
  16.     public PathSearch(){  
  17.         initHashTable();      
  18.         initGraph();  
  19.         makeGraph();  
  20.         addGraphDetail();  
  21.         initTable();  
  22.     }  
  23.       
  24.     /** hash table init */ 
  25.     public void initHashTable(){          
  26.         int i, j, id = 0;  
  27.           
  28.         mHashTable1 = new Hashtable<Integer, String>();  
  29.         mHashTable2 = new Hashtable<String, Integer>();       
  30.           
  31.         for (i = 0; i < ResFinalVars.lines.length; i++)  
  32.         {  
  33.             for (j = 0; j < ResFinalVars.lines[i].length; j++){  
  34.                 if (mHashTable1.contains(ResFinalVars.lines[i][j]) == false)  
  35.                 {  
  36.                     mHashTable1.put(id, ResFinalVars.lines[i][j]);  
  37.                     mHashTable2.put(ResFinalVars.lines[i][j], id);  
  38.                     id++;  
  39.                 }                 
  40.             }             
  41.         }  
  42.           
  43.         vertexNum = id;  
  44.     }  
  45.       
  46.     /** return id by string */ 
  47.     public int findIdByKey(String key){  
  48.         return mHashTable2.get(key);  
  49.     }  
  50.       
  51.     /** return string by id */ 
  52.     public String findStrById(int id){  
  53.         return mHashTable1.get(id);  
  54.     }  
  55.       
  56.     /** graph init */ 
  57.     public void initGraph(){  
  58.         int vertexNum = this.getVertexNum();  
  59.         graph = new GraphEntry[vertexNum];  
  60.         for (int i = 0; i < vertexNum; i++)  
  61.         {  
  62.             graph[i] = new GraphEntry();      
  63.         }  
  64.           
  65.         mPath = new ArrayList<Integer>();  
  66.     }  
  67.       
  68.     /** graph make */ 
  69.     public void makeGraph(){  
  70.         int i, j, id, index;  
  71.         for (i = 0; i < ResFinalVars.lines.length; i++)  
  72.         {  
  73.             for (j = 1; j < ResFinalVars.lines[i].length - 1; j++)  
  74.             {             
  75.                 id = findIdByKey(ResFinalVars.lines[i][j]);  
  76.                 graph[id].insertItem(findIdByKey(ResFinalVars.lines[i][j + 1]));  
  77.                 graph[id].insertItem(findIdByKey(ResFinalVars.lines[i][j - 1]));  
  78.             }    
  79.             index = 0;  
  80.             graph[findIdByKey(ResFinalVars.lines[i][index])].insertItem(findIdByKey(ResFinalVars.lines[i][index + 1]));  
  81.             index = ResFinalVars.lines[i].length - 1;  
  82.             graph[findIdByKey(ResFinalVars.lines[i][index])].insertItem(findIdByKey(ResFinalVars.lines[i][index - 1]));                        
  83.         }       
  84.     }  
  85.       
  86.       
  87.     /** add graph detail, line number and other info */ 
  88.     public void addGraphDetail(){  
  89.           
  90.         int i, j, id;  
  91.         // add line info          
  92.         for (i = 0; i < ResFinalVars.lines.length; i++)  
  93.         {  
  94.             for (j = 0; j < ResFinalVars.lines[i].length; j++)  
  95.             {  
  96.                 id = findIdByKey(ResFinalVars.lines[i][j]);  
  97.                 graph[id].setInfo(ResFinalVars.NORMAL);   
  98.                 switch(i){  
  99.                 case 0:  
  100.                     graph[id].addLine(ResFinalVars.LINESINFO.LINE1.getValue());  
  101.                     break;  
  102.                 case 1:  
  103.                     graph[id].addLine(ResFinalVars.LINESINFO.LINE2.getValue());  
  104.                     break;  
  105.                 case 2:  
  106.                     graph[id].addLine(ResFinalVars.LINESINFO.LINE3.getValue());  
  107.                     break;  
  108.                 case 3:  
  109.                     graph[id].addLine(ResFinalVars.LINESINFO.LINE3.getValue());  
  110.                     break;  
  111.                 case 4:  
  112.                     graph[id].addLine(ResFinalVars.LINESINFO.LINE4.getValue());  
  113.                     break;  
  114.                 case 5:  
  115.                     graph[id].addLine(ResFinalVars.LINESINFO.LINE5.getValue());  
  116.                     break;  
  117.                 case 6:  
  118.                     graph[id].addLine(ResFinalVars.LINESINFO.LINE8.getValue());  
  119.                     break;  
  120.                 case 7:  
  121.                     graph[id].addLine(ResFinalVars.LINESINFO.LINEGF.getValue());  
  122.                     break;  
  123.                 }  
  124.             }  
  125.         }  
  126.           
  127.         // add transit station info  
  128.         for (i = 0; i < ResFinalVars.transit_stations.length; i++)  
  129.         {  
  130.             id = findIdByKey(ResFinalVars.transit_stations[i]);  
  131.             graph[id].setInfo(ResFinalVars.TRANSIT);  
  132.         }  
  133.     }  
  134.       
  135.  
  136.     /** table init */ 
  137.     public void initTable(){  
  138.         table = new TableEntry[this.getVertexNum()];  
  139.         for (int i = 0; i < table.length; i++)  
  140.         {  
  141.             table[i] = new TableEntry();  
  142.         }  
  143.     }  
  144.       
  145.  
  146.     /** table clear */ 
  147.     public void clearTable(){  
  148.         for (int i = 0; i < table.length; i++)  
  149.         {  
  150.             table[i].setKnown(false);  
  151.             table[i].setDist(ResFinalVars.INFINITE);  
  152.             table[i].setPath(ResFinalVars.UNKNOWN);  
  153.         }         
  154.     }  
  155.       
  156.     /** set begin vertex by id */ 
  157.     public boolean setBeginVertex(int id){  
  158.         clearTable();  
  159.         if (mHashTable1.containsKey(id) == true)  
  160.         {  
  161.             beginVertex = id;  
  162.             beginStation = findStrById(id);  
  163.             table[id].setDist(0);  
  164.             return true;  
  165.         }  
  166.         return false;  
  167.     }     
  168.       
  169.     /** set begin vertex by name */ 
  170.     public boolean setBeginVertex(String name){  
  171.         int id;       
  172.         clearTable();  
  173.         if (mHashTable2.containsKey(name) == true)  
  174.         {  
  175.             id = findIdByKey(name);  
  176.             beginVertex = id;  
  177.             beginStation = name;  
  178.             table[id].setDist(0);  
  179.             return true;  
  180.         }  
  181.         return false;                 
  182.     }  
  183.       
  184.     /** get begin vertex in id */ 
  185.     public int getBeginVertexId(){  
  186.         return beginVertex;  
  187.     }  
  188.       
  189.     /** get end vertex in name */ 
  190.     public String getBeginVertexName(){  
  191.         return beginStation;  
  192.     }  
  193.       
  194.     /** set end vertex by id */ 
  195.     public boolean setEndVertex(int id){  
  196.         if (mHashTable1.containsKey(id) == true)  
  197.         {  
  198.             endVertex = id;  
  199.             endStation = findStrById(id);  
  200.             return true;  
  201.         }  
  202.         return false;  
  203.     }  
  204.       
  205.     /** set end vertex by name */ 
  206.     public boolean setEndVertex(String name){  
  207.         if (mHashTable2.containsKey(name) == true)  
  208.         {             
  209.             endVertex = findIdByKey(name);  
  210.             endStation = name;  
  211.             return true;  
  212.         }  
  213.         return false;  
  214.     }  
  215.       
  216.     /** get end vertex in id */ 
  217.     public int getEndVertexId(){  
  218.         return endVertex;  
  219.     }  
  220.       
  221.     /** get end vertex in name */ 
  222.     public String getEndVertexName(){  
  223.         return endStation;  
  224.     }  
  225.       
  226.       
  227.     /** get Vertex number */ 
  228.     public int getVertexNum(){  
  229.         return vertexNum;  
  230.     }  
  231.       
  232.       
  233.     /** startSearch */ 
  234.     public void startSearch(){  
  235.         int currDist, v, w, i;  
  236.         for (currDist = 0; currDist < this.getVertexNum(); currDist++)  
  237.         {  
  238.             for (v = 0; v < this.getVertexNum(); v++)  
  239.             {  
  240.                 if ((table[v].getKnown() == false) && (table[v].getDist() == currDist))  
  241.                 {  
  242.                     table[v].setKnown(true);  
  243.                     for (i = 0; i < graph[v].size(); i++)  
  244.                     {  
  245.                         w = graph[v].getItem(i);  
  246.                         if (table[w].getDist() == ResFinalVars.INFINITE)  
  247.                         {  
  248.                             table[w].setDist(currDist + 1);  
  249.                             table[w].setPath(v);  
  250.                         }  
  251.                     }  
  252.                 }  
  253.             }  
  254.         }  
  255.     }  
  256.       
  257.       
  258.     /** find path */ 
  259.     public void findPath(int id){  
  260.         if (table[id].getDist() != 0)  
  261.         {  
  262.             findPath(table[id].getPath());  
  263.         }         
  264.         mPath.add(id);  
  265.     }  
  266.           
  267.     /** get line info */ 
  268.     public String getLineInfo(int index){  
  269.         String ret = "";  
  270.         switch(index)  
  271.         {  
  272.         case ResFinalVars.LINE1:  
  273.             ret += ResFinalVars.lines_number[0];  
  274.             break;  
  275.         case ResFinalVars.LINE2:  
  276.             ret += ResFinalVars.lines_number[1];  
  277.             break;  
  278.         case ResFinalVars.LINE3:  
  279.             ret += ResFinalVars.lines_number[2];  
  280.             break;  
  281.         case ResFinalVars.LINE4:  
  282.             ret += ResFinalVars.lines_number[3];  
  283.             break;  
  284.         case ResFinalVars.LINE5:  
  285.             ret += ResFinalVars.lines_number[4];  
  286.             break;  
  287.         case ResFinalVars.LINE8:  
  288.             ret += ResFinalVars.lines_number[7];  
  289.             break;  
  290.         case ResFinalVars.LINEGF:  
  291.             ret += ResFinalVars.lines_number[8];  
  292.             break;  
  293.         }  
  294.         return ret;  
  295.     }  
  296.       
  297.     /** process path */ 
  298.     public void makePathPrompt(){  
  299.         String ret = "最短路线: ", linenum = "";  
  300.         int i, id = beginVertex, previd, nextid, cnt = 0;  
  301.           
  302.         // clear path history  
  303.         mPath.clear();    
  304.           
  305.         // find the path   
  306.         findPath(this.getEndVertexId());  
  307.           
  308.         if(mPath.size() == 1// beginVertex == endVertex  
  309.         {  
  310.             ret = "您已经在 " + findStrById(id) + " 了, 无需乘坐地铁";  
  311.             mResult = ret;  
  312.             return ;  
  313.         }  
  314.               
  315.         for (i = 0; i < mPath.size(); i++)  
  316.         {  
  317.             id = mPath.get(i);                        
  318.             if (i == 0// id == beginVertex  
  319.             {                             
  320.                 nextid = mPath.get(i + 1);                
  321.                 linenum = getLineInfo(graph[id].getLine() & graph[nextid].getLine());  
  322.                 ret += "在 " + findStrById(id) + " 乘坐" + linenum;  
  323.             }  
  324.             else if (i == mPath.size() - 1// id == endVertex  
  325.             {  
  326.                 cnt++;  
  327.                 ret += "(坐" + cnt + "站)到 " + findStrById(id) + " 下车";  
  328.             }  
  329.             else if (graph[id].getInfo() == ResFinalVars.NORMAL)  
  330.             {  
  331.                 cnt++;  
  332.             }  
  333.             else if (graph[id].getInfo() == ResFinalVars.TRANSIT)  
  334.             {             
  335.                 cnt++;  
  336.                 if (i + 1 < mPath.size()) // make sure (i + 1) not overflow  
  337.                 {  
  338.                     previd = mPath.get(i - 1);  
  339.                     nextid = mPath.get(i + 1);  
  340.                     linenum = getLineInfo(graph[id].getLine() & graph[nextid].getLine());  
  341.                       
  342.                     if ((graph[previd].getLine() & graph[id].getLine()) != (graph[nextid].getLine() & graph[id].getLine()))  
  343.                     {  
  344.                         ret += "(坐" + cnt + "站)" + "到 " + findStrById(id) + " 换乘" + linenum;  
  345.                         cnt = 0;  
  346.                     }  
  347.                 }  
  348.             }  
  349.         }  
  350.           
  351.         mResult = ret;  
  352.     }  
  353.       
  354.       
  355.     /** get result */ 
  356.     public String getResult(){        
  357.         return mResult;  
  358.     }  

 

 

Activity类:

 
  
  1. public class MetroSearch extends Activity {  
  2.       
  3.     private Spinner mSpinnerBeginStation, mSpinnerEndStation;  
  4.     private ArrayAdapter<String> mAdapterStations;  
  5.     private TextView mTextView;  
  6.     private Button mSearch, mShowMap;     
  7.       
  8.     private PathSearch mPathSearch;  
  9.     private String mStationNames[];  
  10.     public int mBeginStation;  
  11.     public int mEndStation;  
  12.           
  13.       
  14.     public void doLineSearch(){  
  15.         String str;  
  16.         mPathSearch.setBeginVertex(mBeginStation);  
  17.         mPathSearch.setEndVertex(mEndStation);  
  18.         mPathSearch.startSearch();     
  19.         mPathSearch.makePathPrompt();  
  20.         str= mPathSearch.getResult();     
  21.         mTextView.setText(str);  
  22.     }  
  23.       
  24.     /** Called when the activity is first created. */ 
  25.     @Override 
  26.     public void onCreate(Bundle savedInstanceState) {  
  27.         super.onCreate(savedInstanceState);  
  28.         setContentView(R.layout.main);  
  29.           
  30.         mPathSearch = new PathSearch();   
  31.         mTextView = (TextView)findViewById(R.id.result);  
  32.           
  33.         mStationNames = new String[mPathSearch.getVertexNum()];  
  34.         for (int i = 0; i < mPathSearch.getVertexNum(); i++)  
  35.         {  
  36.             mStationNames[i] = mPathSearch.findStrById(i);  
  37.         }  
  38.           
  39.         mAdapterStations = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, mStationNames);  
  40.         mAdapterStations.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);  
  41.           
  42.         mSpinnerBeginStation = (Spinner)findViewById(R.id.station_from);  
  43.         mSpinnerBeginStation.setAdapter(mAdapterStations);  
  44.         mSpinnerEndStation = (Spinner)findViewById(R.id.station_to);  
  45.         mSpinnerEndStation.setAdapter(mAdapterStations);  
  46.           
  47.         /*  
  48.         class OnItemSelectedListenerBeginStation implements OnItemSelectedListener {  
  49.  
  50.             public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {  
  51.                 mBeginStation = pos;  
  52.             }  
  53.             public void onNothingSelected(AdapterView parent) {  
  54.               // Do nothing.  
  55.             }  
  56.         }  
  57.  
  58.         class OnItemSelectedListenerEndStation implements OnItemSelectedListener {  
  59.  
  60.             public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {  
  61.                 mEndStation = pos;                
  62.             }  
  63.             public void onNothingSelected(AdapterView parent) {  
  64.               // Do nothing.  
  65.             }  
  66.         }  
  67.           
  68.         mSpinnerBeginStation.setOnItemSelectedListener(new OnItemSelectedListenerBeginStation());  
  69.         mSpinnerEndStation.setOnItemSelectedListener(new OnItemSelectedListenerEndStation());  
  70.         */ 
  71.           
  72.         // this is the better code than that   
  73.         class OnSpinnerItemSelectedListener implements OnItemSelectedListener {  
  74.  
  75.             public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {  
  76.                 switch(parent.getId()) //attention: should not be view.getId()  
  77.                 {  
  78.                 case R.id.station_from:  
  79.                     mBeginStation = pos;  
  80.                     break;  
  81.                 case R.id.station_to:  
  82.                     mEndStation = pos;                    
  83.                     break;  
  84.                 default:  
  85.                     Log.d("xiaoben""view id not match");  
  86.                     break;  
  87.                 }  
  88.             }  
  89.             public void onNothingSelected(AdapterView parent) {  
  90.               // Do nothing.  
  91.             }  
  92.         }  
  93.         mSpinnerBeginStation.setOnItemSelectedListener(new OnSpinnerItemSelectedListener());  
  94.         mSpinnerEndStation.setOnItemSelectedListener(new OnSpinnerItemSelectedListener());  
  95.           
  96.           
  97.         /* button */          
  98.         mSearch = (Button) findViewById(R.id.search_btn);  
  99.         mSearch.setOnClickListener(new View.OnClickListener() {  
  100.             public void onClick(View v) {  
  101.                 // Perform action on click  
  102.                 doLineSearch();  
  103.             }  
  104.         });  
  105.           
  106.         mShowMap = (Button)findViewById(R.id.map_btn);  
  107.         mShowMap.setOnClickListener(new View.OnClickListener() {  
  108.               
  109.             @Override 
  110.             public void onClick(View v) {  
  111.                 // TODO Auto-generated method stub                            
  112.                 Intent intent = new Intent();  
  113.                 intent.setClass(MetroSearch.this, MapDisplay.class);  
  114.                 startActivity(intent);  
  115.             }  
  116.         });          
  117.     }