private static void InitNShortPath(ColumnFirstDynamicArray <ChainContent> apCost, int nValueKind) { m_apCost = apCost; //Set the cost m_nValueKind = nValueKind; //Set the value kind // 获取顶点的数目 // ----------------- 注:by zhenyulu ------------------ // 原来程序为m_nNode = Math.Max(apCost.ColumnCount, apCost.RowCount) + 1; // 但apCost.ColumnCount应该一定大于apCost.RowCount,所以改成这样。 m_nNode = apCost.ColumnCount + 1; m_pParent = new CQueue[m_nNode - 1][]; //not including the first node m_pWeight = new double[m_nNode - 1][]; //The queue array for every node for (int i = 0; i < m_nNode - 1; i++) { m_pParent[i] = new CQueue[nValueKind]; m_pWeight[i] = new double[nValueKind]; for (int j = 0; j < nValueKind; j++) { m_pParent[i][j] = new CQueue(); } } }
//==================================================================== // 将所有到当前结点(nCurNode)可能的边根据eWeight排序并压入队列 //==================================================================== private static void EnQueueCurNodeEdges(ref CQueue queWork, int nCurNode) { int nPreNode; double eWeight; ChainItem <ChainContent> pEdgeList; queWork.Clear(); pEdgeList = m_apCost.GetFirstElementOfCol(nCurNode); // Get all the edges while (pEdgeList != null && pEdgeList.col == nCurNode) { nPreNode = pEdgeList.row; // 很特别的命令,利用了row与col的关系 eWeight = pEdgeList.Content.eWeight; //Get the eWeight of edges for (int i = 0; i < m_nValueKind; i++) { // 第一个结点,没有PreNode,直接加入队列 if (nPreNode == 0) { queWork.EnQueue(new QueueElement(nPreNode, i, eWeight)); break; } // 如果PreNode的Weight == Predefine.INFINITE_VALUE,则没有必要继续下去了 if (m_pWeight[nPreNode - 1][i] == Predefine.INFINITE_VALUE) { break; } queWork.EnQueue(new QueueElement(nPreNode, i, eWeight + m_pWeight[nPreNode - 1][i])); } pEdgeList = pEdgeList.next; } }
//==================================================================== // 计算出所有结点上可能的路径,为路径数据提供数据准备 //==================================================================== public static void Calculate(ColumnFirstDynamicArray <ChainContent> apCost, int nValueKind) { InitNShortPath(apCost, nValueKind); QueueElement tmpElement; CQueue queWork = new CQueue(); double eWeight; for (int nCurNode = 1; nCurNode < m_nNode; nCurNode++) { // 将所有到当前结点(nCurNode)可能的边根据eWeight排序并压入队列 EnQueueCurNodeEdges(ref queWork, nCurNode); // 初始化当前结点所有边的eWeight值 for (int i = 0; i < m_nValueKind; i++) { m_pWeight[nCurNode - 1][i] = Predefine.INFINITE_VALUE; } // 将queWork中的内容装入m_pWeight与m_pParent tmpElement = queWork.DeQueue(); if (tmpElement != null) { for (int i = 0; i < m_nValueKind; i++) { eWeight = tmpElement.eWeight; m_pWeight[nCurNode - 1][i] = eWeight; do { m_pParent[nCurNode - 1][i].EnQueue(new QueueElement(tmpElement.nParent, tmpElement.nIndex, 0)); tmpElement = queWork.DeQueue(); if (tmpElement == null) { goto nextnode; } } while (tmpElement.eWeight == eWeight); } } nextnode :; } }
//==================================================================== // ��������н���Ͽ��ܵ�·����Ϊ·�������ṩ������ //==================================================================== public static void Calculate(ColumnFirstDynamicArray<ChainContent> apCost, int nValueKind) { InitNShortPath(apCost, nValueKind); QueueElement tmpElement; CQueue queWork = new CQueue(); double eWeight; for (int nCurNode = 1; nCurNode < m_nNode; nCurNode++) { // �����е���ǰ��㣨nCurNode)���ܵı߸���eWeight����ѹ����� EnQueueCurNodeEdges(ref queWork, nCurNode); // ��ʼ����ǰ������бߵ�eWeightֵ for (int i = 0; i < m_nValueKind; i++) m_pWeight[nCurNode - 1][i] = Predefine.INFINITE_VALUE; // ��queWork�е�����װ��m_pWeight��m_pParent tmpElement = queWork.DeQueue(); if (tmpElement != null) { for (int i = 0; i < m_nValueKind; i++) { eWeight = tmpElement.eWeight; m_pWeight[nCurNode - 1][i] = eWeight; do { m_pParent[nCurNode - 1][i].EnQueue(new QueueElement(tmpElement.nParent, tmpElement.nIndex, 0)); tmpElement = queWork.DeQueue(); if (tmpElement == null) goto nextnode; } while (tmpElement.eWeight == eWeight); } } nextnode: ; } }
private void InitNShortPath(ColumnFirstDynamicArray<ChainContent> apCost, int nValueKind) { m_apCost = apCost; //Set the cost m_nValueKind = nValueKind; //Set the value kind // 获取顶点的数目 // ----------------- 注:by zhenyulu ------------------ // 原来程序为m_nNode = Math.Max(apCost.ColumnCount, apCost.RowCount) + 1; // 但apCost.ColumnCount应该一定大于apCost.RowCount,所以改成这样。 m_nNode = apCost.ColumnCount + 1; m_pParent = new CQueue[m_nNode - 1][]; //not including the first node m_pWeight = new double[m_nNode - 1][]; //The queue array for every node for (int i = 0; i < m_nNode - 1; i++) { m_pParent[i] = new CQueue[nValueKind]; m_pWeight[i] = new double[nValueKind]; for (int j = 0; j < nValueKind; j++) m_pParent[i][j] = new CQueue(); } }
private static void InitNShortPath(ColumnFirstDynamicArray<ChainContent> apCost, int nValueKind) { m_apCost = apCost; //Set the cost m_nValueKind = nValueKind; //Set the value kind // ��ȡ�������Ŀ // ----------------- ע��by zhenyulu ------------------ // ԭ������Ϊm_nNode = Math.Max(apCost.ColumnCount, apCost.RowCount) + 1; // ��apCost.ColumnCountӦ��һ������apCost.RowCount�����Ըij������� m_nNode = apCost.ColumnCount + 1; m_pParent = new CQueue[m_nNode - 1][]; //not including the first node m_pWeight = new double[m_nNode - 1][]; //The queue array for every node for (int i = 0; i < m_nNode - 1; i++) { m_pParent[i] = new CQueue[nValueKind]; m_pWeight[i] = new double[nValueKind]; for (int j = 0; j < nValueKind; j++) m_pParent[i][j] = new CQueue(); } }
//==================================================================== // �����е���ǰ��㣨nCurNode�����ܵı߸���eWeight����ѹ����� //==================================================================== private static void EnQueueCurNodeEdges(ref CQueue queWork, int nCurNode) { int nPreNode; double eWeight; ChainItem<ChainContent> pEdgeList; queWork.Clear(); pEdgeList = m_apCost.GetFirstElementOfCol(nCurNode); // Get all the edges while (pEdgeList != null && pEdgeList.col == nCurNode) { nPreNode = pEdgeList.row; // ���ر�����������row��col�Ĺ�ϵ eWeight = pEdgeList.Content.eWeight; //Get the eWeight of edges for (int i = 0; i < m_nValueKind; i++) { // ��һ����㣬û��PreNode��ֱ�Ӽ������ if (nPreNode == 0) { queWork.EnQueue(new QueueElement(nPreNode, i, eWeight)); break; } // ���PreNode��Weight == Predefine.INFINITE_VALUE����û�б�Ҫ������ȥ�� if (m_pWeight[nPreNode - 1][i] == Predefine.INFINITE_VALUE) break; queWork.EnQueue(new QueueElement(nPreNode, i, eWeight + m_pWeight[nPreNode - 1][i])); } pEdgeList = pEdgeList.next; } }
//==================================================================== // 将所有到当前结点(nCurNode)可能的边根据eWeight排序并压入队列 //==================================================================== private void EnQueueCurNodeEdges(ref CQueue queWork, int nCurNode) { int nPreNode; double eWeight; ChainItem<ChainContent> pEdgeList; queWork.Clear(); pEdgeList = m_apCost.GetFirstElementOfCol(nCurNode); // Get all the edges while (pEdgeList != null && pEdgeList.col == nCurNode) { nPreNode = pEdgeList.row; // 很特别的命令,利用了row与col的关系 eWeight = pEdgeList.Content.eWeight; //Get the eWeight of edges for (int i = 0; i < m_nValueKind; i++) { // 第一个结点,没有PreNode,直接加入队列 if (nPreNode == 0) { queWork.EnQueue(new QueueElement(nPreNode, i, eWeight)); break; } // 如果PreNode的Weight == Predefine.INFINITE_VALUE,则没有必要继续下去了 if (m_pWeight[nPreNode - 1][i] == Predefine.INFINITE_VALUE) break; queWork.EnQueue(new QueueElement(nPreNode, i, eWeight + m_pWeight[nPreNode - 1][i])); } pEdgeList = pEdgeList.next; } }
//==================================================================== // 计算出所有结点上可能的路径,为路径数据提供数据准备 //==================================================================== public void Calculate(ColumnFirstDynamicArray<ChainContent> apCost, int nValueKind) { InitNShortPath(apCost, nValueKind); QueueElement tmpElement; CQueue queWork = new CQueue(); double eWeight; for (int nCurNode = 1; nCurNode < m_nNode; nCurNode++) { // 将所有到当前结点(nCurNode)可能的边根据eWeight排序并压入队列 EnQueueCurNodeEdges(ref queWork, nCurNode); // 初始化当前结点所有边的eWeight值 for (int i = 0; i < m_nValueKind; i++) m_pWeight[nCurNode - 1][i] = Predefine.INFINITE_VALUE; // 将queWork中的内容装入m_pWeight与m_pParent tmpElement = queWork.DeQueue(); if (tmpElement != null) { for (int i = 0; i < m_nValueKind; i++) { eWeight = tmpElement.eWeight; m_pWeight[nCurNode - 1][i] = eWeight; do { m_pParent[nCurNode - 1][i].EnQueue(new QueueElement(tmpElement.nParent, tmpElement.nIndex, 0)); tmpElement = queWork.DeQueue(); if (tmpElement == null) goto nextnode; } while (tmpElement.eWeight == eWeight); } } nextnode: ; } }