Esempio n. 1
0
        public CityCluster(List<CityNodeData> Cities, List<CityNodeData> AllCities, CostMatrix costMatrix)
        {
            _containedCities = new List<CityNodeData>(Cities);
            _allCities = new List<CityNodeData>(AllCities);
            _costMatrix = costMatrix;

            _cityEntryPoint = -1;
            _cityExitPoint = -1;

            _incomingEdgesSortedByDistance = new List<int>();
            _outgoingEdgesSortedByDistance = new List<int>();
            _incomingEdgesByCitySortedByDistance = new Dictionary<int, List<int>>();
            _outgoingEdgesByCitySortedByDistance = new Dictionary<int, List<int>>();

            foreach (CityNodeData innerCity in _containedCities)
            {
                int innerCityId = innerCity.CityId;

                foreach (CityNodeData outerCity in AllCities)
                {
                    if (!_containedCities.Contains(outerCity))
                    {
                        int outerCityId = outerCity.CityId;
                        if (!_incomingEdgesByCitySortedByDistance.ContainsKey(outerCityId))
                        {
                            _incomingEdgesByCitySortedByDistance.Add(outerCityId, new List<int>());
                        }
                        if (!_outgoingEdgesByCitySortedByDistance.ContainsKey(outerCityId))
                        {
                            _outgoingEdgesByCitySortedByDistance.Add(outerCityId, new List<int>());
                        }
                        int incomingId = costMatrix.EdgeId(outerCityId, innerCityId);
                        int outgoingId = costMatrix.EdgeId(innerCityId, outerCityId);
                        _incomingEdgesSortedByDistance.Add(incomingId);
                        _incomingEdgesByCitySortedByDistance[outerCityId].Add(incomingId);
                        _outgoingEdgesSortedByDistance.Add(outgoingId);
                        _outgoingEdgesByCitySortedByDistance[outerCityId].Add(outgoingId);

                    }
                }
            }

            _incomingEdgesSortedByDistance.Sort((a, b) =>
                costMatrix.CostAtEdgeId(a).CompareTo(costMatrix.CostAtEdgeId(b))
                );
            _outgoingEdgesSortedByDistance.Sort((a, b) =>
                costMatrix.CostAtEdgeId(a).CompareTo(costMatrix.CostAtEdgeId(b)));

            ContainedCityIds = new List<int>();
            foreach (CityNodeData city in _containedCities)
            {
                ContainedCityIds.Add(city.CityId);
            }
        }
Esempio n. 2
0
        public double SolveExternalClusters(CostMatrix costMatrix, List<CityNodeData> CityData,
            List<CityCluster> cityClusters, Dictionary<int, CityCluster> cityToClusterItsIn,
            out List<int> interNodeEdges)
        {
            int startingEdge = -1;
            foreach (int i in costMatrix.AllEdgesSortedByDistance)
            {
                KeyValuePair<int, int> coords = costMatrix.EdgeCoords(i);
                if (!cityToClusterItsIn[coords.Key].Equals(cityToClusterItsIn[coords.Value]))
                {
                    startingEdge = i;
                    break;
                }
            }
            KeyValuePair<int, int> curCoords = costMatrix.EdgeCoords(startingEdge);
            CityCluster curFromCluster = cityToClusterItsIn[curCoords.Key];
            List<int> visitedCities = new List<int>();
            List<CityCluster> clustersVisitedInOrder = new List<CityCluster>();
            interNodeEdges = new List<int>();

            clustersVisitedInOrder.Add(cityToClusterItsIn[curCoords.Key]);
            visitedCities.AddRange(cityToClusterItsIn[curCoords.Key].ContainedCityIds);
            cityToClusterItsIn[curCoords.Value].IncomingFromEdge(startingEdge);
            cityToClusterItsIn[curCoords.Key].OutgoingOnEdge(startingEdge);
            interNodeEdges.Add(startingEdge);

            while (interNodeEdges.Count < cityClusters.Count - 1)
            {
                curFromCluster = cityToClusterItsIn[curCoords.Value];
                int newEdgeId = curFromCluster.GetShortestValidOutgoingEdgeIgnoringCities(visitedCities);

                curCoords = costMatrix.EdgeCoords(newEdgeId);
                cityToClusterItsIn[curCoords.Value].IncomingFromEdge(newEdgeId);
                cityToClusterItsIn[curCoords.Value].OutgoingOnEdge(newEdgeId);

                clustersVisitedInOrder.Add(curFromCluster);
                visitedCities.AddRange(curFromCluster.ContainedCityIds);
                interNodeEdges.Add(newEdgeId);
            }

            CityCluster end = cityToClusterItsIn[curCoords.Value];
            CityCluster start = clustersVisitedInOrder[0];
            int lastEdge = CityCluster.ShortedValidEdgeBetweenClusters(end, start);
            interNodeEdges.Add(lastEdge);
            _interNodeEdges = interNodeEdges;

            double retVal = 0;
            foreach (int edge in interNodeEdges)
            {
                retVal += costMatrix.CostAtEdgeId(edge);
            }
            return retVal;
        }
