internal Edge[] GetRuralChinesePostmanTour() { // Win.HiPerfTimer pt = new Win.HiPerfTimer(); // create a new PerfTimer object //pt.Start(); if (this.MustEdges == null) { return(null); } if (theTour != null) { return(theTour); } int [,] dist = new int[neg.Length, pos.Length]; //dist[i,j] will be the distance from neg[i] to pos[j] int maxdist = 0; calcDistances(dist, ref maxdist); //construct the weight matrix for matching int [,] w = new int[neg.Length, pos.Length]; for (int i = 0; i < neg.Length; i++) { for (int j = 0; j < pos.Length; j++) { w[i, j] = maxdist - dist[i, j]; } } WeightedCompleteBipartiteMatching wb = new WeightedCompleteBipartiteMatching(w, flatNeg, flatPos); wb.stages(); //now the matching is calculated and we can create a balanced graph //for(int i=0;i<D;i++) // f[neg[wm.M[i]],pos[i]]++; //create an array of links for a balanced graph Edge[] links = new Edge[mustEdges.Length + D]; mustEdges.CopyTo(links, D); for (int i = 0; i < D; i++) { int negi = neg[flatNeg[wb.M[i]]]; int posi = pos[flatPos[i]]; links[i] = new Edge(negi, posi, adjoinedPathLabel); //don't care about weight } EulerianTour et = new EulerianTour(initialVertex, links, n); Edge[] etour = et.GetTour(); ArrayList al = new ArrayList(); //Expands adjoined path paths //Also calculates the maximal length adjoined path leading to the initial node: //will throw this path away in the GetRuralChinesePostmanPath() int maxIndexOfInitialVertexInAdjoinedPaths = -1; int pathToCut = 0; foreach (Edge l in etour) { if (l.label != adjoinedPathLabel) { al.Add(l); } else { int pathLen = dist[nodeToNeg[l.source], nodeToPos[l.target]]; SingleSourceSingleTargetUpperDistSP dm = new SingleSourceSingleTargetUpperDistSP(this, l.source, l.target, pathLen); Edge [] path = dm.GetPath(); al.AddRange(path); int indexOfInitVertex = IndexOfVertexInPath(path, initialVertex); if (indexOfInitVertex > maxIndexOfInitialVertexInAdjoinedPaths) { maxIndexOfInitialVertexInAdjoinedPaths = indexOfInitVertex; pathStart = al.Count - path.Length + indexOfInitVertex; pathToCut = indexOfInitVertex; } } } theTour = new Edge[al.Count]; al.CopyTo(theTour); if (pathStart != Graph.NONE) { this.pathLength = theTour.Length - pathToCut; } //pt.Stop(); //System.Windows.Forms.MessageBox.Show(pt.Duration.ToString()); return(theTour); }
internal Edge[] GetRuralChinesePostmanTour() { // Win.HiPerfTimer pt = new Win.HiPerfTimer(); // create a new PerfTimer object //pt.Start(); if(this.MustEdges==null) { return null; } if(theTour != null) return theTour; int [,]dist=new int[neg.Length,pos.Length]; //dist[i,j] will be the distance from neg[i] to pos[j] int maxdist=0; calcDistances(dist,ref maxdist); //construct the weight matrix for matching int [,]w=new int[neg.Length,pos.Length]; for(int i=0;i<neg.Length;i++) for(int j=0;j<pos.Length;j++) w[i,j]=maxdist-dist[i,j]; WeightedCompleteBipartiteMatching wb=new WeightedCompleteBipartiteMatching(w,flatNeg,flatPos); wb.stages(); //now the matching is calculated and we can create a balanced graph //for(int i=0;i<D;i++) // f[neg[wm.M[i]],pos[i]]++; //create an array of links for a balanced graph Edge[] links=new Edge[ mustEdges.Length+D]; mustEdges.CopyTo(links,D); for(int i=0;i<D;i++) { int negi=neg[flatNeg[wb.M[i]]]; int posi=pos[flatPos[i]]; links[i]=new Edge(negi,posi,adjoinedPathLabel); //don't care about weight } EulerianTour et=new EulerianTour(initialVertex,links,n); Edge[] etour=et.GetTour(); ArrayList al=new ArrayList(); //Expands adjoined path paths //Also calculates the maximal length adjoined path leading to the initial node: //will throw this path away in the GetRuralChinesePostmanPath() int maxIndexOfInitialVertexInAdjoinedPaths=-1; int pathToCut=0; foreach(Edge l in etour) { if(l.label!=adjoinedPathLabel) al.Add(l); else { int pathLen=dist[nodeToNeg[l.source],nodeToPos[l.target]]; SingleSourceSingleTargetUpperDistSP dm= new SingleSourceSingleTargetUpperDistSP(this,l.source,l.target,pathLen); Edge []path=dm.GetPath(); al.AddRange(path); int indexOfInitVertex=IndexOfVertexInPath(path,initialVertex); if(indexOfInitVertex>maxIndexOfInitialVertexInAdjoinedPaths) { maxIndexOfInitialVertexInAdjoinedPaths=indexOfInitVertex; pathStart=al.Count-path.Length+indexOfInitVertex; pathToCut=indexOfInitVertex; } } } theTour=new Edge[al.Count]; al.CopyTo(theTour); if(pathStart!=Graph.NONE) this.pathLength=theTour.Length-pathToCut; //pt.Stop(); //System.Windows.Forms.MessageBox.Show(pt.Duration.ToString()); return theTour; }