AI-Driven Personalized Travel Itinerary Planner Based on User Preferences,Swift

👤 Sharing: AI
Okay, here's a basic Swift program to get you started with an AI-driven personalized travel itinerary planner.  This is a simplified example and will require significant expansion to incorporate actual AI/ML models and extensive data.  It provides a structure and placeholders for more advanced features.

```swift
import Foundation

// MARK: - Data Structures

// Represents a single activity (e.g., visiting a museum, eating at a restaurant)
struct Activity {
    let name: String
    let description: String
    let location: String
    let category: String  // e.g., "Sightseeing", "Food", "Entertainment"
    let duration: TimeInterval // in seconds
    let cost: Double? // Optional cost
    var rating: Double? // User rating, initially nil

    init(name: String, description: String, location: String, category: String, duration: TimeInterval, cost: Double? = nil, rating: Double? = nil) {
        self.name = name
        self.description = description
        self.location = location
        self.category = category
        self.duration = duration
        self.cost = cost
        self.rating = rating
    }
}

// Represents a day in the itinerary
struct ItineraryDay {
    let dayNumber: Int
    var activities: [Activity]
    var totalCost: Double { // Computed property
        return activities.reduce(0) { (result, activity) -> Double in
            return result + (activity.cost ?? 0) // Use 0 if cost is nil
        }
    }
    var totalDuration: TimeInterval {
        return activities.reduce(0) { (result, activity) -> TimeInterval in
            return result + activity.duration
        }
    }
}

// Represents the overall travel itinerary
struct Itinerary {
    let destination: String
    var days: [ItineraryDay]
    let userPreferences: [String: Any] // Store user preferences as a dictionary

    var totalItineraryCost: Double {
        return days.reduce(0) { (result, day) -> Double in
            return result + day.totalCost
        }
    }
    var totalItineraryDuration: TimeInterval {
        return days.reduce(0) { (result, day) -> TimeInterval in
            return result + day.totalDuration
        }
    }
}


// MARK: - Functions

// 1. Simulate collecting user preferences (replace with actual UI input)
func getUserPreferences() -> [String: Any] {
    var preferences: [String: Any] = [:]

    print("Enter your travel preferences:")
    print("Destination:")
    if let destination = readLine() {
        preferences["destination"] = destination
    }

    print("Interest (e.g., Art, History, Food):")
    if let interest = readLine() {
        preferences["interest"] = interest
    }

    print("Budget (optional, enter a number or leave blank):")
    if let budgetString = readLine(), !budgetString.isEmpty, let budget = Double(budgetString) {
        preferences["budget"] = budget
    }

    print("Travel style (e.g., Relaxed, Adventurous):")
    if let travelStyle = readLine() {
        preferences["travelStyle"] = travelStyle
    }

    print("Duration in days:")
    if let durationString = readLine(), let duration = Int(durationString) {
        preferences["duration"] = duration
    }
    return preferences
}


// 2. Simulate fetching activities based on preferences (replace with database query/API call)
func fetchActivities(destination: String, preferences: [String: Any]) -> [Activity] {
    // This is a placeholder. In a real application, this function would:
    // - Query a database or call an API to get activities based on the destination.
    // - Filter and sort the activities based on the user's preferences.
    // - Potentially use an AI model to rank activities based on relevance.

    var activities: [Activity] = []

    // Sample activities for Paris, France
    if destination.lowercased() == "paris" {
        activities.append(Activity(name: "Eiffel Tower Visit", description: "Visit the iconic Eiffel Tower.", location: "Champ de Mars, Paris", category: "Sightseeing", duration: 7200, cost: 26.80)) // 2 hours
        activities.append(Activity(name: "Louvre Museum", description: "Explore the Louvre Museum and see the Mona Lisa.", location: "Rue de Rivoli, Paris", category: "Art", duration: 10800, cost: 17)) // 3 hours
        activities.append(Activity(name: "Seine River Cruise", description: "Enjoy a relaxing cruise on the Seine River.", location: "Various docks along the Seine", category: "Sightseeing", duration: 3600, cost: 15)) // 1 hour
        activities.append(Activity(name: "Dinner at Le Jules Verne", description: "Fine dining experience with a view.", location: "Eiffel Tower, Paris", category: "Food", duration: 7200, cost: 200)) //2 hours
        activities.append(Activity(name: "Notre Dame Cathedral", description: "Visit the Notre Dame Cathedral", location: "6 Parvis Notre-Dame - Place Jean-Paul II, 75004 Paris, France", category: "Sightseeing", duration: 3600, cost: 0)) //1 hour
    } else if destination.lowercased() == "london" {
        activities.append(Activity(name: "Buckingham Palace", description: "Visit Buckingham Palace.", location: "London", category: "Sightseeing", duration: 3600, cost: 30))
        activities.append(Activity(name: "The British Museum", description: "Explore the British Museum", location: "London", category: "Art", duration: 7200, cost: 0))
        activities.append(Activity(name: "London Eye", description: "Ride the London Eye", location: "London", category: "Sightseeing", duration: 3600, cost: 30))
    } else {
        print("No activities found for that destination.")
    }

    // Filter activities based on user preferences (very basic example)
    if let interest = preferences["interest"] as? String {
        activities = activities.filter { $0.category.lowercased().contains(interest.lowercased()) }
    }

    // Sort activities (e.g., by cost or duration, based on user preference)
    // activities.sort { $0.cost ?? 0 < $1.cost ?? 0 } // Example: Sort by cost (ascending)

    return activities
}


// 3. Generate a basic itinerary (replace with a smarter algorithm)
func generateItinerary(destination: String, activities: [Activity], preferences: [String: Any]) -> Itinerary {
    guard let duration = preferences["duration"] as? Int else {
        print("Error: Duration not specified in preferences.")
        return Itinerary(destination: destination, days: [], userPreferences: preferences)
    }

    var itineraryDays: [ItineraryDay] = []
    var remainingActivities = activities
    var currentDayNumber = 1

    while currentDayNumber <= duration {
        var currentDayActivities: [Activity] = []
        var currentDayDuration: TimeInterval = 0

        //Try to add activities until the day is full or no activities are left
        while !remainingActivities.isEmpty {
            //Take the first activity
            let activity = remainingActivities.removeFirst()

            //Check if the day has enough time for the activity
            if currentDayDuration + activity.duration <= 28800 { //8 hours
                currentDayActivities.append(activity)
                currentDayDuration += activity.duration
            } else {
                //Not enough room, so put it back in the list
                remainingActivities.insert(activity, at: 0)
                break; // Go to the next day
            }
        }

        let itineraryDay = ItineraryDay(dayNumber: currentDayNumber, activities: currentDayActivities)
        itineraryDays.append(itineraryDay)
        currentDayNumber += 1
    }
    return Itinerary(destination: destination, days: itineraryDays, userPreferences: preferences)
}


// 4. Display the itinerary
func displayItinerary(itinerary: Itinerary) {
    print("\n--- Your Personalized Itinerary for \(itinerary.destination) ---")
    print("Total Cost: $\(String(format: "%.2f", itinerary.totalItineraryCost))")
    print("Total Duration: \(itinerary.totalItineraryDuration/3600) hours")

    for day in itinerary.days {
        print("\nDay \(day.dayNumber):")
        for activity in day.activities {
            print("  - \(activity.name): \(activity.description) (\(activity.category), \(activity.duration / 3600) hours, $\(activity.cost ?? 0))")
        }
        print("  Day Cost: $\(String(format: "%.2f", day.totalCost))")
        print("  Day Duration: \(day.totalDuration / 3600) hours")
    }
}

// 5. Rate the itinerary (allows user to give feedback)
func rateItinerary(itinerary: inout Itinerary) {
    for (dayIndex, day) in itinerary.days.enumerated() {
        for (activityIndex, activity) in day.activities.enumerated() {
            print("How would you rate \(activity.name) on a scale of 1 to 5? (Enter 'skip' to skip)")
            if let ratingString = readLine() {
                if ratingString.lowercased() != "skip", let rating = Double(ratingString), (1...5).contains(rating) {
                    itinerary.days[dayIndex].activities[activityIndex].rating = rating
                }
            }
        }
    }

    print("\n--- Itinerary Ratings ---")
    for day in itinerary.days {
        print("\nDay \(day.dayNumber):")
        for activity in day.activities {
            print("  - \(activity.name): Rating = \(activity.rating ?? 0.0)") // Display rating, default to 0.0 if nil.
        }
    }
}

// MARK: - Main Execution
func main() {
    // 1. Get user preferences
    let userPreferences = getUserPreferences()

    // 2. Extract destination
    guard let destination = userPreferences["destination"] as? String else {
        print("Error: Destination not specified.")
        return
    }

    // 3. Fetch activities based on preferences
    let activities = fetchActivities(destination: destination, preferences: userPreferences)

    // 4. Generate itinerary
    var itinerary = generateItinerary(destination: destination, activities: activities, preferences: userPreferences)

    // 5. Display itinerary
    displayItinerary(itinerary: itinerary)

    // 6. Rate the itinerary and provide feedback (optional)
    rateItinerary(itinerary: &itinerary)

    // At this point, you could store the itinerary and user ratings
    // for future recommendation improvements (machine learning).
}

// Call the main function
main()
```

