/************************ findCriticalPath ************************************* void findCriticalPath(Graph g, int iVertex, char* szCriticalPath, int iPathIndex) Purpose: This function finds and prints (with the help of the function printCriticalPaths) the critical path(s) for the graph, using the previously calculated TE and TL for each vertex. Parameters: I Graph g The graph to print the critical path from. I int iVertex The index for the current vertex the function is working on. I/O char* szCriticalPath The string variable holding the critical path in progress. I int iPathIndex The current index in the szCriticalPath string where the next vertex should be inserted. Returns: szCriticalPath parm - the critical path in progress. Notes: This function is recursive. *******************************************************************************/ void findCriticalPath(Graph g, int iVertex, char* szCriticalPath, int iPathIndex) { if (g->vertexM[iVertex].iMaxFromSource == g->vertexM[iVertex].iTL) //if the current vertex is part of a critical path { //add the label for the current vertex to the critical path string szCriticalPath[iPathIndex] = g->vertexM[iVertex].cLabel; //followed by a space szCriticalPath[iPathIndex + 1] = ' '; //set p to point to the first successor EdgeNode* p = g->vertexM[iVertex].successorList; if (p == NULL) //if the current vertex is a sink { szCriticalPath[iPathIndex + 2] = '\0'; //end the criticalpath string printf("%s\n", szCriticalPath); //print it } while (p != NULL) //go through each successor { findCriticalPath(g, p->edge.iVertex, szCriticalPath, iPathIndex + 2); //find the next points on the critical path p = p->pNextEdge; //next successor } } }
void NeighbourGenerator::findCriticalPath(Node* node,Node* leaf,vector<Node*>& bottleneck,vector<Node*>& criticalPath,int length){ if(node==leaf){ criticalPath.push_back(leaf); if(m_CriticalPathList.second<length){ m_CriticalPathList=pair<vector<Node*>,int>(criticalPath,length); } return; } for(int i=0;i<node->m_Next.size();i++){ vector<Node*> _criticalPath=criticalPath; for(int j=0;j<bottleneck.size();j++){ if(node->m_Next[i]->m_Jobpair->index==bottleneck[j]->m_Jobpair->index){ _criticalPath.push_back(node); findCriticalPath(node->m_Next[i],leaf,bottleneck,_criticalPath,length+node->m_Jobpair->time); break; } } } }
/*************************** printCriticalPaths ******************************** void printCriticalPaths(Graph g) Purpose: This function finds and prints (with the help of the function findCriticalPath) the critical path(s) for the graph, using the previously calculated TE and TL for each vertex. Parameters: I Graph g The graph to print the critical path from. Returns: Notes: *******************************************************************************/ void printCriticalPaths(Graph g) { char szCriticalPath[MAX_EDGES]; int i; //header for the critical path(s) printf("Critical Path(s)\n"); //for each vertex for (i = 0; i < g->iNumVertices; i++) { if (g->vertexM[i].predecessorList == NULL && g->vertexM[i].iMaxFromSource == g->vertexM[i].iTL) //if current vertex is a source and is part of a critical path { findCriticalPath(g, i, szCriticalPath, 0); //start the recursive search for more points in the critical path //starting with the current vertex as the source } } }
void NeighbourGenerator::makeNeighbour(){ vector<Node*> bottleneck; Graph g(m_solution,m_SettingTable); g.setLongestPath(); int L=g.getMakespan(); for(int i=0;i<g.size();i++){ if(g[i]->m_R+g[i]->m_Q-g[i]->m_Jobpair->time==L){ bottleneck.push_back(g[i]); } } m_CriticalPathList=pair<vector<Node*>,int>(vector<Node*>(),-1); vector<Node*> criticalPath; findCriticalPath(g[0],g[g.size()-1],bottleneck,criticalPath,0); criticalPath.clear(); criticalPath=m_CriticalPathList.first; for(int j=0;j<criticalPath.size()-1;j++){ for(int k=j+1;k<criticalPath.size()-1;k++){ if(criticalPath[j]->m_Jobpair->machine!= criticalPath[k]->m_Jobpair->machine) continue; JobPair *I=criticalPath[j]->m_Jobpair; JobPair *J=criticalPath[k]->m_Jobpair; JobPair *alphaI=findJobFromSetting(I,PREV); JobPair *gammaI=findJobFromSetting(I,NEXT); JobPair *alphaJ=findJobFromSetting(J,PREV); JobPair *gammaJ=findJobFromSetting(J,NEXT); for(int l=0;l<criticalPath.size();l++){ // gammaJがCriticalPathに含まれていればforwardchangeする if(gammaJ!=NULL && gammaI!=NULL && gammaJ->index==criticalPath[l]->m_Jobpair->index && g.getNodeByIndex(J->index)->m_Q-J->time>=g.getNodeByIndex(gammaI->index)->m_Q-gammaI->time){ vector<vector<JobPair> > forwardSolution; forwardSolution=changeForward(m_solution,criticalPath[j]->m_Jobpair,criticalPath[k]->m_Jobpair); m_NeighbourList.push_back(forwardSolution); Graph forward(forwardSolution,m_SettingTable); forward.setLongestPath(); if(g.getMakespan()>forward.getMakespan()){ }else{ if(forward.getNodeByIndex(J->index)->m_R-J->time<=g.getNodeByIndex(J->index)->m_R-J->time-I->time){ } if(forward.getNodeByIndex(J->index)->m_Q<=g.getNodeByIndex(J->index)->m_Q+I->time){ } } } // alphaIがCriticalPathに含まれていればbackwardchangeする if(alphaI!=NULL && alphaJ!=NULL && alphaI->index==criticalPath[l]->m_Jobpair->index && g.getNodeByIndex(I->index)->m_R>=g.getNodeByIndex(alphaJ->index)->m_R){ vector<vector<JobPair> > backwardSolution; backwardSolution=changeBackward(m_solution,criticalPath[j]->m_Jobpair,criticalPath[k]->m_Jobpair); m_NeighbourList.push_back(backwardSolution); Graph backward(backwardSolution,m_SettingTable); backward.setLongestPath(); if(g.getMakespan()>backward.getMakespan()){ }else{ if(backward.getNodeByIndex(I->index)->m_Q<=g.getNodeByIndex(I->index)->m_Q-J->time){ } if(backward.getNodeByIndex(I->index)->m_R-I->time<=g.getNodeByIndex(I->index)->m_R-I->time+J->time){ } } } } } } }