# DJ Scoring Calculation

## 1. Introduction

The **DJ Scoring function** provides a transparent and equitable method to quantify each DJ’s suitability for any given slot. It does so by taking into account historical participation data and role-based modifiers. This approach computes a score for each DJ–slot pair. These scores are then used to build a cost matrix for global optimization using the Hungarian algorithm, ensuring that all available slots are optimally filled while also attempting to honor DJ preferences.

The function uses mathematical techniques—such as normalization, nonlinear scaling, and weighted sums—to minimize bias and highlight the differences among DJs, particularly rewarding those who have played less frequently and have not played recently.

***

## 2. Algorithm Logic

The algorithm follows these steps:

### 2.1 Input Processing

Contestant data includes:

* The total number of times a contestant has participated.
* The time elapsed since their last participation.
* A status that can grant a participation bonus [(if set up)](/functionalities/commands/server-commands/setup.md#dj-role-2)

### 2.2 Normalization

Values for participation history and time elapsed since the last participation are normalized using absolute ranges to ensure that all contestants are compared on a fair scale.

### 2.3 Weighting and Scaling

Weights are assigned to prioritize factors (e.g., participation frequency or recency). A nonlinear scaling function is applied to emphasize differences between contestants.

### 2.4 Role Bonus Calculation [(if set up)](/functionalities/commands/server-commands/setup.md#dj-role-2)

Contestants with specific roles receive additional score bonuses based on their normalized performance.

### 2.5 Score Aggregation

The final score combines the weighted normalized values and the role bonus. Contestants are ranked by their score.

### 2.6 Tie-breaking

If two or more DJs have identical scores, a random selection is used to break the tie, with the winner being randomly picked from the DJs with the highest score.

***

## 3. Mathematical Model

### 3.1 Variables

We define the following variables for each DJ `i ∈ N`:

* `Ti`: The total number of times DJ `i` has performed.
* `Di`: The number of days since DJ `i` last performed.
* `Ri`: The role of DJ `i` in the contest (e.g., `dj1role`, `dj2role`, `dj3role`).

Additionally, we define the following global variables:

* `max(T)`: The maximum value of `TimesPlayed` across all DJs.
* `min(T)`: The minimum value of `TimesPlayed` across all DJs.
* `max(D)`: The maximum value of `DaysSinceLastPlayed` across all DJs.
* `min(D)`: The minimum value of `DaysSinceLastPlayed` across all DJs.

### 3.2 Normalization of Factors

To ensure all DJ scores are on a comparable scale, the algorithm normalizes both `TimesPlayed` and `DaysSinceLastPlayed`. This ensures that the scores reflect relative differences between DJs, irrespective of the absolute values.

#### 3.2.1 Normalizing Times Played

The first step is to normalize the `TimesPlayed` value for each DJ. The normalization process scales the number of performances based on the range of `TimesPlayed` across all DJs. The normalized value is computed using the formula:

$$
Normalized\_TimesPlayed\_i = \left(\frac{ \text{max}(T) - T\_i}{\max(1, \text{max}(T) - \text{min}(T))}\right)^2
$$

Where:

* `max(T)` and `min(T)` represent the maximum and minimum values of `TimesPlayed` across all DJs, respectively.
* `Ti` is the `TimesPlayed` value for DJ `i`.

This formula applies a quadratic scaling to the normalized value, emphasizing the relative difference between DJs with fewer performances.

#### 3.2.2 Normalizing Days Since Last Played

Similarly, the algorithm normalizes the `DaysSinceLastPlayed` value for each DJ, considering the number of days since the DJ’s last performance. This is important because more recent performances should be weighted more heavily. The formula for normalization is:

$$
Normalized\_DaysSinceLastPlayed\_i = \left(\frac{D\_i - \text{min}(D)}{\max(1, \text{max}(D) - \text{min}(D))}\right)^2
$$

Where:

* `max(D)` and `min(D)` represent the maximum and minimum values of `DaysSinceLastPlayed` across all DJs.
* `Di` is the `DaysSinceLastPlayed` value for DJ `i`.

The quadratic scaling used in this formula ensures that DJs with more recent performances receive a higher normalized score.

***

### 3.3 Role-Based Bonus Calculation

If set up, each DJ’s role within the contest can influence their final score through a bonus system. The algorithm assigns a predefined bonus based on the DJ’s role

* `dj1role`: No bonus (`0`).
* `dj2role`: A bonus of `0.15`.
* `dj3role`: A bonus of `0.30`.

The role-based bonus for each DJ is calculated as follows:

$$
RoleBonus\_i = \text{maxBonus}(R\_i) \times \left( \frac{(\text{weightTimesPlayed} \times \text{Normalized\_TimesPlayed}\_i) + (\text{weightDaysSinceLastPlayed} \times \text{Normalized\_DaysSinceLastPlayed}\_i)}{2} \right)
$$

Where:

* `maxBonus(Ri)` represents the maximum role bonus for the DJ’s role.
* `weightTimesPlayed` and `weightDaysSinceLastPlayed` are predefined weights that control the influence of the two factors: `TimesPlayed` and `DaysSinceLastPlayed`.

### 3.4 Final Score Calculation

The final score for each DJ is computed by combining the normalized values for `TimesPlayed` and `DaysSinceLastPlayed`, along with the role-based bonus. The formula for the final score is:

$$
Score\_i = (\text{weightTimesPlayed} \times \text{Normalized\_TimesPlayed}\_i) + (\text{weightDaysSinceLastPlayed} \times \text{Normalized\_DaysSinceLastPlayed}\_i) + \text{RoleBonus}\_i
$$

Where:

* `weightTimesPlayed` is set to `0.45`
* `weightDaysSinceLastPlayed` is set to `0.55`

This weighted sum combines all factors into a single score for each DJ, which determines their ranking in the contest.

### 3.5 Winner Selection

Once all DJs have been scored, the winner is determined by selecting the DJ with the highest score. Let `S` be the set of all computed scores for the DJs:

$$
S = {Score\_1, Score\_2, …, Score\_n}
$$

The winner is the DJ with the maximum score:

$$
Winner = \arg\max\_{i \in N} (\text{Score}\_i)
$$

If there is a tie, meaning multiple DJs have the same highest score, the winner is randomly selected from the DJs with the maximum score.

***

## 4. Conclusion

This algorithm provides an efficient and fair method for selecting the winner of a DJ contest, by considering both the frequency and recency of performances, as well as the DJ's role. The nonlinear normalization ensures that recent performances have a larger impact on the score, and the role-based bonuses allow for differentiation between DJs based on their assigned roles. The final score reflects these factors and determines the winner in a transparent manner.

The algorithm is robust to ties, offering a fair resolution through random selection from the top scorers. This approach ensures that DJs are evaluated comprehensively and that the contest winner is chosen based on a clear, quantifiable process.

***

## Notes

* The algorithm’s effectiveness depends on the accuracy of the input data for `TimesPlayed` and `DaysSinceLastPlayed`.
* The role bonuses allow for flexibility in determining how different roles impact the final result.
* The quadratic scaling in the normalization steps helps to emphasize the relative differences, particularly when DJs are far apart in their performance history.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.vrave.app/functionalities/slot-assignment-algorithm/dj-scoring-calculation.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
