public List<Venue> findSimilarRelevantVenues(Venue venue) {
		List<Venue> similarRelevantVenues = new ArrayList<Venue>();
		
		// venueRatings maps each rated venue Id with the rating user has
		// given to this venue (the ratings have been rescaled from -1 to 4
		// into -0.25 to 1.0).
		Map<String, Double> venueRatings = user.getVenueRatings();
		for (String ratedVenueId : venueRatings.keySet()) {
			Venue ratedVenue = ratedVenues.get(ratedVenueId);
			if (tsim(venue, ratedVenue) == 1.0 && 
					(venueRatings.get(ratedVenueId) == 0.75 || venueRatings.get(ratedVenueId) == 1.0)) {
				// ratedVenue is both topically similar to venue (tsim = 1) and
				// got a good rating (0.75/1.0 or 1.0/1.0). It is thus added to
				// similarRelevantVenues.
				similarRelevantVenues.add(ratedVenue);
			}
		}
		
		// similarRelevantVenues is ordered by decreasing estimated
		// appreciation (eapp). Estimated appreciation is chosen over the
		// rating of the venue in order to smooth the rating and take into
		// account the complete profile of the user.
		Collections.sort(similarRelevantVenues, new Comparator<Venue>() {
		    public int compare(Venue venue1, Venue venue2) {
		    	return -Double.compare(eapp(venue1), eapp(venue2));
		    }
		});
		
		return similarRelevantVenues;
	}