Esempio n. 3
0
        public void DoClusters(out CostMatrix CostMatrix, out List<CityNodeData> CityData, 
            out List<CityCluster> CityClusters, out Dictionary<int, CityCluster> CityToClusterItsIn,
            out Dictionary<int, int> SizeClusterToNumberOfThatSize)
        {
            CostMatrix = new CostMatrix(Cities);
                _costMatrix = CostMatrix;
                Stopwatch clusterWatch = new Stopwatch();
                clusterWatch.Start();
                CityData = new List<CityNodeData>();
                _cityNodes = CityData;
                for (int i = 0; i < CostMatrix.Size; i++)
                {
                    CityData.Add(new CityNodeData(i, CostMatrix, Cities));
                }

                //Clustering
                double threshold = CostMatrix.DistanceRange * _clusterPercent;
                _threshold = (float)threshold;
                List<CityNodeData> citiesSortedByNumberUnderThreshold = new List<CityNodeData>(CityData);
                citiesSortedByNumberUnderThreshold.Sort((a, b) =>
                    (a.AverageWorstDistanceOfBelowThreshold(threshold).CompareTo(
                    b.AverageWorstDistanceOfBelowThreshold(threshold))));

                List<List<CityNodeData>> finalClusters = new List<List<CityNodeData>>();
                List<CityNodeData> visited = new List<CityNodeData>(CityData);
                Dictionary<CityNodeData, int> clusterAssignment = new Dictionary<CityNodeData, int>();
                foreach (CityNodeData c in visited)
                {
                    clusterAssignment.Add(c, -1);
                }

                while (citiesSortedByNumberUnderThreshold.Count > 0)
                {
                    List<CityNodeData> curCluster = new List<CityNodeData>();
                    CityNodeData cur = citiesSortedByNumberUnderThreshold[0];
                    clusterAssignment[cur] = finalClusters.Count;

                    citiesSortedByNumberUnderThreshold.RemoveAt(0);
                    visited.Remove(cur);
                    curCluster.Add(cur);

                    for (int i = 0; i < cur.SortedWorstDistance.Count; i++)
                    {
                        bool canAdd = true;
                        CityNodeData curCloseCheck = CityData[cur.SortedWorstDistance[i].CityId];
                        if (!visited.Contains(curCloseCheck))
                        {
                            continue;
                        }
                        foreach (CityNodeData inCluster in curCluster)
                        {
                            double worstDistance = CostMatrix.WorstDistanceBetween(inCluster.CityId, curCloseCheck.CityId);
                            if (worstDistance > threshold)
                            {
                                canAdd = false;
                                break;
                            }
                        }

                        if (canAdd)
                        {
                            curCluster.Add(curCloseCheck);
                            visited.Remove(curCloseCheck);
                            citiesSortedByNumberUnderThreshold.Remove(curCloseCheck);
                        }
                    }

                    finalClusters.Add(curCluster);
                }
                clusterWatch.Stop();
                Console.WriteLine("SAVED: " + (CostMatrix.Size - finalClusters.Count));
                _storedClusters = finalClusters;

                CityClusters = new List<CityCluster>();
                CityToClusterItsIn = new Dictionary<int, CityCluster>();
                SizeClusterToNumberOfThatSize = new Dictionary<int, int>();
                foreach (List<CityNodeData> clust in finalClusters)
                {
                    CityCluster actualCluster = new CityCluster(clust, CityData, CostMatrix);
                    CityClusters.Add(actualCluster);
                    foreach (int city in actualCluster.ContainedCityIds)
                    {
                        CityToClusterItsIn.Add(city, actualCluster);
                    }
                    if (!SizeClusterToNumberOfThatSize.ContainsKey(clust.Count))
                    {
                        SizeClusterToNumberOfThatSize.Add(clust.Count, 0);
                    }
                    SizeClusterToNumberOfThatSize[clust.Count] =
                        SizeClusterToNumberOfThatSize[clust.Count] + 1;
                }
        }
Esempio n. 4
0
        private TSPSolution Solve(CostMatrix costMatrix, List<CityNodeData> CityData,
            List<CityCluster> cityClusters, Dictionary<int, CityCluster> cityToClusterItsIn,
            List<int> interNodeEdges)
        {
            List<int> allEdges = new List<int>();
            ArrayList sol = new ArrayList();

            foreach (int edge in interNodeEdges)
            {
                KeyValuePair<int, int> coords = costMatrix.EdgeCoords(edge);
                CityCluster target = cityToClusterItsIn[coords.Value];
                allEdges.Add(edge);
                List<int> edgesSolved = target.GreedySolveEdges();
                if (edgesSolved.Count == 0)
                {
                    sol.Add(Cities[target.ContainedCityIds[0]]);
                }
                else
                {
                    for (int i = 0; i < edgesSolved.Count; i++)
                    {
                        int curEdge = edgesSolved[i];
                        KeyValuePair<int, int> innerCoords = costMatrix.EdgeCoords(curEdge);
                        if (i == 0)
                        {
                            sol.Add(Cities[innerCoords.Key]);
                        }
                        sol.Add(Cities[innerCoords.Value]);

                        allEdges.Add(curEdge);
                    }
                }

            }
            return new TSPSolution(sol);
        }