//constructor for creating first node public Node(City[] cities) { matrixLength = cities.Length; entered = new int[matrixLength]; exited = new int[matrixLength]; for (int i = 0; i < matrixLength; i++) { entered[i] = -1; exited[i] = -1; } rCmatrix = new double[matrixLength, matrixLength]; for (int i = 0; i < matrixLength; i++) { for (int j = 0; j < matrixLength; j++) { rCmatrix[i, j] = cities[i].costToGetTo(cities[j]); } } for(int i = 0; i < matrixLength; i++) { rCmatrix[i, i] = Double.PositiveInfinity; } lowerBound = 0; totalEdges = 0; reduceMatrix(rCmatrix); }
// Initial state, reduces matrix public State(City[] cities) { queue = new HeapPriorityQueue<State>(10000); root = this; Watch = new Stopwatch(); Watch.Start(); State.cities = cities; cityCount = cities.Length; matrix = new double[cities.Length, cities.Length]; for (int i = 0; i < cities.Length; i++) { for (int j = 0; j < cities.Length; j++) { matrix[i, j] = cities[i].costToGetTo(cities[j]); // Set diagonals to infinity (negative) if (i == j) { matrix[i, j] = double.PositiveInfinity; } } } bound = 0; route = new ArrayList(); visited = new ArrayList(); pathsLeft = cityCount; setInitialBSSF(); reduceMatrix(); // Start expanding until agenda is empty, time is up, or BSSF cost is equal to original LB. Expand(); }
public HardMode(Modes mode, Random rnd, City[] cities) { this.mode = mode; this.rnd = rnd; this.cities = cities; this.removedEdges = new HashSet<Edge>(); }
/// <summary> /// how much does it cost to get from this to the destination? /// note that this is an asymmetric cost function /// </summary> /// <param name="destination">um, the destination</param> /// <returns></returns> public double costToGetTo(City destination) { double magnitude = Math.Sqrt(Math.Pow(this.X - destination.X, 2) + Math.Pow(this.Y - destination.Y, 2)); magnitude *= INCREASE_X; return Math.Round(magnitude); }
public State(City[] cities, int f, int d, ArrayList routeSF, double costSF, double[,] adj) { _routeSF = new ArrayList(routeSF); _routeSF.Add(cities[d]); _costSF = costSF; _costSF += cities[f].costToGetTo(cities[d]); CopyArray(adj); ToInfinity(f, d); DetermineLB(); }
public CostMatrix(City[] Cities) { Size = Cities.Length; _innerMatrix = new double[Size][]; AllEdgesSortedByDistance = new List<int>(); MaxNonInfiniteDistance = double.MinValue; MinDistance = double.MaxValue; for (int i = 0; i < Size; i++) { _innerMatrix[i] = new double[Size]; for (int j = 0; j < Size; j++) { double val = double.PositiveInfinity; if (i != j) { val = Cities[i].costToGetTo(Cities[j]); MinDistance = Math.Min(MinDistance, val); if (val != double.PositiveInfinity) { MaxNonInfiniteDistance = Math.Max(MaxNonInfiniteDistance, val); } } AllEdgesSortedByDistance.Add(i * Size + j); _innerMatrix[i][j] = val; } } AllEdgesSortedByDistance.Sort((a, b) => CostAtEdgeId(a).CompareTo(CostAtEdgeId(b))); DistanceRange = MaxNonInfiniteDistance - MinDistance; _innerBestDistance = new double[Size][]; _innerWorstDistance = new double[Size][]; for (int i = 0; i < Size; i++) { _innerWorstDistance[i] = new double[Size]; _innerBestDistance[i] = new double[Size]; for (int j = 0; j < Size; j++) { double minBest = Math.Min(_innerMatrix[i][j], _innerMatrix[j][i]); _innerBestDistance[i][j] = minBest; double maxWorst = Math.Max(_innerMatrix[i][j], _innerMatrix[j][i]); _innerWorstDistance[i][j] = maxWorst; } } }
//Generate next States from this State public ArrayList Expand(City[] cities) { ArrayList newStates = new ArrayList(); for (int i = 0; i < _adj.GetLength(0); i++) { for (int j = 0; j < _adj.GetLength(1); j++) { if (_adj[i, j] < 999999) newStates.Add(new State(cities, i, j, _routeSF, _costSF, _adj)); } } return newStates; }
/// <summary> /// How much does it cost to get from this city to the destination? /// Note that this is an asymmetric cost function. /// /// In advanced mode, it returns infinity when there is no connection. /// </summary> public double costToGetTo (City destination) { // Cartesian distance double magnitude = Math.Sqrt(Math.Pow(this.X - destination.X, 2) + Math.Pow(this.Y - destination.Y, 2)); // For Medium and Hard modes, add in an asymmetric cost (in easy mode it is zero). magnitude += (destination._elevation - this._elevation); if (magnitude < 0.0) magnitude = 0.0; magnitude *= SCALE_FACTOR; // In hard mode, remove edges; this slows down the calculation... if (modeManager.isEdgeRemoved(this,destination)) magnitude = Double.PositiveInfinity; return Math.Round(magnitude); }
public Matrix(City[] cities) { _matrix = new double[cities.Length, cities.Length]; for(int i = 0; i < cities.Length; i++) { for(int j = 0; j < cities.Length; j++) { if (i == j) { _matrix[i, j] = double.PositiveInfinity; continue; } _matrix[i, j] = cities[i].costToGetTo(cities[j]); } } }
private void GetCheapestCityFrom(City startNode, IEnumerable<City> availableCities) { if (!availableCities.Any()) return; City next = startNode; double lowestCost = double.MaxValue; foreach (City c in availableCities) { double cost = startNode.Distance(c); if (cost < lowestCost) { next = c; lowestCost = cost; } } visitationOrder.Add(next); GetCheapestCityFrom(next, availableCities.Where(cc => cc.Name != next.Name)); }
public List<int> initRemaining(List<int> remainingCities, City[] Cities) { //initialize the remaining cities array with all the cities for (int i = 0; i < Cities.Length; i++) { remainingCities.Add(i); } return remainingCities; }
public ArrayList BranchAndBound(City[] Cities, ArrayList Route, double BSSF) { Node startNode = new Node(Cities); startNode.initStaticMembers(); PriorityQueue pQ = new PriorityQueue(startNode); ArrayList bbRoute = null; Stopwatch timer = new Stopwatch(); timer.Start(); //while ((pQ.Size() > 0) && (pQ.Peek() < BSSF) && (timer.Elapsed.TotalMinutes < 10)) while ((pQ.Size() > 0) && (pQ.Peek() < BSSF) && (timer.Elapsed.TotalSeconds < 30)) { // Keep track of the largest size of the queue if (pQ.Size() > Node.maxNodesCreated) { Node.maxNodesCreated = pQ.Size(); } startNode = pQ.DeleteMinimum(); //startNode.matrix2Table(); // Check for a solution if (startNode.includedEdges == Cities.Length) { ArrayList tempRoute = new ArrayList(); if (!startNode.exited.Contains(-1)) { int index = 0; while (tempRoute.Count < Cities.Length) { tempRoute.Add(Cities[startNode.exited[index]]); index = startNode.exited[index]; } BSSF = startNode.lowerBound; bbRoute = tempRoute; Node.numSolutions++; } } Node incNode = new Node(startNode); Node excNode = new Node(startNode); Node maxInclude = null; Node maxExclude = null; double maxDiff = -1; double diff = 0; int maxRow = 0; int maxCol = 0; for (int row = 0; row < startNode.matrixSize; row++) { for (int col = 0; col < startNode.matrixSize; col++) { if (startNode.rcMatrix[row, col] == 0) { Node includeNode = new Node(incNode, true, row, col); Node excludeNode = new Node(excNode, false, row, col); diff = excludeNode.lowerBound - includeNode.lowerBound; Node.numStatesCreated += 2; if (diff > maxDiff) { maxDiff = diff; maxRow = row; maxCol = col; maxInclude = new Node(includeNode); maxExclude = new Node(excludeNode); } } } } if (maxInclude != null && maxInclude.lowerBound < BSSF) { pQ.Insert(maxInclude); } else { Node.pruneCount++; } if (maxExclude != null && maxExclude.lowerBound < BSSF) { pQ.Insert(maxExclude); } else { Node.pruneCount++; } } timer.Stop(); Node.timeElapsed = timer.ElapsedMilliseconds; if (bbRoute == null) { return Route; } else { // Add the rest of the queue to the pruned count Node.pruneCount += pQ.Size(); return bbRoute; } }
public ArrayList GreedySolution(City[] Cities) { ArrayList greedyRoute = new ArrayList(); for (int w = 0; w < Cities.Length; w++) { greedyRoute.Clear(); List<int> remainingCities = new List<int>(); //initialize the remaining cities array with all the cities for (int i = 0; i < Cities.Length; i++) { remainingCities.Add(i); } int nextCity = w; City firstCity = Cities[w]; City currCity = firstCity; while (remainingCities.Count > 0) { greedyRoute.Add(Cities[nextCity]); remainingCities.Remove(nextCity); double bestDist = double.PositiveInfinity; int bestCity = -1; foreach (int city in remainingCities) { double dist = Cities[nextCity].costToGetTo(Cities[city]); if (bestDist > dist) { bestCity = city; bestDist = dist; currCity = Cities[bestCity]; } } nextCity = bestCity; } if ((currCity.costToGetTo(firstCity) != double.PositiveInfinity) && (greedyRoute.Count == Cities.Length)) { // Solution found, stop looping break; } } return greedyRoute; }
void RateSubCycle(IDictionary<Tuple<City, City>, double> Ratings, City[] SubCycle) { double SubCycleRate = ((double) SubCycle.Count) / ((double) Cities.Count); for (int i = 0; i < SubCycle.Count - 1; i++) { Tuple<City,City> CurrentEdge = new Tuple<City, City>(SubCycle[i],SubCycle[i+1]); double CurrentRating; if (Ratings.TryGetValue(CurrentEdge, out CurrentRating)) { Ratings.Remove(CurrentEdge); Ratings.Add(CurrentEdge,CurrentRating + SubCycleRate); } else { Ratings.Add(CurrentEdge,SubCycleRate); } } }
public Edge(City city1, City city2) { this.City1 = city1; this.City2 = city2; }
public void AddConnection(City city) { Route.Add(city); }
private ArrayList getNextRoute(ArrayList prev, City[] Cities) { ArrayList newRoute = new ArrayList(prev); List<int> remainingCities = new List<int>(); //initialize the remaining cities array with all the cities for (int i = 0; i < Cities.Length; i++) { remainingCities.Add(i); } int firstCity = new Random(DateTime.Now.Millisecond).Next(Cities.Length); remainingCities.Remove(firstCity); int secondCity = getUniqueRandom(Cities.Length, remainingCities); City temp = (City)newRoute[firstCity]; newRoute[firstCity] = newRoute[secondCity]; newRoute[secondCity] = temp; return newRoute; }
// this method is not thread-safe, i.e., it should not be called from two separate threads public bool IsEdgeRemoved(City city1, City city2) { _tempEdge.City1 = city1; _tempEdge.City2 = city2; return(_removedEdges.Contains(_tempEdge)); }
//List<City> cities) // Shuffles cities to generate a temporary reference path. The reference path // guarantees that we don't create an impossible graph when removing edges. private HashSet<Edge> generateReferencePath(City[] cities) { City[] referencePath = new City[cities.Length]; City[] remainingCities = new City[cities.Length]; for (int i = 0; i < cities.Length; i++) remainingCities[i] = cities[i]; int remainingSize = remainingCities.Length; for (int i = 0; i < referencePath.Length; i++) { int index = rnd.Next() % remainingSize; referencePath[i] = remainingCities[index]; remainingCities[index] = remainingCities[remainingSize - 1]; } // put the loop into a HashSet of Edges... HashSet<Edge> referenceSet = new HashSet<Edge>(); for (int i = 0; i < cities.Length - 1; i++) referenceSet.Add(new Edge(cities[i], cities[(i + 1) % cities.Length])); return referenceSet; }
/// <summary> /// Reset the problem instance. /// </summary> private void resetData() { Cities = new City[_size]; Route = new ArrayList(_size); bssf = null; if (_mode == HardMode.Modes.Easy) { for (int i = 0; i < _size; i++) Cities[i] = new City(rnd.NextDouble(), rnd.NextDouble()); } else // Medium and hard { for (int i = 0; i < _size; i++) Cities[i] = new City(rnd.NextDouble(), rnd.NextDouble(), rnd.NextDouble() * City.MAX_ELEVATION); } HardMode mm = new HardMode(this._mode, this.rnd, Cities); if (_mode == HardMode.Modes.Hard) { int edgesToRemove = (int)(_size * FRACTION_OF_PATHS_TO_REMOVE); mm.removePaths(edgesToRemove); } City.setModeManager(mm); cityBrushStyle = new SolidBrush(Color.Black); cityBrushStartStyle = new SolidBrush(Color.Red); routePenStyle = new Pen(Color.Blue,1); routePenStyle.DashStyle = System.Drawing.Drawing2D.DashStyle.Solid; }
/// <summary> /// return a copy of the cities in this problem. /// </summary> /// <returns>array of cities</returns> public City[] GetCities() { City[] retCities = new City[Cities.Length]; Array.Copy(Cities, retCities, Cities.Length); return(retCities); }
public double GetCost(City from, City to) { double magnitude = Math.Sqrt(Math.Pow(from.X - to.X, 2) + Math.Pow(from.Y - to.Y, 2)); if (to.X > from.X) magnitude *= INCREASE_X; else if (to.X < from.X) magnitude *= DECREASE_X; if (to.Y > from.Y) magnitude *= INCREASE_Y; else if (to.Y < from.Y) magnitude *= DECREASE_Y; return magnitude; }
public ArrayList RandomSolution(City[] Cities) { ArrayList randomRoute = new ArrayList(); List<int> remainingCities = new List<int>(); int currCity = -1; int prevCity = -1; bool notConnected = true; double dist = -1; remainingCities = initRemaining(remainingCities, Cities); while (notConnected) { while (remainingCities.Count > 0) { if (remainingCities.Count > 1) { currCity = getUniqueRandom(Cities.Length, remainingCities); if (prevCity != -1) { dist = Cities[prevCity].costToGetTo(Cities[currCity]); if (!double.IsInfinity(dist)) { randomRoute.Add(Cities[currCity]); remainingCities.Remove(currCity); prevCity = currCity; } } else { randomRoute.Add(Cities[currCity]); remainingCities.Remove(currCity); prevCity = currCity; } } else { // no need to get a random number if only 1 city is left in the list, just return the remaining city currCity = remainingCities[remainingCities.Count - 1]; dist = Cities[prevCity].costToGetTo(Cities[currCity]); if (!double.IsInfinity(dist)) { randomRoute.Add(Cities[currCity]); remainingCities.Remove(currCity); prevCity = currCity; } else { // Next to last city cannot connect to last city. Need to reset and try again to get a connected route. randomRoute.Clear(); remainingCities.Clear(); currCity = -1; prevCity = -1; remainingCities = initRemaining(remainingCities, Cities); } } } dist = Cities[currCity].costToGetTo((City)randomRoute[0]); if (!double.IsInfinity(dist)) { notConnected = false; } else { // Last city cannot connect to first city. Need to reset and try again to get a connected route. randomRoute.Clear(); remainingCities.Clear(); currCity = -1; prevCity = -1; remainingCities = initRemaining(remainingCities, Cities); } } return randomRoute; }
public void addCityToPath(City city) { path.Add(city); }
public ArrayList SimulatedAnnealingSolution(City[] Cities, ArrayList simAnnealRoute) { //ArrayList simAnnealRoute = GreedySolution(Cities); ArrayList nextRoute = new ArrayList(); Random random = new Random(DateTime.Now.Millisecond); int iteration = -1; //double temperature = 50000.0; double temperature = Program.MainForm.saMaxTemp; double deltaDistance = 0; double coolingRate = 0.9999; double absTemperature = 0.00001; double distance = getCost(simAnnealRoute); while (temperature > absTemperature) { nextRoute = getNextRoute(simAnnealRoute, Cities); deltaDistance = getCost(nextRoute) - distance; if (deltaDistance < 0 || (distance > 0 && Math.Exp(-deltaDistance / temperature) > random.NextDouble())) { for (int i = 0; i < nextRoute.Count; i++) { simAnnealRoute[i] = nextRoute[i]; } distance = deltaDistance + distance; } temperature *= coolingRate; iteration++; } return simAnnealRoute; }
public BoundedBrancher(City[] _cities) { cities = _cities; agenda = new TSPAgenda(); }
/// <summary> /// return a copy of the cities in this problem. /// </summary> /// <returns>array of cities</returns> public City[] GetCities() { City[] retCities = new City[_size]; Array.Copy(Cities, retCities, _size); return retCities; }
private void GenerateDataSet() { Cities = new City[_size]; Route = new ArrayList(_size); Random rnd = new Random(_seed); for (int i = 0; i < _size; i++) Cities[i] = new City(rnd.NextDouble(), rnd.NextDouble()); cityBrushStyle = new SolidBrush(Color.Black); cityBrushStartStyle = new SolidBrush(Color.Red); routePenStyle = new Pen(Color.LightGray, 1); routePenStyle.DashStyle = System.Drawing.Drawing2D.DashStyle.Solid; }
/// <summary> /// return a copy of the cities in this problem. /// </summary> /// <returns>array of cities</returns> public City[] GetCities() { City[] retCities = new City[Cities.Length]; Array.Copy(Cities, retCities, Cities.Length); return retCities; }
public TSPSolution(City firstcity) { Route = new ArrayList(); Route.Add(firstcity); }
public Edge(City city1, City city2) { this.city1 = city1; this.city2 = city2; }
public double Distance(City c) { return Math2D.Distance(X, Y, c.X, c.Y); }
// this method is not thread-safe, i.e., it should not be called from two separate threads public bool isEdgeRemoved(City city1, City city2) { tempEdge.city1 = city1; tempEdge.city2 = city2; return removedEdges.Contains(tempEdge); }
/// <summary> /// reset the problem instance. /// </summary> private void resetData() { Cities = new City[_size]; Route = new ArrayList(_size); bssf = null; for (int i = 0; i < _size; i++) Cities[i] = new City(rnd.NextDouble(), rnd.NextDouble()); cityBrushStyle = new SolidBrush(Color.Black); cityBrushStartStyle = new SolidBrush(Color.Red); routePenStyle = new Pen(Color.LightGray,1); routePenStyle.DashStyle = System.Drawing.Drawing2D.DashStyle.Solid; }