NShortPath.cpp
上传用户:chen_dj
上传日期:2013-04-22
资源大小:111k
文件大小:7k
源码类别:

多国语言处理

开发平台:

C/C++

  1. /****************************************************************************
  2.  *
  3.  * Copyright (c) 2000, 2001 
  4.  *     Software Research Lab.
  5.  *     Institute of Computing Tech.
  6.  *     Chinese Academy of Sciences
  7.  *     All rights reserved.
  8.  *
  9.  * This file is the confidential and proprietary property of 
  10.  * Institute of Computing Tech. and the posession or use of this file requires 
  11.  * a written license from the author.
  12.  *
  13.  * Abstract:
  14.  *      N-Shortest Path Problem for graph in word segement
  15.  *
  16.  * Author: Kevin Chang (zhanghp@software.ict.ac.cn)
  17.  *
  18.  * Notes:
  19.  *
  20.  ****************************************************************************/
  21. // NShortPath.cpp: implementation of the CNShortPath class.
  22. //
  23. //////////////////////////////////////////////////////////////////////
  24. #include "stdafx.h"
  25. #include "NShortPath.h"
  26. #include "Segment.h"
  27. #include <memory.h>
  28. #include <string.h>
  29. //#include <stdlib.h>
  30. //////////////////////////////////////////////////////////////////////
  31. // Construction/Destruction
  32. //////////////////////////////////////////////////////////////////////
  33. CNShortPath::CNShortPath(CDynamicArray *apCost,unsigned int nValueKind)
  34. {
  35.        m_apCost=apCost;//Set the cost
  36.    m_nValueKind=nValueKind;//Set the value kind
  37.    m_nVertex=apCost->m_nCol+1;
  38.        if(m_nVertex<apCost->m_nRow+1)
  39.    m_nVertex=apCost->m_nRow+1;//Get the vertex numbers
  40.    m_pParent=new CQueue*[m_nVertex-1];//not including the first node
  41.    m_pWeight=new ELEMENT_TYPE *[m_nVertex-1];
  42. //    m_pParent=(CQueue **)malloc((m_nVertex-1)*sizeof(CQueue *));//not including the first node
  43. //    m_pWeight=(ELEMENT_TYPE **)malloc(sizeof(ELEMENT_TYPE *)*(m_nVertex-1));
  44. for(unsigned int i=0;i<m_nVertex-1;i++)//The queue array for every node
  45. {
  46. m_pParent[i]=new CQueue[nValueKind];
  47. m_pWeight[i]=new ELEMENT_TYPE[nValueKind];
  48. // m_pParent[i]=(CQueue *)malloc(sizeof(CQueue)*nValueKind);
  49. // m_pWeight[i]=(ELEMENT_TYPE *)malloc(sizeof(ELEMENT_TYPE)*nValueKind);
  50. }
  51. }
  52. CNShortPath::~CNShortPath()
  53. {
  54.  for(unsigned int i=0;i<m_nVertex-1;i++)//The queue array for every node
  55.  {
  56.  delete [] m_pWeight[i];
  57. //  free(m_pWeight[i]);
  58. /*  for(unsigned int j=0;j<m_nValueKind;j++)
  59.  {
  60.  m_pParent[i][j].~CQueue();//;delete 
  61.  }*/
  62. //  free(m_pParent[i]);
  63.          delete [] m_pParent[i];
  64.  }
  65.  delete [] m_pWeight;
  66.  delete [] m_pParent;//not including the first node
  67. //  free(m_pWeight);
  68. //  free(m_pParent);
  69. }
  70. int CNShortPath::ShortPath()
  71. {
  72. unsigned int nCurNode=1,nPreNode,i,nIndex;
  73. ELEMENT_TYPE eWeight;
  74. PARRAY_CHAIN pEdgeList;
  75.     for(;nCurNode<m_nVertex;nCurNode++)
  76. {
  77.    CQueue queWork;
  78.    eWeight=m_apCost->GetElement(-1,nCurNode,0,&pEdgeList);//Get all the edges
  79.        while(pEdgeList!=0 && pEdgeList->col==nCurNode)
  80.    {
  81.    nPreNode=pEdgeList->row;
  82.    eWeight=pEdgeList->value;//Get the value of edges
  83.            for(i=0;i<m_nValueKind;i++)
  84.    {
  85.    if(nPreNode>0)//Push the weight and the pre node infomation
  86.    {
  87.    if(m_pWeight[nPreNode-1][i]==INFINITE_VALUE)
  88.    break;
  89.            queWork.Push(nPreNode,i,eWeight+m_pWeight[nPreNode-1][i]);
  90.    }
  91.    else
  92.    {
  93.    queWork.Push(nPreNode,i,eWeight);
  94.    break;
  95.    }
  96.    }//end for
  97.            pEdgeList=pEdgeList->next;
  98.    
  99.    }//end while
  100.        
  101.    //Now get the result queue which sort as weight.
  102.    //Set the current node information
  103.    for(i=0;i<m_nValueKind;i++)
  104.    {
  105. m_pWeight[nCurNode-1][i]=INFINITE_VALUE;
  106.    }
  107.    //memset((void *),(int),sizeof(ELEMENT_TYPE)*);
  108.        //init the weight
  109.    i=0;    
  110.        while(i<m_nValueKind&&queWork.Pop(&nPreNode,&nIndex,&eWeight)!=-1)
  111.    {//Set the current node weight and parent
  112.    if(m_pWeight[nCurNode-1][i]==INFINITE_VALUE)
  113.    m_pWeight[nCurNode-1][i]=eWeight;
  114.    else if(m_pWeight[nCurNode-1][i]<eWeight)//Next queue
  115.    {
  116.    i++;//Go next queue and record next weight
  117.    if(i==m_nValueKind)//Get the last position
  118.    break;
  119.    m_pWeight[nCurNode-1][i]=eWeight;
  120.    }
  121.            m_pParent[nCurNode-1][i].Push(nPreNode,nIndex);
  122.    }
  123. }//end for
  124. return 1;
  125. }
  126. //bBest=true: only get one best result and ignore others
  127. //Added in 2002-1-24
  128. void CNShortPath::GetPaths(unsigned int nNode,unsigned int nIndex,int **nResult,bool bBest)
  129. {
  130.     CQueue queResult;
  131. unsigned int nCurNode,nCurIndex,nParentNode,nParentIndex,nResultIndex=0;
  132.     
  133. if(m_nResultCount>=MAX_SEGMENT_NUM)//Only need 10 result
  134. return ;
  135. nResult[m_nResultCount][nResultIndex]=-1;//Init the result 
  136. queResult.Push(nNode,nIndex);
  137.     nCurNode=nNode;
  138. nCurIndex=nIndex;
  139.     bool bFirstGet;
  140.     while(!queResult.IsEmpty())
  141. {
  142. while(nCurNode>0)//
  143. {//Get its parent and store them in nParentNode,nParentIndex
  144. if(m_pParent[nCurNode-1][nCurIndex].Pop(&nParentNode,&nParentIndex,0,false,true)!=-1)
  145. {
  146.    nCurNode=nParentNode;
  147.    nCurIndex=nParentIndex;
  148. }
  149. if(nCurNode>0)
  150.                 queResult.Push(nCurNode,nCurIndex);
  151. }
  152. if(nCurNode==0)
  153. { //Get a path and output
  154.       nResult[m_nResultCount][nResultIndex++]=nCurNode;//Get the first node
  155.    bFirstGet=true;
  156.    nParentNode=nCurNode;
  157.    while(queResult.Pop(&nCurNode,&nCurIndex,0,false,bFirstGet)!=-1)
  158.    {
  159.    nResult[m_nResultCount][nResultIndex++]=nCurNode;
  160.             bFirstGet=false;
  161.    nParentNode=nCurNode;
  162.    }
  163.    nResult[m_nResultCount][nResultIndex]=-1;//Set the end
  164.    m_nResultCount+=1;//The number of result add by 1
  165.    if(m_nResultCount>=MAX_SEGMENT_NUM)//Only need 10 result
  166. return ;
  167.    nResultIndex=0;
  168.    nResult[m_nResultCount][nResultIndex]=-1;//Init the result 
  169.    if(bBest)//Return the best result, ignore others
  170.    return ;
  171. }
  172. queResult.Pop(&nCurNode,&nCurIndex,0,false,true);//Read the top node
  173.         while(queResult.IsEmpty()==false&&(m_pParent[nCurNode-1][nCurIndex].IsSingle()||m_pParent[nCurNode-1][nCurIndex].IsEmpty(true)))
  174. {
  175.        queResult.Pop(&nCurNode,&nCurIndex,0);//Get rid of it
  176.    queResult.Pop(&nCurNode,&nCurIndex,0,false,true);//Read the top node
  177. }
  178.         if(queResult.IsEmpty()==false&&m_pParent[nCurNode-1][nCurIndex].IsEmpty(true)==false)
  179. {
  180.    m_pParent[nCurNode-1][nCurIndex].Pop(&nParentNode,&nParentIndex,0,false,false);
  181.    nCurNode=nParentNode;
  182.    nCurIndex=nParentIndex;
  183.    if(nCurNode>0)
  184.        queResult.Push(nCurNode,nCurIndex);
  185. }
  186. }
  187. }
  188. int CNShortPath::Output(int **nResult,bool bBest,int *npCount)
  189. {//sResult is a string array
  190.   unsigned int i;
  191.   
  192.   m_nResultCount=0;//The 
  193.   if(m_nVertex<2)
  194.   {
  195.   nResult[0][0]=0;
  196.   nResult[0][1]=1;
  197.   *npCount=1;
  198.   return 1;
  199.   }
  200.   for(i=0;i<m_nValueKind&&m_pWeight[m_nVertex-2][i]<INFINITE_VALUE;i++)
  201.   {
  202.   GetPaths(m_nVertex-1,i,nResult,bBest);
  203.   *npCount=m_nResultCount;
  204.   if(nResult[i][0]!=-1&&bBest)//Get the best answer
  205.   return 1;
  206.       if(m_nResultCount>=MAX_SEGMENT_NUM)//Only need 10 result
  207.     return 1;
  208.   }
  209.   return 1;
  210. }