Exemple #1
0
        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);
        }
Exemple #2
0
        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;
        }