skills/43-wentorai-research-plugins/skills/domains/business/operations-research-guide/SKILL.md
Optimization and operations research methods for business and logistics
npx skillsauth add brycewang-stanford/Awesome-Agent-Skills-for-Empirical-Research operations-research-guideInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
A skill for applying operations research (OR) methods to business, logistics, and resource allocation problems. Covers linear programming, integer programming, scheduling, network optimization, simulation, and decision analysis using Python optimization libraries.
from scipy.optimize import linprog
import numpy as np
def solve_production_planning():
"""
Example: A factory produces two products (A and B).
Product A: profit $40, uses 2h labor + 1kg material
Product B: profit $30, uses 1h labor + 2kg material
Constraints: 100h labor available, 80kg material available
Maximize total profit.
"""
# linprog minimizes, so negate for maximization
c = [-40, -30] # objective coefficients (negated)
# Inequality constraints: A_ub @ x <= b_ub
A_ub = [
[2, 1], # labor constraint
[1, 2], # material constraint
]
b_ub = [100, 80]
# Non-negativity bounds
bounds = [(0, None), (0, None)]
result = linprog(c, A_ub=A_ub, b_ub=b_ub, bounds=bounds, method="highs")
return {
"product_A": result.x[0],
"product_B": result.x[1],
"max_profit": -result.fun,
"status": "optimal" if result.success else "infeasible",
}
from pulp import LpProblem, LpMaximize, LpVariable, lpSum, value
def workforce_scheduling():
"""
Workforce scheduling: minimize staffing cost while meeting
demand for each day of the week. Workers work 5 consecutive days.
"""
days = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
demand = [17, 13, 15, 19, 14, 16, 11]
cost_per_worker = 1 # uniform cost
prob = LpProblem("workforce_scheduling", LpMaximize)
# x[i] = number of workers starting on day i
x = {i: LpVariable(f"start_{days[i]}", lowBound=0, cat="Integer")
for i in range(7)}
# Minimize total workers
prob += -lpSum(x[i] for i in range(7))
# Each day, workers starting on days [d-4, d-3, ..., d] are available
for d in range(7):
workers_available = lpSum(x[(d - j) % 7] for j in range(5))
prob += workers_available >= demand[d], f"demand_{days[d]}"
prob.solve()
return {
"status": prob.status,
"schedule": {days[i]: int(value(x[i])) for i in range(7)},
"total_workers": int(sum(value(x[i]) for i in range(7))),
}
from itertools import combinations
def solve_tsp_mtz(distances: np.ndarray) -> dict:
"""
Solve the Traveling Salesman Problem using Miller-Tucker-Zemlin formulation.
distances: n x n distance matrix
Returns optimal tour and total distance.
"""
from pulp import LpProblem, LpMinimize, LpVariable, LpBinary, lpSum, value
n = len(distances)
prob = LpProblem("TSP", LpMinimize)
# Binary variables: x[i][j] = 1 if edge (i,j) in tour
x = {(i, j): LpVariable(f"x_{i}_{j}", cat=LpBinary)
for i in range(n) for j in range(n) if i != j}
# Subtour elimination variables
u = {i: LpVariable(f"u_{i}", lowBound=1, upBound=n - 1)
for i in range(1, n)}
# Objective: minimize total distance
prob += lpSum(distances[i][j] * x[i, j] for i, j in x)
# Each city visited exactly once
for i in range(n):
prob += lpSum(x[i, j] for j in range(n) if j != i) == 1
prob += lpSum(x[j, i] for j in range(n) if j != i) == 1
# MTZ subtour elimination
for i in range(1, n):
for j in range(1, n):
if i != j:
prob += u[i] - u[j] + (n - 1) * x[i, j] <= n - 2
prob.solve()
# Extract tour
tour = [0]
current = 0
for _ in range(n - 1):
for j in range(n):
if j != current and (current, j) in x and value(x[current, j]) > 0.5:
tour.append(j)
current = j
break
return {
"tour": tour,
"total_distance": value(prob.objective),
}
from math import factorial, exp
def mmc_queue(arrival_rate: float, service_rate: float,
n_servers: int) -> dict:
"""
Analyze an M/M/c queue (Poisson arrivals, exponential service, c servers).
arrival_rate: lambda (customers per unit time)
service_rate: mu (customers served per unit time per server)
n_servers: c (number of parallel servers)
"""
rho = arrival_rate / (n_servers * service_rate)
if rho >= 1:
return {"stable": False, "utilization": rho}
# Erlang C formula: probability of waiting
a = arrival_rate / service_rate
sum_terms = sum(a ** k / factorial(k) for k in range(n_servers))
erlang_c = (a ** n_servers / factorial(n_servers)) / (
(a ** n_servers / factorial(n_servers)) + (1 - rho) * sum_terms
)
# Performance metrics
Lq = erlang_c * rho / (1 - rho) # avg queue length
Wq = Lq / arrival_rate # avg wait time
W = Wq + 1 / service_rate # avg time in system
L = arrival_rate * W # avg number in system
return {
"stable": True,
"utilization": round(rho, 4),
"prob_wait": round(erlang_c, 4),
"avg_queue_length": round(Lq, 4),
"avg_wait_time": round(Wq, 4),
"avg_system_time": round(W, 4),
"avg_in_system": round(L, 4),
}
import simpy
import random
def simulate_service_center(n_servers: int, arrival_rate: float,
service_rate: float, sim_time: float = 480):
"""
Discrete-event simulation of a service center using SimPy.
sim_time: simulation duration in minutes (default 8-hour day).
"""
wait_times = []
def customer(env, server):
arrival_time = env.now
with server.request() as req:
yield req
wait = env.now - arrival_time
wait_times.append(wait)
yield env.timeout(random.expovariate(service_rate))
def customer_generator(env, server):
customer_id = 0
while True:
yield env.timeout(random.expovariate(arrival_rate))
customer_id += 1
env.process(customer(env, server))
env = simpy.Environment()
server = simpy.Resource(env, capacity=n_servers)
env.process(customer_generator(env, server))
env.run(until=sim_time)
return {
"customers_served": len(wait_times),
"avg_wait": np.mean(wait_times) if wait_times else 0,
"max_wait": max(wait_times) if wait_times else 0,
"pct_waited": sum(1 for w in wait_times if w > 0) / len(wait_times) * 100,
}
| Method | Description | Best For | |--------|-------------|----------| | AHP (Analytic Hierarchy Process) | Pairwise comparison matrix | Structured group decisions | | TOPSIS | Distance to ideal/anti-ideal solution | Ranking alternatives | | Weighted scoring | Simple weighted sum | Quick comparisons | | Decision trees | Sequential decision under uncertainty | Multi-stage problems |
development
Conduct rigorous thematic analysis (TA) of qualitative data following Braun and Clarke's (2006) six-phase framework. Use whenever the user mentions 'thematic analysis', 'TA', 'Braun and Clarke', 'qualitative coding', 'identifying themes', or asks for help analysing interviews, focus groups, open-ended survey responses, or transcripts to identify patterns. Also trigger for questions about inductive vs theoretical coding, semantic vs latent themes, essentialist vs constructionist epistemology, building a thematic map, or writing up a qualitative findings section. Covers all six phases, the four upfront analytic decisions, the 15-point quality checklist, and the five common pitfalls. Produces a Word document write-up and an annotated thematic map. Does NOT cover IPA, grounded theory, discourse analysis, conversation analysis, or narrative analysis — use a different method for those.
development
Guide users through writing a systematic literature review (SLR) following the PRISMA 2020 framework. Use this skill whenever the user mentions 'systematic review', 'systematic literature review', 'SLR', 'PRISMA', 'PRISMA 2020', 'PRISMA flow diagram', 'PRISMA checklist', or asks for help writing, structuring, or auditing a literature review that follows reporting guidelines. Also trigger when the user asks about inclusion/exclusion criteria for a review, search strategies for databases like Scopus/WoS/PubMed, study selection processes, risk of bias assessment, or narrative synthesis for a review paper. This skill covers the full PRISMA 2020 checklist (27 items), produces a Word document manuscript in strict journal article format, generates an annotated PRISMA flow diagram, and enforces APA 7th Edition referencing throughout. It does NOT cover meta-analysis or statistical pooling. By Chuah Kee Man.
testing
Performs placebo-in-time sensitivity analysis with hierarchical null model and optional Bayesian assurance. Use when checking model robustness, verifying lack of pre-intervention effects, or estimating study power.
data-ai
Fit, summarize, plot, and interpret a chosen CausalPy experiment. Use after the causal method has been selected, including when configuring PyMC/sklearn models and scale-aware custom priors.