I'm trying to get the hang of queues by making a very simple program that simulates a checkout line. For some reason my custom dequeue function (using a linkedlist's removeFirst()) wont actually delete stuff in the queue.
Heres the CustomerQueue Class
public class CustomerQueue<E> {
private LinkedList<E> list = new LinkedList<>();
public void enqueue(E e) { list.addLast(e); }
public E dequeue() { return list.removeFirst(); }
public int size() { return list.size(); }
public E element() { return list.getFirst(); }
#Override
public String toString() { return "Queue: " + list.toString(); }
}
Here is my main:
public static void main(String[] args) {
CustomerQueue<Customer> queue = new CustomerQueue<>();
final int totalTime = 720;
int totalServiced = 0;
int totalQueued = 0;
int totalArrived = 1;
int maxQueuedAtOnce = 0;
Customer next = new Customer();
queue.enqueue(next);
System.out.println(next.getATime() + " <-- ATIME STIME --> " + next.getSTime());
for (int minute = 0; minute < totalTime; minute++) {
System.out.println("-- Minute " + (minute + 1) + " ---------");
if (queue.element().getSTime() == 0) {
totalServiced++;
System.out.println("Current customer (" + queue.dequeue() + ") finished being serviced. (Removed)");
//queue.dequeue();
}
if (next.getATime() == 0) {
System.out.println("Customer ID=" + next.getID() + " has arrived.");
queue.enqueue(next);
System.out.println("Customer ID=" + next.getID() + " in queue.");
next = new Customer();
System.out.println("New Customer generated. ID=" + next.getID() + " ATIME: " + next.getATime() + " STIME: " + next.getSTime());
totalArrived++;
totalQueued++;
}
System.out.println("Customer ID=" + next.getID() + " arrival ticked down.");
next.tickArrivalDown();
queue.element().tickServiceDown();
System.out.println("Current queue customer ID=" + next.getID() + " ticked down.");
if (queue.size() > maxQueuedAtOnce)
maxQueuedAtOnce = queue.size();
}
System.out.println("Total Customers Generated " + next.getNumCustomers());
System.out.println("Total Customers Serviced: " + totalServiced);
System.out.println("Total Customers Arrived: " + totalArrived);
System.out.println("Maximum Customers Queued: " + maxQueuedAtOnce);
System.out.println(queue.element());
}
And of course the Customer Class:
public class Customer {
private int serviceTime;
private int arrivalTime;
private static int numCustomers = 0;
private int ID;
public int getSTime() { return serviceTime; }
public void setSTime(int t) { serviceTime = t; }
public int getATime() { return arrivalTime; }
public void setATime(int t) { arrivalTime = t; }
public int getID() { return ID; }
public static int getNumCustomers() { return numCustomers; }
Customer() {
serviceTime = (int) (Math.random()*3 + 1);
arrivalTime = (int) (Math.random()*3 + 1);
ID = ++numCustomers;
}
public void tickServiceDown() { serviceTime--; }
public void tickServiceUp() { serviceTime++; }
public void tickArrivalDown() { arrivalTime--; }
public void tickArrivalUp() { arrivalTime++; }
#Override
public String toString() {
return "ID: " + ID + " ArrivalTime: " + arrivalTime + " ServiceTime: " + serviceTime;
}
}
The Customer class I have setup generates its own arrival time and completion time when a Customer is instantiated. Basically at the end of the loop, the next customer's arrival time ticks down and the current customer's service time ticks down. When the current customer's service time hits 0, it should dequeue/remove the first element in the LinkedList. For some reason it isnt removing it. Here is the post-loop output:
Total Customers Generated 358
Total Customers Serviced: 1
Total Customers Arrived: 358
Maximum Customers Queued: 357
ID: 1 ArrivalTime: 0 ServiceTime: -717
I'm totally stumped, no amount of googling has helped.
Looking at your output
ID: 1 ArrivalTime: 0 ServiceTime: -717
and ServiceTime being what is being returned in getSTime()
then as 0 != -717 I think the below will be fine
How about if (queue.element().getSTime() <= 0) {
I figured out the answer. The initial if statement:
if (queue.element().getSTime() == 0) needed to become if (queue.size() > 0 && queue.element().getSTime() == 0)
Also needed to make the queue.element().tickServiceDown(); enclosed with the following if-statement if (queue.size() > 0)
Related
I've been tasked as an assignment to make a queue, that is supposed to be simulated 10 times, and for it to have a waiting room that can hold 100 customers.
I was able to simulate it 10 times, but the assignment mentions criteria such as having an average waiting time of x minutes, having a minimum number of served customers, and at the end have a maximum number of those waiting in line.
Here are my classes
Customer.class
public class Customer {
int arrivalTime;
int transactionTime;
int customerNumber;
public Customer(int a, int t, int c) {
arrivalTime = a;
transactionTime = t;
customerNumber = c;
}
public int getArrivalTime() {
return arrivalTime;
}
public int getTransactionTime() {
return transactionTime;
}
public int getCustomerNumber() {
return customerNumber;
}
}
WaitLine.class
import java.util.*;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;
public class WaitLine {
private static QueueInterface<Customer> line;
private static int numberOfArrivals;
private static int numberServed;
private static int totalTimeWaited;
public WaitLine() {
line = new LinkedQueue<Customer>();
reset();
}
public final void reset() {
line.clear();
numberOfArrivals = 0;
numberServed = 0;
totalTimeWaited = 0;
}
public void simulate(int duration, double arrivalProbability, int maxTransactionTime) {
int transactionTimeLeft = 0;
for (int clock = 0; clock < duration; clock++) {
if (Math.random() < arrivalProbability) {
numberOfArrivals++;
int transactionTime = (int) (Math.random() * maxTransactionTime + 1);
Customer nextArrival = new Customer(clock, transactionTime, numberOfArrivals);
line.enqueue(nextArrival);
System.out.println("Customer " + numberOfArrivals + " enters line at time " + clock
+ ". Transaction time is " + transactionTime);
}
if(transactionTimeLeft > 0) {
transactionTimeLeft--;
}else if(!line.isEmpty()) {
Customer nextCustomer = line.dequeue();
transactionTimeLeft = nextCustomer.getTransactionTime()-1;
int timeWaited = clock - nextCustomer.getArrivalTime();
totalTimeWaited += timeWaited;
numberServed++;
System.out.println("Customer " + nextCustomer.getCustomerNumber() + " begins service at time " + clock + ". Time waited is " + timeWaited );
}
}
}
public void displayResults() {
System.out.println();
System.out.println("Number served = " + numberServed);
System.out.println("Total time Waited = " + totalTimeWaited);
double averageTimeWaited = ((double)totalTimeWaited) / numberServed;
System.out.println("Average time waited = " + averageTimeWaited);
int leftInLine = numberOfArrivals - numberServed;
System.out.println("Number left in line " + leftInLine);
}
}```
I am currently stuck on meeting the criteria described, I put the simulate function in a loop that looped 10 times and after that I used displayresults, but my results did not fit the criteria.
Any help is appreciated, thank you.
transactionTime is handled in the main method/simulation(s) and not on the customer instance itself. Yo just need the arrivalTime and departureTime, and the constructor only needs to be Customer( int arrives ). Then you just need getArrivalTime() setDepartureTime(int time) and totalTime()
Then use import java.util.*; with Queue<Customer> line = new LinkedList<Customer>() and from there you just need the main method using that queue and the customer class that I modified above.
We have a program that compares thousands of pairs of Students by checking each field of the Student and counting the diffs:
class Student{
String name;
String address;
String biologyCourse;
.....
// about 100 other fields
}
And the counter POJO class:
class Counters{
long bothStudentsHaveName;
long onlyLeftHasName;
long onlyRightHasName;
......
// number of fields in Student * 3 (both, only left, only right)
}
Our compare function accepts 2 students plus the counters object and needs to scan the fields and update the relevant counters:
public void compareStudents(Student left, Student right, Counters counters){
if (!StringUtils.isEmpty(left.name) && !StringUtils.isEmpty(right.name) ){
counters.bothStudentsHaveName++;
} else if (StringUtils.isEmpty(left.name) && !StringUtils.isEmpty(right.name)){
counters.onlyRightHasName++;
} else if (!StringUtils.isEmpty(left.name) && StringUtils.isEmpty(right.name))){
counters.onlyLeftHasName++;
}
/// and now??
}
At this point, we can add 100s more triplets of if/else like the above - but we believe there should be a much easier way to do that.
Reflection can be an option or maybe X dimensions arrays, but can we somehow write the code so the comparison and counting will be much more generic?
I have solved your problem with one single loop. But here I'm assuming that naming convention for all the fields will be the same as described in your question. Here I am dynamically accessing the Student fields and updating Counter fields accordingly. Here is the complete solution:
Solution Class:
public class Solution {
public void compareStudents(Student left, Student right, Counter counter) throws Exception {
for (Field field : Student.class.getDeclaredFields()) {
Object leftValue = field.get(left);
Object rightValue = field.get(right);
String fieldName = field.getName().substring(0, 1).toUpperCase() + field.getName().substring(1);
if(leftValue != null && rightValue != null) {
Field counterField = Counter.class.getDeclaredField("bothStudentsHave" + fieldName);
counterField.set(counter, (long) counterField.get(counter) + 1);
} else if (leftValue != null) {
Field counterField = Counter.class.getDeclaredField("onlyLeftHas" + fieldName);
counterField.set(counter, (long) counterField.get(counter) + 1);
} else if (rightValue != null) {
Field counterField = Counter.class.getDeclaredField("onlyRightHas" + fieldName);
counterField.set(counter, (long) counterField.get(counter) + 1);
}
}
}
}
Student Class:
class Student {
String name;
String address;
String biologyCourse;
}
Counter Class:
class Counter {
// name
long bothStudentsHaveName;
long onlyLeftHasName;
long onlyRightHasName;
// address
long bothStudentsHaveAddress;
long onlyLeftHasAddress;
long onlyRightHasAddress;
// biologyCourse
long bothStudentsHaveBiologyCourse;
long onlyLeftHasBiologyCourse;
long onlyRightHasBiologyCourse;
// ... and so on
#Override
public String toString() {
return "Counter{" + "\n" +
"\tbothStudentsHaveName = " + bothStudentsHaveName + "\n" +
"\t, onlyLeftHasName = " + onlyLeftHasName + "\n" +
"\t, onlyRightHasName = " + onlyRightHasName + "\n" +
"\t, bothStudentsHaveAddress = " + bothStudentsHaveAddress + "\n" +
"\t, onlyLeftHasAddress = " + onlyLeftHasAddress + "\n" +
"\t, onlyRightHasAddress = " + onlyRightHasAddress + "\n" +
"\t, bothStudentsHaveBiologyCourse = " + bothStudentsHaveBiologyCourse + "\n" +
"\t, onlyLeftHasBiologyCourse = " + onlyLeftHasBiologyCourse + "\n" +
"\t, onlyRightHasBiologyCourse = " + onlyRightHasBiologyCourse + "\n" +
'}';
}
}
Tester Class:
public class Tester {
public static void main(String[] args) throws Exception {
// Creating Dummy Variables
Student student1 = new Student();
student1.name = "Test";
student1.biologyCourse = "Yes";
Student student2 = new Student();
student2.name = "Test1";
student2.address = "abc street";
Counter counter = new Counter();
// Comparing Students
Solution solution = new Solution();
solution.compareStudents(student1, student2, counter);
// Printing Counter
System.out.println(counter);
}
}
Output:
Counter{
bothStudentsHaveName = 1
, onlyLeftHasName = 0
, onlyRightHasName = 0
, bothStudentsHaveAddress = 0
, onlyLeftHasAddress = 0
, onlyRightHasAddress = 1
, bothStudentsHaveBiologyCourse = 0
, onlyLeftHasBiologyCourse = 1
, onlyRightHasBiologyCourse = 0
}
If you keep repreating the same basic pattern of fields, then consider extracting that into a class. For example introduce a FieldComparison class that looks a little like this:
public class FieldComparisonCounter {
public int bothHave;
public int onlyLeftHas;
public int onlyRightHas;
// constructor, getters, setters left as an exercise for the reader
}
Then have a Map<String,FieldComparisonCounter> counters somewhere and a method like this:
public void compareField(String fieldName, String leftValue, String rightValue) {
FieldComparisonCounter counter = counters.get(fieldName);
if (counter == null) {
counter = new FieldComparisonCounter();
counters.put(fieldName, counter);
}
boolean leftHas = !StringUtils.isEmpty(leftValue);
boolean rightHas = !StringUtils.isEmpty(rightValue);
if (leftHas && rightHas) {
counter.bothHave++;
} else if (leftHas) {
counter.onlyLeftHas++;
} else if (rightHas) {
counter.onlyRightHas++;
}
}
Then adding a new field comparison is as simple as calling
compareField("name", left.name, right.name);
In my program, I have three variables: when one of these variables reaches 100, it must appear the words "variable came first to the finish line."
How do I organize the arrival of the second and third variable, so they come out like this:
variable1-arrived first
variable2-finished second
variable3 finished third
Help!
public Corsa(String name)
{
this.name = name;
System.out.println("Start: " + name);
System.out.println("---------------");
}
public void run()
{
while(finita == false)
{
try
{
avanza = (int) (Math.random()*20+1);
percorso = percorso + avanza;
System.out.println(name + " has path " + percorso + " meters");
if(percorso < 100)
{
System.out.println("---------------");
sleep = (int) (Math.random()*20+1);
Thread.sleep(sleep);
}
else
{
System.out.println("---------------");
System.out.println("---------------");
System.out.println(name + " came in first");
finita = true;
}
}
catch(InterruptedException e){}
Thread.yield();
}
}
}
I haven't tested this (so it might not even compile), but something like the following should work:
public class myRace
{
private int distance = 100;
private float offset = 20;
public int runners[3];
public void run()
{
// Set all runners to 0
for ( int i = 0; i < runners.length; i++ )
runners[i] = 0;
// Run the race and stop when at least 1 runner has reached the distance...
boolean finished = false;
while ( !finished )
{
for ( int i = 0; i < runners.length; i++ )
{
runners[i] += (int)((Math.random() * offset) + 1);
if ( runners[i] >= distance ) finished = true;
}
}
// Race finished now sort the runners
TreeMap<String, int> ranking = new TreeMap<String, int>();
for ( int i = 0; i < runners.length; i++ )
{
// A TreeMap is sorted on its key, not the value!
// The runners number is tagged on, just in case two runners have finished on the same distance.
String sortedKey = Integer.toString(runners[i]) + "." + Integer.toString(i);
ranking.put(sortedKey, i);
}
// Print the results
int pos = 1;
for ( Map.Entry entry : ranking.entrySet() )
{
String key = entry.getKey();
String distance = key.subString(0, key.indexOf(".")); // chop off the "." + runners number.
System.out.println("#" + pos + // position
"." + entry.getValue() + // who
", Distance = " + distance); // distance covered
pos++; // this does take in account whether multiple runners finished on the same distance.
}
}
}
I'm writing a simple music database and ATM I'm trying to create a playlist class which will let the user organise their music (4 tracks previously entered into the database class) into a playlist of 3 songs.
After the user selects a song to be put into the playlist, the method is meant to search for the closest free slot in the newplaylist and place the Song variables (artist, name, duration & filesize) inside.
At the moment i am receiving this;
Entering the playlist tool...
Hello, welcome to the playlist builder!
Please select a track to add to the new playlist from the database below(using keys 1-4)
Slot 1:Trees:Breeze:2.34:128
1
Error: there is no free space in the database
Slot A : Song#3a1ec6
Slot B : Song#1ba6076
Slot C : Song#112e7f7
MENU
0 EXIT
1 IMPORT TRACK
2 SHOW ALL
3 Build a playlist(requires atleast 1 track in database)
Am I right in guessing that what is being returned is the reference to the location of the variables and not the variables themselves?
The code for Playlist.class is;
public class Playlist {
Song songDataPlay = new Song();
static UserInterface UI = new UserInterface();
static Song playlisttrackA = new Song();
static Song playlisttrackB = new Song();
static Song playlisttrackC = new Song();
private int MAX_TIME;
private double totalSize;
private double totalTIme;
String playlistClassArtist, playlistClassName;
double playlistClassDuration;
int playlistClassFileSize;
static String playlistArtist;
static String playlistName;
static double playlistDuration;
static int playlistFileSize;
static Song newplaySong;
static Song newSong;
static Song carryfromuserintoplaylist = UI.newPlaylistSongIN;
public void playlistObject(Song a, Song b, Song c) {
this.playlisttrackA = a;
this.playlisttrackB = b;
this.playlisttrackC = c;
}
public static void playlistAllocation() {
newSong = UI.newPlaylistSongIN;
Playlist plu = new Playlist();
SongDatabase SD = new SongDatabase();
Song newSong = carryfromuserintoplaylist;
if (playlisttrackA.songfileSize == 0) {
setSongA(newplaySong);
System.out.println("Slot A : " + playlisttrackA);
System.out.println("Slot B : " + playlisttrackB);
System.out.println("Slot C : " + playlisttrackC);
newplaySong = newSong;
} else if (playlisttrackB.songfileSize == 0) {
setSongB(newplaySong);
System.out.println("Slot A : " + playlisttrackA);
System.out.println("Slot B : " + playlisttrackB);
System.out.println("Slot C : " + playlisttrackC);
newplaySong = newSong;
} else if (playlisttrackC.songfileSize == 0) {
setSongC(newplaySong);
System.out.println("Slot A : " + playlisttrackA);
System.out.println("Slot B : " + playlisttrackB);
System.out.println("Slot C : " + playlisttrackC);
newplaySong = newSong;
} else {
System.out.println("Error: there is no free space in the database");
System.out.println("Slot A : " + playlisttrackA);
System.out.println("Slot B : " + playlisttrackB);
System.out.println("Slot C : " + playlisttrackC);
}
}
public static void setSongA(Song newSong) {
playlisttrackA = newplaySong;
playlisttrackA.songartist = newplaySong.songartist;
playlisttrackA.songname = newplaySong.songname;
playlisttrackA.songduration = newplaySong.songduration;
playlisttrackA.songfileSize = newplaySong.songfileSize;
}
public Song getSongA() {
return (playlisttrackA);
}
public static void setSongB(Song newSong) {
playlisttrackB = newplaySong;
playlisttrackB.songartist = newplaySong.songartist;
playlisttrackB.songname = newplaySong.songname;
playlisttrackB.songduration = newplaySong.songduration;
playlisttrackB.songfileSize = newplaySong.songfileSize;
}
public Song getSongB() {
return (playlisttrackB);
}
public static void setSongC(Song newSongC) {
playlisttrackC = newplaySong;
playlisttrackC.songartist = newplaySong.songartist;
playlisttrackC.songname = newplaySong.songname;
playlisttrackC.songduration = newplaySong.songduration;
playlisttrackC.songfileSize = newplaySong.songfileSize;
}
public Song getSongC() {
return (playlisttrackC);
}
public String returnPlaylist() {
if (playlisttrackA.songfileSize == 0 && playlisttrackB.songfileSize == 0 && playlisttrackC.songfileSize == 0) {
return ("Error ; No new playlists have been added.");
} else if (playlisttrackB.songfileSize == 0 && playlisttrackC.songfileSize == 0) {
return ("You have imported:" + newplaySong.songname + " By " + newplaySong.songartist + " to slot A in the new playlist");
} else if (newplaySong.songfileSize == 0) {
return ("You have imported:" + newplaySong.songname + " By " + newplaySong.songartist + " to slot B in the new playlist");
} else {
return ("You have imported:" + newplaySong.songname + " By " + newplaySong.songartist + " to slot C in the new playlist");
}
}
}
Any help would be great thanks,
System.out.println("Slot A : "+playlisttrackA); this calls the toString() method of Song (which is derived from Object). By default it prints the hash code of an object.
You should better print playlisttrackA.songname if I understand your code right.
I've got some problems with the topological sorting. It can find lops, but it counts some of the tasks (or "nodes" if you want to call it) several times. I think the problem is something with how I read or the Edge class, but I just can't see where it goes wrong. Any help would be really appreciated :)
enter code here
import java.util.*;
import java.io.*;
import java.lang.*;
class Task {
int id, time, staff;
int depA, depB;
String name;
int eStart, lStart;
Edge outEdge;
int cntPredecessors;
boolean visited;
Task(int id, String name, int time, int staff) {
this.id = id;
this.name = name;
this.time = time;
this.staff = staff;
visited = false;
}
public String getName() {
return name;
}
public String toString() {
return name;
}
}
class Edge {
Task id, name, time, staff;
Edge neste;
Task fra, til;
Edge(Task id) {
this.id = id;
}
}
class Input {
public static void main(String[] args) {
if (args.length == 0) {
System.out.println("enter a filename!");
System.exit(1);
} else if (args.length == 1) {
String fil = args[0]+".txt";
LesFraFil(fil);
// skrivUt();
topSort();
} else {
System.out.println("too many parameters, try again...");
}
}
static int antTask;
static Task[] ids;
static int tTid;
static void LesFraFil(String fil) {
int i = 0;
int j;
try {
String lest;
Scanner in = new Scanner(new FileReader(fil));
Edge til;
int counter = 0;
antTask = in.nextInt();
ids = new Task[antTask];
System.out.println(antTask);
while (in.hasNextLine()) {
lest = in.nextLine();
// hvis tom linje, så hopper den over
if(lest.trim().length() == 0) continue;
String split[] = lest.split("\\s+");
int id = Integer.parseInt(split[0]);
String act = split[1];
int tid = Integer.parseInt(split[2]);
int staff = Integer.parseInt(split[3]);
int depA = Integer.parseInt(split[4]);
tTid += tid;
ids[i] = new Task(id, act, tid, staff);
j = 4;
/*
* Lesingen av inputen skal avbrytes når den leser 0.
* j er den som holder på hvor langt vi er i split arrayet
* når den møter på 0
*/
while(split[j].compareTo("0") != 0) {
int tmp = Integer.parseInt(split[j])-1;
// System.out.println(tmp+1 + " Aktivitetens navn : " + act); //+ " tiden aktiviteten tar tid: " + tid + " avhengihet: " + split[j]);
j++;
if (ids[tmp] == null) {
ids[tmp] = new Task(id, act, tid, staff);
ids[tmp].visited = true;
}
ids[i].cntPredecessors++;
if(ids[tmp].outEdge == null) {
ids[tmp].outEdge = new Edge(ids[i]);
} else {
til = ids[tmp].outEdge;
while(til.neste != null) {
til = til.neste;
}
til.neste = new Edge(ids[i]);
}
}
counter++;
i++;
}
if (antTask == counter) {
System.out.println("Lesinga gikk som planlagt av fil: " + fil);
System.out.println("Total arbeidstid: " + tTid);// + antTask + " == " + counter );
} else {
System.out.println("Noe gikk galt avslutter!");
System.out.println(antTask + " || " + counter);
System.exit(2);
}
in.close();
} catch (Exception e) {
System.err.println("ERROR!" + e.getMessage());
}
}
static void skrivUt() {
for (Task sort : ids) {
System.out.print(sort.id + " " + sort.name);
Edge til = sort.outEdge;
while (til != null) {
System.out.print(" " + til.id.id);
til = til.neste;
}
System.out.println();
}
}
static void topSort() {
LinkedList<Task> list = new LinkedList<Task>();
ArrayList<Task> array = new ArrayList<Task>();
Task temp;
int count = 0;
int totalTime = 0;
// Legger taskene i lista
for (Task t : ids) {
if(t.cntPredecessors == 0) {
list.add(t);
totalTime += t.time;
// System.out.println(t);
t.visited = true;
}
}
for (Task t : ids) {
if(t.cntPredecessors == 1) {
list.add(t);
totalTime += t.time;
// System.out.println(t);
t.visited = true;
}
}
// går i evig løkke til lista er tom.
while (!list.isEmpty()) {
temp = list.pop(); // fjerner elementet fra lista
array.add(temp); // legger inn i arraylisten
count++;
// System.out.println(temp);
for(Edge til = temp.outEdge; til!=null;til=til.neste) {
til.id.cntPredecessors--;
if(til.id.cntPredecessors==0) {
list.add(til.id);
}
}
}
if(count < antTask) {
System.out.println("A loop has been found. Terminating...");
System.exit(0);
}
System.out.println("Topological sort: " + Arrays.toString(array.toArray()));// den sorterte "arraylisten"
System.out.println("Total time spend: " + totalTime);
}
} // End class Input
Here is an example of an input file
8
1 Build-walls 4 2 5 0
2 Build-roofs 6 4 1 0
3 Put-on-wallpapers 1 2 1 2 0
4 Put-on-tiles 1 3 2 0
5 Build-foundation 4 2 0
6 Make-floor 2 2 5 0
7 Put-carpet-floor 4 2 6 2 0
8 Move-in 4 4 3 7 0
The problem is with this loop (inside topSort()):
for (Task t : ids) {
if(t.cntPredecessors == 1) {
list.add(t);
totalTime += t.time;
// System.out.println(t);
t.visited = true;
}
}
You just need to remove it.
Reason: this loop adds to list nodes that have 1 incoming edge. Later (in the while loop), it is possible that for these nodes the cntPredecessors field will be decreased to 0 which will make them being pushed back onto list, thus counted twice.
In the future, please try to narrow down your code to something that contains less "noise", that is: the smallset (or nearly smallest) code that illustrates the problem. This will ease the understanding on potential answerers (not to mention that it may help you see the problem yourself).