Skip to content

Commit 0020ab2

Browse files
authored
Add LotteryScheduling algorithm (#5656)
1 parent 213fd5a commit 0020ab2

File tree

4 files changed

+214
-0
lines changed

4 files changed

+214
-0
lines changed

DIRECTORY.md

+2
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,7 @@
504504
* [FCFSScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/FCFSScheduling.java)
505505
* [HighestResponseRatioNextScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/HighestResponseRatioNextScheduling.java)
506506
* [JobSchedulingWithDeadline](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/JobSchedulingWithDeadline.java)
507+
* [LotteryScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/LotteryScheduling.java)
507508
* [MLFQScheduler](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/MLFQScheduler.java)
508509
* [NonPreemptivePriorityScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/NonPreemptivePriorityScheduling.java)
509510
* [PreemptivePriorityScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/PreemptivePriorityScheduling.java)
@@ -1039,6 +1040,7 @@
10391040
* [FCFSSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/FCFSSchedulingTest.java)
10401041
* [HighestResponseRatioNextSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/HighestResponseRatioNextSchedulingTest.java)
10411042
* [JobSchedulingWithDeadlineTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/JobSchedulingWithDeadlineTest.java)
1043+
* [LotterySchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/LotterySchedulingTest.java)
10421044
* [MLFQSchedulerTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/MLFQSchedulerTest.java)
10431045
* [NonPreemptivePrioritySchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/NonPreemptivePrioritySchedulingTest.java)
10441046
* [PreemptivePrioritySchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/PreemptivePrioritySchedulingTest.java)

pom.xml

+7
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,13 @@
4040
<version>${assertj.version}</version>
4141
<scope>test</scope>
4242
</dependency>
43+
<dependency>
44+
<groupId>org.mockito</groupId>
45+
<artifactId>mockito-core</artifactId>
46+
<version>5.14.1</version>
47+
<scope>test</scope>
48+
</dependency>
49+
4350

4451
<dependency>
4552
<groupId>org.junit.jupiter</groupId>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
package com.thealgorithms.scheduling;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
import java.util.Random;
6+
7+
/**
8+
* The LotteryScheduling class implements the Lottery Scheduling algorithm, which is
9+
* a probabilistic CPU scheduling algorithm. Processes are assigned tickets, and
10+
* the CPU is allocated to a randomly selected process based on ticket count.
11+
* Processes with more tickets have a higher chance of being selected.
12+
*/
13+
public final class LotteryScheduling {
14+
private LotteryScheduling() {
15+
}
16+
17+
private List<Process> processes;
18+
private Random random;
19+
20+
/**
21+
* Constructs a LotteryScheduling object with the provided list of processes.
22+
*
23+
* @param processes List of processes to be scheduled using Lottery Scheduling.
24+
*/
25+
public LotteryScheduling(final List<Process> processes) {
26+
this.processes = processes;
27+
this.random = new Random();
28+
}
29+
30+
/**
31+
* Constructs a LotteryScheduling object with the provided list of processes and a Random object.
32+
*
33+
* @param processes List of processes to be scheduled using Lottery Scheduling.
34+
* @param random Random object used for generating random numbers.
35+
*/
36+
public LotteryScheduling(final List<Process> processes, Random random) {
37+
this.processes = processes;
38+
this.random = random;
39+
}
40+
41+
/**
42+
* Schedules the processes using the Lottery Scheduling algorithm.
43+
* Each process is assigned a certain number of tickets, and the algorithm randomly
44+
* selects a process to execute based on ticket count. The method calculates the
45+
* waiting time and turnaround time for each process and simulates their execution.
46+
*/
47+
public List<Process> scheduleProcesses() {
48+
int totalTickets = processes.stream().mapToInt(Process::getTickets).sum();
49+
int currentTime = 0;
50+
List<Process> executedProcesses = new ArrayList<>();
51+
52+
while (!processes.isEmpty()) {
53+
int winningTicket = random.nextInt(totalTickets) + 1;
54+
Process selectedProcess = selectProcessByTicket(winningTicket);
55+
56+
if (selectedProcess == null) {
57+
// This should not happen in normal circumstances, but we'll handle it just in case
58+
System.err.println("Error: No process selected. Recalculating total tickets.");
59+
totalTickets = processes.stream().mapToInt(Process::getTickets).sum();
60+
continue;
61+
}
62+
63+
selectedProcess.setWaitingTime(currentTime);
64+
currentTime += selectedProcess.getBurstTime();
65+
selectedProcess.setTurnAroundTime(selectedProcess.getWaitingTime() + selectedProcess.getBurstTime());
66+
67+
executedProcesses.add(selectedProcess);
68+
processes.remove(selectedProcess);
69+
70+
totalTickets = processes.stream().mapToInt(Process::getTickets).sum();
71+
}
72+
73+
return executedProcesses;
74+
}
75+
76+
/**
77+
* Selects a process based on a winning ticket. The method iterates over the
78+
* list of processes, and as the ticket sum accumulates, it checks if the
79+
* current process holds the winning ticket.
80+
*
81+
* @param winningTicket The randomly generated ticket number that determines the selected process.
82+
* @return The process associated with the winning ticket.
83+
*/
84+
private Process selectProcessByTicket(int winningTicket) {
85+
int ticketSum = 0;
86+
for (Process process : processes) {
87+
ticketSum += process.getTickets();
88+
if (ticketSum >= winningTicket) {
89+
return process;
90+
}
91+
}
92+
return null;
93+
}
94+
95+
/**
96+
* The Process class represents a process in the scheduling system. Each process has
97+
* an ID, burst time (CPU time required for execution), number of tickets (used in
98+
* lottery selection), waiting time, and turnaround time.
99+
*/
100+
public static class Process {
101+
private String processId;
102+
private int burstTime;
103+
private int tickets;
104+
private int waitingTime;
105+
private int turnAroundTime;
106+
107+
public Process(String processId, int burstTime, int tickets) {
108+
this.processId = processId;
109+
this.burstTime = burstTime;
110+
this.tickets = tickets;
111+
}
112+
113+
public String getProcessId() {
114+
return processId;
115+
}
116+
117+
public int getBurstTime() {
118+
return burstTime;
119+
}
120+
121+
public int getTickets() {
122+
return tickets;
123+
}
124+
125+
public int getWaitingTime() {
126+
return waitingTime;
127+
}
128+
129+
public void setWaitingTime(int waitingTime) {
130+
this.waitingTime = waitingTime;
131+
}
132+
133+
public int getTurnAroundTime() {
134+
return turnAroundTime;
135+
}
136+
137+
public void setTurnAroundTime(int turnAroundTime) {
138+
this.turnAroundTime = turnAroundTime;
139+
}
140+
}
141+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package com.thealgorithms.scheduling;
2+
3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
import static org.mockito.Mockito.mock;
5+
import static org.mockito.Mockito.when;
6+
7+
import java.util.ArrayList;
8+
import java.util.List;
9+
import java.util.Random;
10+
import org.junit.jupiter.api.BeforeEach;
11+
import org.junit.jupiter.api.Test;
12+
13+
public class LotterySchedulingTest {
14+
15+
private Random mockRandom;
16+
17+
@BeforeEach
18+
public void setup() {
19+
mockRandom = mock(Random.class);
20+
}
21+
22+
@Test
23+
public void testLotterySchedulingWithMockedRandom() {
24+
List<LotteryScheduling.Process> processes = createProcesses();
25+
LotteryScheduling lotteryScheduling = new LotteryScheduling(processes, mockRandom);
26+
27+
// Mock the sequence of random numbers (winning tickets)
28+
// This sequence ensures that P1 (10 tickets), P3 (8 tickets), and P2 (5 tickets) are selected.
29+
when(mockRandom.nextInt(23)).thenReturn(5, 18, 11); // winning tickets for P1, P3, and P2
30+
31+
List<LotteryScheduling.Process> executedProcesses = lotteryScheduling.scheduleProcesses();
32+
33+
assertEquals(3, executedProcesses.size());
34+
35+
// Assert the process execution order and properties
36+
LotteryScheduling.Process process1 = executedProcesses.get(0);
37+
assertEquals("P1", process1.getProcessId());
38+
assertEquals(0, process1.getWaitingTime());
39+
assertEquals(10, process1.getTurnAroundTime());
40+
41+
LotteryScheduling.Process process2 = executedProcesses.get(1);
42+
assertEquals("P2", process2.getProcessId());
43+
assertEquals(10, process2.getWaitingTime());
44+
assertEquals(15, process2.getTurnAroundTime());
45+
46+
LotteryScheduling.Process process3 = executedProcesses.get(2);
47+
assertEquals("P3", process3.getProcessId());
48+
assertEquals(15, process3.getWaitingTime());
49+
assertEquals(23, process3.getTurnAroundTime());
50+
}
51+
52+
private List<LotteryScheduling.Process> createProcesses() {
53+
LotteryScheduling.Process process1 = new LotteryScheduling.Process("P1", 10, 10); // 10 tickets
54+
LotteryScheduling.Process process2 = new LotteryScheduling.Process("P2", 5, 5); // 5 tickets
55+
LotteryScheduling.Process process3 = new LotteryScheduling.Process("P3", 8, 8); // 8 tickets
56+
57+
List<LotteryScheduling.Process> processes = new ArrayList<>();
58+
processes.add(process1);
59+
processes.add(process2);
60+
processes.add(process3);
61+
62+
return processes;
63+
}
64+
}

0 commit comments

Comments
 (0)