Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Optimize shared resource pools across multiple construction projects. Balance resource allocation, minimize conflicts, and maximize utilization across the portfolio.
.claude/skills/datadrivenconstruction-resource-pool-optimizer/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-14 | ✗→✓ | ▲ Improved | 169% | 0% |
| case-04 | ✗→✓ | ▲ Improved | 390% | 0% |
| case-08 | ✗→✓ | ▲ Improved | 266% | 0% |
| case-10 | ✗→✓ | ▲ Improved | 248% | 0% |
| case-13 | ✗→✓ | ▲ Improved | 178% | 0% |
Manage and optimize shared resources (equipment, specialized labor, materials) across multiple construction projects. Identify conflicts, balance allocations, and maximize resource utilization while minimizing idle time and project delays.
┌─────────────────────────────────────────────────────────────────┐
│ RESOURCE POOL OPTIMIZATION │
├─────────────────────────────────────────────────────────────────┤
│ │
│ RESOURCE POOL PROJECTS │
│ ───────────── ──────── │
│ 🏗️ Tower Crane A ───────────→ Project 1 (Weeks 1-8) │
│ 🏗️ Tower Crane B ───────────→ Project 2 (Weeks 3-12) │
│ 🔧 Excavator Fleet ─────┬─────→ Project 1 (Weeks 1-4) │
│ └─────→ Project 3 (Weeks 5-10) │
│ 👷 Steel Crew A ───────────→ Project 2 (Weeks 6-15) │
│ 👷 Steel Crew B ─────┬─────→ Project 1 (Weeks 8-14) │
│ └─────→ Project 3 (Weeks 15-20) │
│ │
│ OPTIMIZATION GOALS: │
│ • Minimize idle time between projects │
│ • Avoid double-booking conflicts │
│ • Prioritize critical path activities │
│ • Balance utilization across resources │
│ │
└─────────────────────────────────────────────────────────────────┘pythonfrom dataclasses import dataclass, field from typing import List, Dict, Optional, Tuple, Set from datetime import datetime, timedelta from enum import Enum import heapq class ResourceType(Enum): EQUIPMENT = "equipment" LABOR_CREW = "labor_crew" MATERIAL = "material" SPECIALTY = "specialty" class AllocationStatus(Enum): AVAILABLE = "available" ALLOCATED = "allocated" MAINTENANCE = "maintenance" CONFLICT = "conflict" class Priority(Enum): CRITICAL = 1 HIGH = 2 NORMAL = 3 LOW = 4 @dataclass class Resource: id: str name: str resource_type: ResourceType capacity: float = 1.0 # Can be split (e.g., crew size) daily_cost: float = 0.0 home_location: str = "" mobilization_days: int = 1 skills: List[str] = field(default_factory=list) @dataclass class ResourceRequest: id: str project_id: str project_name: str resource_type: ResourceType required_skills: List[str] start_date: datetime end_date: datetime quantity_needed: float = 1.0 priority: Priority = Priority.NORMAL is_critical_path: bool = False flexibility_days: int = 0 # Can shift by this many days notes: str = "" @dataclass class Allocation: id: str resource_id: str request_id: str project_id: str start_date: datetime end_date: datetime quantity: float status: AllocationStatus = AllocationStatus.ALLOCATED @dataclass class Conflict: resource_id: str resource_name: str date: datetime requests: List[ResourceRequest] total_demand: float available: float resolution_options: List[str] @dataclass class UtilizationReport: resource_id: str resource_name: str period_start: datetime period_end: datetime total_days: int allocated_days: int utilization_pct: float idle_periods: List[Tuple[datetime, datetime]] cost: float class ResourcePoolOptimizer: """Optimize shared resources across projects.""" def __init__(self, pool_name: str): self.pool_name = pool_name self.resources: Dict[str, Resource] = {} self.requests: Dict[str, ResourceRequest] = {} self.allocations: Dict[str, Allocation] = {} def add_resource(self, id: str, name: str, resource_type: ResourceType, capacity: float = 1.0, daily_cost: float = 0.0, skills: List[str] = None) -> Resource: """Add resource to pool.""" resource = Resource( id=id, name=name, resource_type=resource_type, capacity=capacity, daily_cost=daily_cost, skills=skills or [] ) self.resources[id] = resource return resource def add_request(self, project_id: str, project_name: str, resource_type: ResourceType, start_date: datetime, end_date: datetime, quantity: float = 1.0, priority: Priority = Priority.NORMAL, required_skills: List[str] = None, is_critical_path: bool = False, flexibility_days: int = 0) -> ResourceRequest: """Add resource request from project.""" request_id = f"REQ-{project_id}-{len(self.requests)+1:03d}" request = ResourceRequest( id=request_id, project_id=project_id, project_name=project_name, resource_type=resource_type, required_skills=required_skills or [], start_date=start_date, end_date=end_date, quantity_needed=quantity, priority=priority, is_critical_path=is_critical_path, flexibility_days=flexibility_days ) self.requests[request_id] = request return request def find_available_resources(self, request: ResourceRequest) -> List[Tuple[Resource, float]]: """Find resources that can fulfill request.""" available = [] for resource in self.resources.values(): # Check type match if resource.resource_type != request.resource_type: continue # Check skills match if request.required_skills: if not all(skill in resource.skills for skill in request.required_skills): continue # Check availability available_qty = self._get_availability( resource.id, request.start_date, request.end_date ) if available_qty > 0: available.append((resource, available_qty)) return sorted(available, key=lambda x: -x[1]) def _get_availability(self, resource_id: str, start: datetime, end: datetime) -> float: """Get available capacity for resource in period.""" resource = self.resources.get(resource_id) if not resource: return 0 # Find overlapping allocations allocated = 0 for alloc in self.allocations.values(): if alloc.resource_id != resource_id: continue # Check overlap if alloc.start_date < end and alloc.end_date > start: allocated = max(allocated, alloc.quantity) return resource.capacity - allocated def allocate(self, request_id: str, resource_id: str, quantity: float = None) -> Allocation: """Allocate resource to request.""" if request_id not in self.requests: raise ValueError(f"Request {request_id} not found") if resource_id not in self.resources: raise ValueError(f"Resource {resource_id} not found") request = self.requests[request_id] resource = self.resources[resource_id] if quantity is None: quantity = min(request.quantity_needed, resource.capacity) # Check availability available = self._get_availability( resource_id, request.start_date, request.end_date ) if available < quantity: raise ValueError(f"Insufficient capacity. Available: {available}, Requested: {quantity}") alloc_id = f"ALLOC-{len(self.allocations)+1:04d}" allocation = Allocation( id=alloc_id, resource_id=resource_id, request_id=request_id, project_id=request.project_id, start_date=request.start_date, end_date=request.end_date, quantity=quantity ) self.allocations[alloc_id] = allocation return allocation def auto_allocate(self) -> Dict[str, List[Allocation]]: """Automatically allocate resources using priority-based algorithm.""" results = {"allocated": [], "unallocated": [], "conflicts": []} # Sort requests by priority and critical path sorted_requests = sorted( self.requests.values(), key=lambda r: (r.priority.value, not r.is_critical_path, r.start_date) ) for request in sorted_requests: # Check if already allocated existing = [a for a in self.allocations.values() if a.request_id == request.id] if existing: continue # Find available resources available = self.find_available_resources(request) if not available: results["unallocated"].append(request) continue # Allocate best match resource, qty = available[0] try: allocation = self.allocate(request.id, resource.id, min(request.quantity_needed, qty)) results["allocated"].append(allocation) except ValueError: results["conflicts"].append(request) return results def detect_conflicts(self) -> List[Conflict]: """Detect resource conflicts across all requests.""" conflicts = [] # Group requests by resource type by_type: Dict[ResourceType, List[ResourceRequest]] = {} for req in self.requests.values(): if req.resource_type not in by_type: by_type[req.resource_type] = [] by_type[req.resource_type].append(req) # Check each resource type for resource_type, requests in by_type.items(): # Get all resources of this type resources = [r for r in self.resources.values() if r.resource_type == resource_type] total_capacity = sum(r.capacity for r in resources) # Check each day for conflicts all_dates = set() for req in requests: current = req.start_date while current <= req.end_date: all_dates.add(current) current += timedelta(days=1) for date in sorted(all_dates): # Sum demand for this date day_requests = [r for r in requests if r.start_date <= date <= r.end_date] total_demand = sum(r.quantity_needed for r in day_requests) if total_demand > total_capacity: # Generate resolution options options = [] for req in sorted(day_requests, key=lambda x: x.priority.value, reverse=True): if req.flexibility_days > 0: options.append(f"Shift {req.project_name} by {req.flexibility_days} days") options.append("Add additional resource") options.append("Extend work hours") conflict = Conflict( resource_id=resource_type.value, resource_name=resource_type.value, date=date, requests=day_requests, total_demand=total_demand, available=total_capacity, resolution_options=options ) conflicts.append(conflict) return conflicts def calculate_utilization(self, start_date: datetime, end_date: datetime) -> List[UtilizationReport]: """Calculate utilization for all resources.""" reports = [] total_days = (end_date - start_date).days for resource in self.resources.values(): # Find allocations in period allocs = [a for a in self.allocations.values() if a.resource_id == resource.id and a.start_date < end_date and a.end_date > start_date] # Calculate allocated days allocated_dates = set() for alloc in allocs: current = max(alloc.start_date, start_date) while current < min(alloc.end_date, end_date): allocated_dates.add(current) current += timedelta(days=1) allocated_days = len(allocated_dates) utilization = (allocated_days / total_days * 100) if total_days > 0 else 0 # Find idle periods idle_periods = [] all_dates = set() current = start_date while current < end_date: all_dates.add(current) current += timedelta(days=1) idle_dates = sorted(all_dates - allocated_dates) if idle_dates: # Group consecutive idle dates period_start = idle_dates[0] for i, date in enumerate(idle_dates[1:], 1): if (date - idle_dates[i-1]).days > 1: idle_periods.append((period_start, idle_dates[i-1])) period_start = date idle_periods.append((period_start, idle_dates[-1])) cost = allocated_days * resource.daily_cost reports.append(UtilizationReport( resource_id=resource.id, resource_name=resource.name, period_start=start_date, period_end=end_date, total_days=total_days, allocated_days=allocated_days, utilization_pct=utilization, idle_periods=idle_periods, cost=cost )) return sorted(reports, key=lambda x: -x.utilization_pct) def suggest_optimization(self) -> List[Dict]: """Suggest optimizations for resource allocation.""" suggestions = [] # Find underutilized resources util = self.calculate_utilization( datetime.now(), datetime.now() + timedelta(days=90) ) for report in util: if report.utilization_pct < 50: suggestions.append({ "type": "underutilization", "resource": report.resource_name, "utilization": report.utilization_pct, "suggestion": f"Consider reassigning or releasing {report.resource_name}" }) # Find conflicts conflicts = self.detect_conflicts() for conflict in conflicts[:5]: suggestions.append({ "type": "conflict", "date": conflict.date, "demand": conflict.total_demand, "available": conflict.available, "suggestion": conflict.resolution_options[0] if conflict.resolution_options else "Review allocation" }) return suggestions def generate_report(self) -> str: """Generate resource pool report.""" lines = [ "# Resource Pool Optimization Report", "", f"**Pool:** {self.pool_name}", f"**Date:** {datetime.now().strftime('%Y-%m-%d')}", "", "## Resource Inventory", "", "| Resource | Type | Capacity | Daily Cost |", "|----------|------|----------|------------|" ] for r in self.resources.values(): lines.append( f"| {r.name} | {r.resource_type.value} | {r.capacity} | ${r.daily_cost:,.0f} |" ) lines.extend([ "", "## Current Allocations", "", "| Resource | Project | Start | End | Qty |", "|----------|---------|-------|-----|-----|" ]) for alloc in sorted(self.allocations.values(), key=lambda x: x.start_date): resource = self.resources.get(alloc.resource_id) lines.append( f"| {resource.name if resource else alloc.resource_id} | " f"{alloc.project_id} | {alloc.start_date.strftime('%Y-%m-%d')} | " f"{alloc.end_date.strftime('%Y-%m-%d')} | {alloc.quantity} |" ) # Utilization util = self.calculate_utilization( datetime.now(), datetime.now() + timedelta(days=90) ) lines.extend([ "", "## 90-Day Utilization Forecast", "", "| Resource | Utilization | Idle Periods |", "|----------|-------------|--------------|" ]) for report in util: idle_str = f"{len(report.idle_periods)} gaps" if report.idle_periods else "None" lines.append( f"| {report.resource_name} | {report.utilization_pct:.0f}% | {idle_str} |" ) # Conflicts conflicts = self.detect_conflicts() if conflicts: lines.extend([ "", f"## Conflicts Detected ({len(conflicts)})", "", "| Date | Resource | Demand | Available |", "|------|----------|--------|-----------|" ]) for c in conflicts[:10]: lines.append( f"| {c.date.strftime('%Y-%m-%d')} | {c.resource_name} | " f"{c.total_demand} | {c.available} |" ) return "\n".join(lines)
pythonfrom datetime import datetime, timedelta # Initialize optimizer optimizer = ResourcePoolOptimizer("Regional Equipment Pool") # Add resources optimizer.add_resource("CR-001", "Tower Crane Alpha", ResourceType.EQUIPMENT, capacity=1, daily_cost=2500) optimizer.add_resource("CR-002", "Tower Crane Beta", ResourceType.EQUIPMENT, capacity=1, daily_cost=2500) optimizer.add_resource("EX-001", "Excavator Fleet", ResourceType.EQUIPMENT, capacity=3, daily_cost=1500) optimizer.add_resource("SC-001", "Steel Crew A", ResourceType.LABOR_CREW, capacity=1, daily_cost=8000, skills=["structural", "welding"]) # Add requests from projects optimizer.add_request( "PRJ-001", "Downtown Tower", ResourceType.EQUIPMENT, start_date=datetime(2025, 2, 1), end_date=datetime(2025, 6, 30), quantity=1, priority=Priority.HIGH, is_critical_path=True ) optimizer.add_request( "PRJ-002", "Hospital Wing", ResourceType.EQUIPMENT, start_date=datetime(2025, 3, 1), end_date=datetime(2025, 8, 31), quantity=1, priority=Priority.NORMAL, flexibility_days=14 ) # Auto-allocate resources results = optimizer.auto_allocate() print(f"Allocated: {len(results['allocated'])}") print(f"Unallocated: {len(results['unallocated'])}") # Detect conflicts conflicts = optimizer.detect_conflicts() print(f"Conflicts: {len(conflicts)}") # Get optimization suggestions suggestions = optimizer.suggest_optimization() for s in suggestions[:5]: print(f"{s['type']}: {s['suggestion']}") # Generate report print(optimizer.generate_report())
bashpip install (no external dependencies)
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-14 | fail→pass | 12,341 | 2,557 | -79% | 1 | 1 | 0% | 1,969 | 5,294 | +169% | 0 | 0 | — |
case-15 | pass→pass | 7,823 | 3,652 | -53% | 1 | 1 | 0% | 1,328 | 5,513 | +315% | 0 | 0 | — |
case-01 | pass→pass | 10,422 | 14,665 | +41% | 1 | 1 | 0% | 1,880 | 7,629 | +306% | 0 | 0 | — |
case-02 | pass→pass | 15,378 | 7,367 | -52% | 1 | 1 | 0% | 2,716 | 6,271 | +131% | 0 | 0 | — |
case-03 | fail→fail | 6,829 | 7,615 | +12% | 1 | 1 | 0% | 1,377 | 6,301 | +358% | 0 | 0 | — |
case-04 | fail→pass | 6,813 | 3,526 | -48% | 1 | 1 | 0% | 1,143 | 5,595 | +390% | 0 | 0 | — |
case-05 | pass→pass | 3,199 | 3,861 | +21% | 1 | 1 | 0% | 528 | 5,587 | +958% | 0 | 0 | — |
case-06 | pass→pass | 7,179 | 5,970 | -17% | 1 | 1 | 0% | 1,330 | 6,039 | +354% | 0 | 0 | — |
case-07 | pass→pass | 5,308 | 4,141 | -22% | 1 | 1 | 0% | 796 | 5,651 | +610% | 0 | 0 | — |
case-08 | fail→pass | 10,311 | 7,049 | -32% | 1 | 1 | 0% | 1,680 | 6,142 | +266% | 0 | 0 | — |
case-09 | pass→pass | 6,127 | 3,322 | -46% | 1 | 1 | 0% | 984 | 5,434 | +452% | 0 | 0 | — |
case-10 | fail→pass | 13,846 | 12,533 | -9% | 1 | 1 | 0% | 1,970 | 6,848 | +248% | 0 | 0 | — |
case-11 | pass→pass | 3,850 | 3,562 | -7% | 1 | 1 | 0% | 631 | 5,543 | +778% | 0 | 0 | — |
case-12 | pass→pass | 5,482 | 4,895 | -11% | 1 | 1 | 0% | 916 | 5,774 | +530% | 0 | 0 | — |
case-13 | fail→pass | 13,780 | 8,733 | -37% | 1 | 1 | 0% | 2,468 | 6,861 | +178% | 0 | 0 | — |
case-16 | pass→pass | 7,462 | 4,111 | -45% | 1 | 1 | 0% | 1,108 | 5,655 | +410% | 0 | 0 | — |
case-17 | fail→pass | 9,622 | 3,633 | -62% | 1 | 1 | 0% | 1,422 | 5,538 | +289% | 0 | 0 | — |
case-18 | fail→pass | 21,224 | 3,331 | -84% | 1 | 1 | 0% | 1,090 | 5,447 | +400% | 0 | 0 | — |
case-19 | fail→pass | 7,356 | 3,515 | -52% | 1 | 1 | 0% | 1,190 | 5,452 | +358% | 0 | 0 | — |
case-20 | fail→pass | 18,050 | 2,985 | -83% | 1 | 1 | 0% | 1,242 | 5,297 | +326% | 0 | 0 | — |
case-21 | pass→pass | 8,542 | 2,757 | -68% | 1 | 1 | 0% | 1,256 | 5,350 | +326% | 0 | 0 | — |
case-22 | pass→pass | 4,401 | 3,892 | -12% | 1 | 1 | 0% | 828 | 5,594 | +576% | 0 | 0 | — |
case-23 | pass→pass | 5,964 | 6,587 | +10% | 1 | 1 | 0% | 1,175 | 6,096 | +419% | 0 | 0 | — |
case-24 | pass→pass | 18,699 | 18,774 | +0% | 1 | 1 | 0% | 2,829 | 7,657 | +171% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 24 cases were attempted, and 23 counted toward the lift figure. The other 1 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +38 percentage points is the difference between those two pass rates over the 23 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.