Skip to content

Commit 4ba96ab

Browse files
committed
Add LotteryScheduling new algorithm with Junit tests
1 parent b54cc21 commit 4ba96ab

File tree

3 files changed

+206
-0
lines changed

3 files changed

+206
-0
lines changed

pom.xml

Lines changed: 7 additions & 0 deletions
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>
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
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+
selectedProcess.setWaitingTime(currentTime);
57+
currentTime += selectedProcess.getBurstTime();
58+
selectedProcess.setTurnAroundTime(selectedProcess.getWaitingTime() + selectedProcess.getBurstTime());
59+
60+
executedProcesses.add(selectedProcess);
61+
processes.remove(selectedProcess);
62+
63+
totalTickets = processes.stream().mapToInt(Process::getTickets).sum();
64+
}
65+
66+
return executedProcesses;
67+
}
68+
69+
/**
70+
* Selects a process based on a winning ticket. The method iterates over the
71+
* list of processes, and as the ticket sum accumulates, it checks if the
72+
* current process holds the winning ticket.
73+
*
74+
* @param winningTicket The randomly generated ticket number that determines the selected process.
75+
* @return The process associated with the winning ticket.
76+
*/
77+
private Process selectProcessByTicket(int winningTicket) {
78+
int ticketSum = 0;
79+
for (Process process : processes) {
80+
ticketSum += process.getTickets();
81+
if (ticketSum >= winningTicket) {
82+
return process;
83+
}
84+
}
85+
return null;
86+
}
87+
88+
/**
89+
* The Process class represents a process in the scheduling system. Each process has
90+
* an ID, burst time (CPU time required for execution), number of tickets (used in
91+
* lottery selection), waiting time, and turnaround time.
92+
*/
93+
public static class Process {
94+
private String processId;
95+
private int burstTime;
96+
private int tickets;
97+
private int waitingTime;
98+
private int turnAroundTime;
99+
100+
public Process(String processId, int burstTime, int tickets) {
101+
this.processId = processId;
102+
this.burstTime = burstTime;
103+
this.tickets = tickets;
104+
}
105+
106+
public String getProcessId() {
107+
return processId;
108+
}
109+
110+
public int getBurstTime() {
111+
return burstTime;
112+
}
113+
114+
public int getTickets() {
115+
return tickets;
116+
}
117+
118+
public int getWaitingTime() {
119+
return waitingTime;
120+
}
121+
122+
public void setWaitingTime(int waitingTime) {
123+
this.waitingTime = waitingTime;
124+
}
125+
126+
public int getTurnAroundTime() {
127+
return turnAroundTime;
128+
}
129+
130+
public void setTurnAroundTime(int turnAroundTime) {
131+
this.turnAroundTime = turnAroundTime;
132+
}
133+
}
134+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
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+
// Assert correct number of processes
34+
assertEquals(3, executedProcesses.size());
35+
36+
// Assert the process execution order and properties
37+
LotteryScheduling.Process process1 = executedProcesses.get(0);
38+
assertEquals("P1", process1.getProcessId());
39+
assertEquals(0, process1.getWaitingTime());
40+
assertEquals(10, process1.getTurnAroundTime());
41+
42+
LotteryScheduling.Process process2 = executedProcesses.get(1);
43+
assertEquals("P2", process2.getProcessId());
44+
assertEquals(10, process2.getWaitingTime());
45+
assertEquals(15, process2.getTurnAroundTime());
46+
47+
LotteryScheduling.Process process3 = executedProcesses.get(2);
48+
assertEquals("P3", process3.getProcessId());
49+
assertEquals(15, process3.getWaitingTime());
50+
assertEquals(23, process3.getTurnAroundTime());
51+
}
52+
53+
private List<LotteryScheduling.Process> createProcesses() {
54+
LotteryScheduling.Process process1 = new LotteryScheduling.Process("P1", 10, 10); // 10 tickets
55+
LotteryScheduling.Process process2 = new LotteryScheduling.Process("P2", 5, 5); // 5 tickets
56+
LotteryScheduling.Process process3 = new LotteryScheduling.Process("P3", 8, 8); // 8 tickets
57+
58+
List<LotteryScheduling.Process> processes = new ArrayList<>();
59+
processes.add(process1);
60+
processes.add(process2);
61+
processes.add(process3);
62+
63+
return processes;
64+
}
65+
}

0 commit comments

Comments
 (0)