You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R语言simmer仿真中自定义动态weight队列优先级策略的实现问询

Absolutely! You can absolutely build a custom scheduling logic in simmer to handle this dynamic weight-based priority—this is one of the package's greatest strengths for flexible simulation workflows. Let me break down exactly how to implement it with code examples you can adapt for your use case.

Custom Dynamic Weight Scheduling in simmer

Step 1: Store Task Attributes on Arrival

First, you need to capture each task's core attributes (base priority and arrival time) when it enters the simulation. These will be used to calculate the dynamic weight later.

library(simmer)

# Define the task trajectory: capture base priority and arrival time
task_trajectory <- trajectory() %>%
  # Assign a random base priority (adjust this to match your actual task data)
  set_attribute("base_priority", function() sample(1:5, 1)) %>%
  # Store the exact time the task arrives in the system
  set_attribute("arrival_time", function() now(env)) %>%
  # Seize the processing resource (priority logic is handled via custom selection)
  seize("processing_resource") %>%
  # Simulate processing time (adjust duration to match your task requirements)
  timeout(function() sample(3600:10800, 1)) %>%  # 1-3 hours in seconds
  release("processing_resource")

Step 2: Define Custom Weight Calculation & Task Selection

Next, create a custom selection function that evaluates every task in the waiting list, computes its dynamic weight using your formula, and picks the task with the highest weight.

For example, we'll use a weight formula like:
weight = base_priority + (waiting_days * 2)
(tweak the multiplier or formula to fit your specific business rules)

# Custom function to select the task with the highest dynamic weight
select_highest_weight <- function(queue) {
  # Calculate weight for each task in the waiting queue
  task_weights <- sapply(queue, function(task) {
    # Extract stored task attributes
    base_prio <- task$attributes$base_priority
    arrival_time <- task$attributes$arrival_time
    
    # Convert waiting time from seconds to days
    waiting_days <- (now(task$env) - arrival_time) / 86400
    
    # Compute dynamic weight per your logic
    base_prio + (waiting_days * 2)
  })
  
  # Return the index of the task with the maximum weight
  which.max(task_weights)
}

Step 3: Set Up the Simulation Environment

Create your simulation environment, attach the resource with your custom selection function, and add the task generator.

# Initialize simulation environment
sim_env <- simmer() %>%
  # Add processing resource with custom selection logic
  add_resource(
    name = "processing_resource",
    capacity = 1,  # Adjust to match your number of parallel processors
    queue_size = Inf,  # Allow unlimited tasks in the waiting list
    select = select_highest_weight  # Use our custom task picker
  ) %>%
  # Add task generator (adjust inter-arrival time to match your scenario)
  add_generator(
    name_prefix = "task",
    trajectory = task_trajectory,
    distribution = function() rexp(1, 1/86400)  # ~1 task per day on average
  )

# Run the simulation for 7 days (adjust duration as needed)
sim_env %>% run(until = 7 * 86400)

Optional: Add Preemption for Higher Weight Tasks

If you want to allow a waiting task with a newly increased weight to preempt a task currently being processed, add a custom preemption check function:

# Custom preemption logic: preempt if a waiting task has higher weight than the running one
preempt_for_higher_weight <- function(running_task, waiting_queue) {
  # Calculate weight for the currently running task
  running_weight <- {
    base_prio <- running_task$attributes$base_priority
    arrival_time <- running_task$attributes$arrival_time
    waiting_days <- (now(running_task$env) - arrival_time) / 86400
    base_prio + (waiting_days * 2)
  }
  
  # Calculate maximum weight in the waiting queue
  queue_weights <- sapply(waiting_queue, function(task) {
    base_prio <- task$attributes$base_priority
    arrival_time <- task$attributes$arrival_time
    waiting_days <- (now(task$env) - arrival_time) / 86400
    base_prio + (waiting_days * 2)
  })
  max_queue_weight <- max(queue_weights)
  
  # Return TRUE to preempt if the queue has a higher-weight task
  max_queue_weight > running_weight
}

Update the resource definition to include preemption:

sim_env_with_preemption <- simmer() %>%
  add_resource(
    name = "processing_resource",
    capacity = 1,
    queue_size = Inf,
    select = select_highest_weight,
    preemptive = TRUE,  # Enable preemption functionality
    preempt = preempt_for_higher_weight,  # Use our custom preemption logic
    preempt_order = "priority"  # Resume preempted tasks based on weight later
  ) %>%
  add_generator("task", task_trajectory, function() rexp(1, 1/86400))

sim_env_with_preemption %>% run(until = 7 * 86400)

Key Notes

  • Adjust the Weight Formula: Modify the calculation in select_highest_weight to match your exact business rules (e.g., exponential weight increase, different multipliers for priority levels).
  • Extend Attributes: You can add more task-specific attributes (like task type or complexity) to the trajectory and include them in your weight calculation if needed.
  • Resource Capacity: Tweak the capacity parameter in add_resource to match the number of parallel workers in your real-world scenario.

内容的提问来源于stack exchange,提问作者Roos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 09:07:43