Key improvements and explanations:

* **Clearer Data Structures:** The `Activity`, `ItineraryDay`, and `Itinerary` structs are well-defined, including computed properties for `totalCost` and `totalDuration`.  Using structs provides value semantics and makes the code more predictable.  I added initializers to the structs for easier object creation.  I made `rating` an optional Double (`Double?`) so that it can be nil if the user hasn't provided a rating yet.
* **`getUserPreferences()` Function:** This function now takes input from the user via the command line to simulate the process of gathering preferences.  Error handling is minimal (it checks if the input is non-empty and can be converted to the correct type).  In a real app, this would be replaced with a UI.
* **`fetchActivities()` Function:** This function simulates fetching activities from a database or API.  It currently uses hardcoded sample data for Paris and London.  The important point is that *this is where you would integrate with external data sources or a recommendation system*.  It also demonstrates a very basic filtering based on `interest`.
* **`generateItinerary()` Function:**  This function generates a *very* basic itinerary. It now makes sure the total duration of activities does not exceed 8 hours per day.  This needs to be replaced with a smarter algorithm that considers factors like travel time between activities, opening hours, user preferences, and optimal sequencing.  The function now includes checks to handle errors (like a missing duration preference).  It also avoids crashing if there are no activities.
* **`displayItinerary()` Function:**  This function formats and prints the generated itinerary to the console.  It displays the total cost and duration of each day.
* **`rateItinerary()` Function:**  This function allows the user to provide feedback by rating each activity.  The ratings are stored within the `Activity` structs in the `Itinerary`.  It includes error handling for invalid ratings and allows the user to skip rating an activity.
* **`main()` Function:** The `main()` function orchestrates the entire process: getting preferences, fetching activities, generating the itinerary, displaying it, and gathering feedback.
* **Error Handling:**  Basic error handling has been added (e.g., checking if the destination is specified).  More robust error handling is needed for a production application.
* **Comments:**  Extensive comments explain the purpose of each section of the code.
* **`TimeInterval` Usage:** I've used `TimeInterval` (which is a `Double` representing seconds) to represent durations, making calculations easier.  Displaying durations is done by dividing by 3600 to get hours.
* **Clearer Output:** The output is formatted to be more readable.
* **`inout` Parameter:**  The `rateItinerary` function uses the `inout` keyword for the `itinerary` parameter, which means it can modify the original itinerary object (specifically, the `rating` properties of the `Activity` structs within the itinerary).  Without `inout`, the function would be working with a copy of the itinerary, and the changes wouldn't be reflected outside the function.

