package neuralnets;


/**
 *Dustin Stevens-Baier
 *
 *original code by Vania Sarieva modified and fine tuned by Dustin
 * 
 * TourCity contains randomly generated city tours within a certain population. Once the tours are
 * generated, the distance between the tours can be calculated. The mutator operator is also applied
 * here to swap two random values.
 */
import java.util.*;
public class TourCity 
{
	private int numCities;
	private int[] tours;
	private double totalTraveledDistance;
	
	public TourCity(int numCities)
	{
		// Create tours
		totalTraveledDistance = 0;		
		this.numCities = numCities;
		tours = new int[numCities]; 
	}
	
	public void initializeTours()
	{
		// Koshok's initialization tour
		int tempCityVisit;
		//	initialize to random cities
		for(int i = 0; i < numCities; i++)
			tours[i] = -1;
		
		// initialize tours to randomly stop at every city
		for(int i = 0; i < numCities; i++)
		{
			do
			{
				tempCityVisit = (int)Math.floor(Math.random() * numCities);
			}
			while(tours[tempCityVisit] != -1);
			tours[tempCityVisit] = i;			
		}
	}
	
	public void setTraveledDistance(double totalTraveledDistance)
	{
		this.totalTraveledDistance = totalTraveledDistance;
	}
	
	public double getTraveledDistance()
	{
		return totalTraveledDistance;
	}
	
	public int getTourCityVisited(int cityIndex)
	{
		return tours[cityIndex];
	}
	
	public void setTourCityVisited(int cityIndex, int cityNum)
	{
		tours[cityIndex] = cityNum;
	}
	
	public void mutatorOperatorOne()
	{
		int swapTourValue;
		// Create a random number
		Random randNum = new Random();
		
		int startIndex = (int)randNum.nextInt(numCities - 1) % (numCities - 1);
		int endIndex = (int)randNum.nextInt(numCities - 1) % (numCities - 1);
		
		// Make sure no two indices are the same
		if(startIndex == endIndex)
			endIndex = (endIndex + 1) % (numCities-1);
		
		// Randomly swap two numbers
		swapTourValue = tours[startIndex];
		tours[startIndex] = tours[endIndex];
		tours[endIndex] = swapTourValue;
	}
	
	public double calculateDistance(City3[] cities)
	{
		double totalDistance = 0;
		double x1 = 0;
		double x2 = 0;
		double y1 = 0;
		double y2 = 0;
		
		// Get cities before the last point
		for(int i = 0; i < numCities - 1; i++)
		{
			x1 = cities[tours[i]].getXCoord();
			y1 = cities[tours[i]].getYCoord();
			
			x2 = cities[tours[i + 1]].getXCoord();
			y2 = cities[tours[i + 1]].getYCoord();
			
			totalDistance += Math.sqrt( Math.pow(Math.abs(x2 - x1), 2.0) +  
							            Math.pow(Math.abs(y2 - y1), 2.0));
		}
		
		// Calculate the distance between the last city and the first city
		x1 = cities[tours[numCities - 1]].getXCoord();
		y1 = cities[tours[numCities - 1]].getYCoord();
		
		x2 = cities[tours[0]].getXCoord();
		y2 = cities[tours[0]].getYCoord();
		
		totalDistance += Math.sqrt( Math.pow(Math.abs(x2 - x1), 2.0) +  
	            					Math.pow(Math.abs(y2 - y1), 2.0));		
		
		totalTraveledDistance = totalDistance;
		return totalDistance;
	}
		
	public void displayTourInfo()
	{
		String tourInfo = "";
		for(int i = 0; i < numCities; i++)
		{
			if(tours[i] < 9)
				tourInfo += "0";
			
			tourInfo += tours[i]+1;
			
			if(i < numCities-1)
			{
				tourInfo += "  ";
			}
		}
		System.out.println("[ " + tourInfo + " ] " + totalTraveledDistance);
	}
}
