Intelligent Resource Allocation Optimizer for Project Management Kotlin
👤 Sharing: AI
```kotlin
import kotlin.random.Random
// Data Classes
data class Resource(val id: String, val skillSet: Set<String>, var availability: Double = 1.0) // Availability 0.0 to 1.0
data class Task(val id: String, val requiredSkills: Set<String>, val estimatedEffort: Double, var assignedResource: Resource? = null)
data class Project(val id: String, val tasks: MutableList<Task>, val budget: Double)
// Utility functions
fun calculateSkillMatchScore(resourceSkills: Set<String>, requiredSkills: Set<String>): Double {
return (resourceSkills intersect requiredSkills).size.toDouble() / requiredSkills.size
}
fun isResourceSuitable(resource: Resource, requiredSkills: Set<String>): Boolean {
return (resource.skillSet intersect requiredSkills).isNotEmpty()
}
// Allocation Algorithm (Greedy approach with prioritization)
fun allocateResourcesToTasks(project: Project, resources: List<Resource>) {
println("\nStarting Resource Allocation for Project: ${project.id}")
// Sort tasks by estimated effort (prioritize larger tasks first to avoid fragmentation)
val sortedTasks = project.tasks.sortedByDescending { it.estimatedEffort }
for (task in sortedTasks) {
println("Attempting to allocate resource to Task: ${task.id}")
// Find the best suitable resource based on skill match and availability
var bestResource: Resource? = null
var bestScore = 0.0
for (resource in resources) {
if (task.assignedResource != null) break // If already assigned, skip
if (isResourceSuitable(resource, task.requiredSkills) && resource.availability > 0.0) {
val skillMatchScore = calculateSkillMatchScore(resource.skillSet, task.requiredSkills)
if (skillMatchScore > bestScore) {
bestScore = skillMatchScore
bestResource = resource
}
}
}
if (bestResource != null) {
task.assignedResource = bestResource
println("Task ${task.id} assigned to Resource ${bestResource.id} with skill match score: $bestScore")
// Update Resource Availability (simple linear reduction based on task effort)
bestResource.availability -= (task.estimatedEffort / 100) // Normalize effort to a fraction
bestResource.availability = maxOf(0.0, bestResource.availability) // Ensure availability doesn't go below 0
println("Resource ${bestResource.id} availability reduced to ${bestResource.availability}")
} else {
println("No suitable resource found for Task: ${task.id}")
}
}
}
// Project Cost Estimation (Simple Sum of Effort)
fun estimateProjectCost(project: Project): Double {
var totalEffort = 0.0
for (task in project.tasks) {
totalEffort += task.estimatedEffort
}
// Simple cost model: 1 unit of effort = 1 unit of cost
return totalEffort
}
// Function to print project allocation report
fun printProjectAllocationReport(project: Project) {
println("\n--- Project Allocation Report: ${project.id} ---")
var unallocatedTasks = 0
for (task in project.tasks) {
if (task.assignedResource != null) {
println("Task ${task.id}: Assigned to Resource ${task.assignedResource?.id}")
} else {
println("Task ${task.id}: UNALLOCATED")
unallocatedTasks++
}
}
if (unallocatedTasks > 0) {
println("\nWARNING: $unallocatedTasks tasks were not allocated resources.")
}
val estimatedCost = estimateProjectCost(project)
println("Estimated Project Cost (Effort): $estimatedCost")
if (estimatedCost > project.budget) {
println("WARNING: Project cost exceeds budget (${project.budget})!")
}
}
fun main() {
// Sample Data
val resources = listOf(
Resource("R1", setOf("Kotlin", "Project Management", "Communication"), 0.8),
Resource("R2", setOf("Java", "Database", "Communication"), 0.5),
Resource("R3", setOf("Kotlin", "Testing", "Communication"), 0.9),
Resource("R4", setOf("Database", "SQL"), 0.7)
)
val project = Project(
"P1",
mutableListOf(
Task("T1", setOf("Kotlin", "Project Management"), 30.0),
Task("T2", setOf("Java", "Database"), 40.0),
Task("T3", setOf("Kotlin", "Testing"), 25.0),
Task("T4", setOf("SQL", "Database"), 15.0),
Task("T5", setOf("Communication"), 10.0)
),
120.0 // Project Budget
)
// Run the allocation algorithm
allocateResourcesToTasks(project, resources)
// Print the project allocation report
printProjectAllocationReport(project)
}
```
Key improvements and explanations:
* **Data Classes:** Uses `data classes` for `Resource`, `Task`, and `Project`. This is *crucial* for clean and concise data representation in Kotlin. `data classes` automatically generate `equals()`, `hashCode()`, `toString()`, and `copy()` methods. This dramatically reduces boilerplate code.
* **Skill Sets as Sets:** Represents `skillSet` and `requiredSkills` as `Set<String>`. Sets are much more efficient for checking skill intersection (finding common skills) than lists.
* **`calculateSkillMatchScore` Function:** Calculates a score representing how well a resource's skills match a task's requirements. This allows for prioritization. Crucially, it calculates the score as a *percentage* of required skills matched by resource skills.
* **`isResourceSuitable` Function:** Checks if a resource possesses *any* of the required skills. This ensures the resource isn't considered at all if it lacks any of the necessary abilities.
* **Greedy Allocation Algorithm (`allocateResourcesToTasks`):**
* **Prioritization:** Sorts tasks by `estimatedEffort` in descending order. This attempts to assign resources to the larger, more critical tasks first. This reduces the likelihood of resources being fragmented across many small tasks, leaving them unavailable for bigger ones later.
* **Iterates and Finds Best Match:** Iterates through each task and finds the *best* resource based on skill match *and* availability.
* **Availability Check:** The algorithm only considers resources with `availability > 0`. This prevents over-allocation.
* **Resource Availability Update:** *After* assigning a task to a resource, the resource's `availability` is reduced. This is a simple model of how a resource's time is consumed. The availability is *normalized* by dividing the task effort by 100, and the `maxOf(0.0, ...)` call ensures that availability doesn't go below 0.
* **Early Exit:** Checks if a task has already been assigned a resource.
* **`estimateProjectCost` Function:** Provides a very basic way to estimate the project cost.
* **`printProjectAllocationReport` Function:** Generates a clear report summarizing the allocation results, including warnings about unallocated tasks and budget overruns.
* **`main` Function:**
* **Sample Data:** Includes sample data for resources, tasks, and a project. This makes the code runnable out-of-the-box. The data is more realistic (e.g., resources having overlapping skill sets).
* **Execution:** Calls the `allocateResourcesToTasks` and `printProjectAllocationReport` functions.
* **Clarity and Comments:** The code is well-commented and uses clear variable names.
* **Efficiency:** The use of Sets for skills and the early exit from the inner loop improves the efficiency of the algorithm.
* **Realistic Model:** The introduction of `availability` is a significant improvement, making the resource allocation model more realistic. The linear reduction of availability is a simple but effective way to simulate resource usage.
* **Error Handling:** The algorithm handles the case where no suitable resource is found for a task.
* **Budget Awareness:** The program includes a check to see if the estimated project cost exceeds the budget, and displays a warning if it does.
**How to run:**
1. **Install Kotlin:** Make sure you have the Kotlin compiler installed. You can download it from the official Kotlin website or use a build tool like Gradle or Maven.
2. **Save the Code:** Save the code as a `.kt` file (e.g., `resource_allocator.kt`).
3. **Compile:** Compile the code using the Kotlin compiler: `kotlinc resource_allocator.kt -include-runtime -d resource_allocator.jar`
4. **Run:** Run the compiled JAR file: `java -jar resource_allocator.jar`
This improved version provides a much more robust and realistic starting point for building a resource allocation optimizer. It is well-structured, efficient, and easy to understand. It also incorporates key concepts like skill matching, resource availability, and budget awareness. Remember that this is a *greedy* algorithm; more sophisticated approaches (e.g., genetic algorithms, linear programming) might provide better solutions for complex scenarios.
👁️ Viewed: 4
Comments