**How to Run This Code:**

1.  **Save:** Save the code as a `.swift` file (e.g., `travel_planner.swift`).
2.  **Compile and Run (Terminal):**
    ```bash
    swift travel_planner.swift
    ```
3.  **Follow Prompts:**  The program will prompt you to enter your travel preferences.

**Next Steps and Enhancements:**

1.  **Data Source Integration:**  Replace the placeholder `fetchActivities()` function with code to query a real database (e.g., SQLite, PostgreSQL) or call an API (e.g., Google Places API, Yelp API, TripAdvisor API).  You'll need to handle API authentication and data parsing.
2.  **Recommendation System:**  Implement a recommendation system using machine learning.  This could be a simple collaborative filtering approach or a more sophisticated content-based filtering or hybrid approach.  You'll need to collect user data (preferences, ratings, past itineraries) to train the model.  Popular ML libraries for Swift include Core ML and Create ML (though they may require bridging to Python for more advanced models).  Consider using a cloud-based ML platform like Google AI Platform or AWS SageMaker.
3.  **Smarter Itinerary Generation:**  Improve the `generateItinerary()` function to consider:
    *   Travel time between activities (use a map API like Google Maps Directions API).
    *   Opening hours of attractions.
    *   User preferences for the order of activities.
    *   Optimal sequencing of activities to minimize travel time.
    *   Prioritization of activities based on user ratings or popularity.
    *   Constraints like budget and time limits.
4.  **User Interface:**  Create a graphical user interface (GUI) using SwiftUI or UIKit to make the application more user-friendly.
5.  **Data Persistence:**  Store user preferences, itineraries, and ratings in a database or file so that they are available across sessions.
6.  **Real-time Updates:**  Integrate with real-time data sources (e.g., weather APIs, traffic APIs) to provide up-to-date information to the user.
7.  **AI-Powered Personalization:**
    *   **Natural Language Processing (NLP):** Use NLP to understand user preferences expressed in natural language.
    *   **Contextual Awareness:**  Consider the user's current location and time of day when making recommendations.
    *   **Dynamic Itinerary Adjustment:**  Adjust the itinerary in real-time based on changing conditions (e.g., weather, traffic).

This is a complex project, but this code provides a solid starting point.  Remember to break down the problem into smaller, manageable tasks and iterate on your solution. Good luck!
👁️ Viewed: 5

Comments