public boolean twoOpt(){
		int pathLength=tour.length();
		int k=Math.min(160, pathLength);

		int progress=0;
		
		boolean better=false;
		outer:
		for(int currentVerticeIndex=0; currentVerticeIndex<pathLength;currentVerticeIndex++){
//		for(int currentVerticeIndex=0; progress<pathLength; progress++){
//			currentVerticeIndex=Help.mod2(progress, pathLength);
			
			int nextVerticeIndex=(currentVerticeIndex+1)%pathLength;
			int previousVerticeIndex=Help.mod2(currentVerticeIndex-1, pathLength);
			int distOldEdge=tour.indexDistance(currentVerticeIndex, nextVerticeIndex);

			//goes the edges in sorted order
			for(int iters=0;iters<k;iters++){
				//want index in path instead
				int toVertice=se.getXNeighbor(tour.getVertice(currentVerticeIndex), iters);

				if(toVertice!=tour.getVertice(currentVerticeIndex) && 
						toVertice!=tour.getVertice(previousVerticeIndex) &&
						toVertice!=tour.getVertice(nextVerticeIndex)){
					//					
//					toVertice= Help.circleIncrement(toVertice, pathLength);
				
					int distNewEdge=ug.dist(tour.getVertice(currentVerticeIndex), toVertice);
					if(distNewEdge>=distOldEdge){
						break;
					}



					//check if edge to swapwith is better than edge from current to next
					if(distNewEdge < distOldEdge ){
						int swapWithIndexInPath=Help.indexInArray(tour.path, toVertice);
//						int swapWithIndexInPath=Help.indexInArray(tour.path, toVertice);
						//check if second edge swap if it really is an improvement
						if(swapIfBetterTwoOpt(nextVerticeIndex,swapWithIndexInPath)){
							//it was better so complete the reversing
							int innerFrom=(nextVerticeIndex+1)%pathLength;
							int innerTo= swapWithIndexInPath==0 ? pathLength-1 : swapWithIndexInPath-1; 

							tour.reverseSubPath(innerFrom, innerTo);
							
							better=true;
							// test!
//							currentVerticeIndex= currentVerticeIndex==0 ? pathLength-2 :  currentVerticeIndex-1;
						
						
							
						}


					}
				}


			}

		}
		return better;
	}