bool EdgeColoringTest<DefaultStructs>::test(const Graph &graph, const ColorMap &colors) { typedef typename Graph::PVertex Vert; typedef typename Graph::PEdge Edge; const EdgeDirection Mask = EdDirIn|EdDirOut|EdUndir; int degree = graph.Delta(Mask); int LOCALARRAY(kolory, degree+1); int lenKolory = 0; for(Vert vv = graph.getVert(); vv; vv = graph.getVertNext(vv)) { lenKolory = 0; for(Edge ee = graph.getEdge(vv, Mask); ee; ee = graph.getEdgeNext(vv, ee, Mask)) { if(!colors.hasKey(ee)) return false; int col = colors[ee]; if(col<0) return false; kolory[lenKolory++] = col; } DefaultStructs::sort(kolory, kolory+lenKolory); int tmpLen = std::unique(kolory, kolory+lenKolory)-kolory; if(tmpLen!=lenKolory) return false; } return true; }
int SeqEdgeColoringPar<DefaultStructs>::greedy(const Graph &graph, ColorMap &colors, typename Graph::PEdge edge) { if(colors.hasKey(edge) && colors[edge]>=0) return -1; typedef typename Graph::PVertex Vert; typedef typename Graph::PEdge Edge; const EdgeDirection Mask = EdDirIn|EdDirOut|EdUndir; Vert v1 = graph.getEdgeEnd1(edge); Vert v2 = graph.getEdgeEnd2(edge); int deg = graph.deg(v1, Mask)+graph.deg(v2, Mask); bool LOCALARRAY(neighCol, deg); for(int i = 0; i < deg; i++) neighCol[i] = false; for(Edge ee = graph.getEdge(v1, Mask); ee; ee = graph.getEdgeNext(v1, ee, Mask)) { if(!colors.hasKey(ee)) continue; int col = colors[ee]; if(col>=0 && col<deg) neighCol[ col ] = true; } for(Edge ee = graph.getEdge(v2, Mask); ee; ee = graph.getEdgeNext(v2, ee, Mask)) { if(!colors.hasKey(ee)) continue; int col = colors[ee]; if(col>=0 && col<deg) neighCol[ col ] = true; } int col = 0; while( neighCol[col] ) col++; return colors[ edge ] = col; }
int EdgeColoringTest<DefaultStructs>::maxColor(const Graph &graph, const ColorMap &colors) { typedef typename Graph::PEdge Edge; const EdgeDirection Mask = EdDirIn|EdDirOut|EdUndir; int col = -1; for(Edge ee = graph.getEdge(Mask); ee; ee = graph.getEdgeNext(ee, Mask) ) { if(!colors.hasKey(ee)) continue; int tmp = colors[ee]; if(tmp>col) col = tmp; } return col; }
int SeqEdgeColoringPar<DefaultStructs>::vizing(const Graph &graph, ColorMap &colors, typename Graph::PEdge edge, typename Graph::PVertex vert, int maxCol) { if(colors.hasKey(edge)&&colors[edge]>=0) return -1; typedef typename Graph::PVertex Vert; typedef typename Graph::PEdge Edge; const EdgeDirection Mask = EdDirIn|EdDirOut|EdUndir; int degree = graph.Delta(Mask); int mu = makeSubgraph(graph, std::make_pair(stdChoose(true), !edgeTypeChoose(Loop))).mu(); VizingState<Graph, ColorMap> vState(graph, colors, degree+mu); vState.maxColor = maxCol; //edge coloring vizing(vState, edge, vert); return colors[edge]; }
int SeqEdgeColoringPar<DefaultStructs>::vizingSimple(const Graph &graph, ColorMap &colors) { typedef typename Graph::PVertex Vert; typedef typename Graph::PEdge Edge; const EdgeDirection Mask = EdDirIn|EdDirOut|EdUndir; colors.reserve(graph.getEdgeNo(EdDirIn|EdDirOut|EdUndir)); int degree = graph.Delta(Mask); VizingState<Graph, ColorMap> vState(graph, colors, degree+1); int LOCALARRAY(tmpTab, vState.notColored); //tmpTab - is used for checking free color availability if(colors.size()>0) { //for each vertex checks the free color availability (freeColor) for(Vert vv = graph.getVert(); vv; vv = graph.getVertNext(vv)) { for(int i=0; i<vState.notColored; i++) tmpTab[i] = 0; for(Edge ee=graph.getEdge(vv, Mask); ee; ee = graph.getEdgeNext(vv, ee, Mask)) { if(!colors.hasKey(ee)) continue; int tmpCol = colors[ee]; if(tmpCol<0 || tmpCol>=vState.notColored) continue; tmpTab[ tmpCol ] = 1; } int i=0; while(i<vState.notColored && tmpTab[i]==1) i++; vState.tabVert[ vState.vertToTab[vv] ].freeColor = i; } } //init edges by degree colors int ii; for(Edge edge = graph.getEdge(Mask); edge; edge = graph.getEdgeNext(edge, Mask)) { if(colors.hasKey(edge)&&colors[edge]>=0) continue; Vert vert1 = graph.getEdgeEnd1(edge); Vert vert2 = graph.getEdgeEnd2(edge); for(int i=0; i<degree; i++) tmpTab[i] = 0; for(Edge ee = graph.getEdge(vert1, Mask); ee; ee = graph.getEdgeNext(vert1, ee, Mask)) { if(!colors.hasKey(ee)) continue; int tmpCol = colors[ee]; if(tmpCol<0 || tmpCol>=vState.notColored) continue; tmpTab[ tmpCol ] = 1; } for(Edge ee=graph.getEdge(vert2, Mask); ee; ee=graph.getEdgeNext(vert2, ee, Mask)) { if(!colors.hasKey(ee)) continue; int tmpCol = colors[ee]; if(tmpCol<0 || tmpCol>=vState.notColored) continue; tmpTab[ tmpCol ] |= 2; } for(int i=0; i<degree; i++) { if(tmpTab[i]!=0) continue; colors[edge] = i; vState.changeColor(edge, vState.notColored, i); tmpTab[i] = 3; // 3=1|2 if(i > vState.maxColor) vState.maxColor = i; break; } //setting free colors at vertices for(ii=0; ii<degree; ii++) if((tmpTab[ii]&1)==0) break; int id = vState.vertToTab[vert1]; vState.tabVert[id].freeColor = ii; for(ii=0; ii<degree; ii++) if((tmpTab[ii]&2)==0) break; id = vState.vertToTab[vert2]; vState.tabVert[id].freeColor = ii; } //edge coloring int idFree; while( (idFree=vState.colorToList[vState.notColored])>0 ) { Edge ee = vState.listEdgeCol[idFree].edge; vizingSimple(vState, ee, ee->getEnd1()); } return vState.maxColor; }
int SeqEdgeColoringPar<DefaultStructs>::colorInterchange(const Graph &graph, ColorMap &colors, typename Graph::PEdge edge) { typedef typename Graph::PVertex Vert; typedef typename Graph::PEdge Edge; const EdgeDirection Mask = EdDirIn|EdDirOut|EdUndir; int oldColor = colors[ edge ]; //oldColor is maximal color in the graph colors.delKey( edge ); Vert vert1 = graph.getEdgeEnd1(edge); Vert vert2 = graph.getEdgeEnd2(edge); int deg = graph.deg(vert1, Mask) + graph.deg(vert2, Mask); char LOCALARRAY(matchedColors, deg); for(int i=0; i<deg; i++) matchedColors[i] = 0; for(Edge ee = graph.getEdge(vert1, Mask); ee; ee = graph.getEdgeNext(vert1, ee, Mask)) { if(!colors.hasKey(ee)) continue; int col = colors[ee]; if(col<0 || col>=deg) continue; matchedColors[col] |= 1; } for(Edge ee = graph.getEdge(vert2, Mask); ee; ee = graph.getEdgeNext(vert2, ee, Mask)) { if(!colors.hasKey(ee)) continue; int col = colors[ee]; if(col<0 || col>=deg) continue; matchedColors[col] |= 2; } VizingState<Graph, ColorMap> vState(graph, colors, oldColor); int idVert1 = vState.vertToTab[vert1]; int idVert2 = vState.vertToTab[vert2]; for(int c1 = 0; c1<oldColor; c1++) { for(int c2 = c1+1; c2<oldColor; c2++) { if((matchedColors[c1]&1)!=0 && (matchedColors[c2]&1)!=0) continue; if((matchedColors[c1]&2)!=0 && (matchedColors[c2]&2)!=0) continue; int begPath, endPath, colPath; if((matchedColors[c1]&1)!=0) { begPath = idVert1; endPath = idVert2; colPath = c1; } else if((matchedColors[c2]&1)!=0) { begPath = idVert1; endPath = idVert2; colPath = c2; } else if((matchedColors[c1]&2)!=0) { begPath = idVert2; endPath = idVert1; colPath = c1; } else if((matchedColors[c2]&2)!=0) { begPath = idVert2; endPath = idVert1; colPath = c2; } vState.subgraph(c1, c2); if(vState.altPathWalk(begPath, colPath)==endPath) continue; vState.altPathRecoloring(begPath, colPath); colors[edge] = colPath; return colPath; } } return colors[edge] = oldColor; //recoloring failed }