Allocate random priority in priority queue? - java

I am working on assigning random priorities (i.e. high, medium, low) to a list for a ServiceDesk assignment.
Before that, I was wondering how to go about storing (and printing) an array in said priority queue. This is currently what I have.
*UPDATED CODE
import java.util.*;
import java.util.Random;
public class Demo {
public static void main (String[] args) {
String [] names = {
"Tanya Turner","Juana Downs","Mac Bautista","Leanne Donaldson",
"Jere Romero","Autumn Hayden","Vincenzo Mckee","Penelope Stanley",
"Rose Solis","Randal Savage","Delia Hardy","Alisha Hebert","Johnson Jefferson",
"Gregorio Richard","Jana Simmons","Marian Shepherd","Lynn Pugh","Christine Newman",
"Essie Frederick","Jewel Oneill","Raul Coleman","Lou Glover","Cora Rush",
"Damien Norris","Omer Parsons","Adolph Petersen","Dane Proctor","Norbert Ritter",
"Gloria Dickerson","Ella Morton","Madeline Mccullough","Patsy Berger","Tory Hardin",
"Sonny Guzman","Kathrine Bond","Teodoro Bolton","Aimee Moran","Jerry Rhodes",
"Palmer Golden","Zelma Hobbs","Marcella Patel","Freddy Lucas","Ladonna Hutchinson",
"Devon Boone","Sue Graves","Chadwick Mcpherson","Antonia Rocha","Roseann Peters",
"Leif Riggs","Judith Mcbride","Frances Simon","Nora Cervantes","Alba Hickman",
"Concetta Wu","Chelsea Eaton","Dana Rocha","Hubert Kaiser","Phillip Stephenson",
"Estela Kent","Rene Hughes","Clement Gilmore","Arlie Fernandez","Teodoro Buckley",
"Daniel Chavez","Jeffry Shepherd","Devin Case","Eric Cooley","Dina Duncan","Teddy Price",
"Matthew Cooke","Andres Dalton","Clayton Fields","Vito Lara","Lynette Mccann","Greta Choi",
"Santo Noble","Thurman Douglas","Therese Norton","Juliette Graves","Fran Vang",
"Forrest Gibbs","Cameron Bernard","Tracy Zhang","Hugh Huerta","Jaime Huynh","Tami Cordova",
"Jami Mcpherson","Melissa Stein","Rayford Brewer","Tammie Lucero","Marcia Velez","Jasper Watkins",
"Cora Chapman","Vickie Mccarthy","Gino Pena","Chadwick Hutchinson","Antonio Bryan",
"Zachery Barnett","Randy Crawford","Laura Barton","Nolan Leach","Deborah Perry",
"Georgina Sanford","Heidi Anthony","Leah Hester","Dong Swanson","Genevieve Wagner",
"Russell Todd","Sherman Wolfe","Bo Schultz","Rosalyn Stevens","Brooke Moses","Jasmine Brock",
"Guadalupe Andersen","Emilio Horne","Clara Spencer","Raul Levine","Colton Adams","Eve Avila",
"Donny Murray","Laverne Valentine","Wilbert Gilbert","Justine Terrell","Waldo Nielsen",
"Erma Mason","Brandie Sullivan","Murray Torres","Angelique Whitney","Shanna Humphrey",
"Graig Farley","Lindsay Hines","Susanne Compton","Frankie Frank","Saundra Marks","Lorna Skinner",
"Josephine Boyle","Maynard Wagner","Ronda Potts","Elias French","Gilberto Nguyen"
};
String[] priority = {"High", "Medium", "Low"};
Random r = new Random();
for (String i : names) {
System.out.println("Names are: " + i);
int randomPriority = r.nextInt(priority.length);
System.out.println("Priority: " + priority[randomPriority]);
}
}
}

Sounds like you are asking for help on how to get started. You are asking for help on learning to learn. Here is how I would approach your problem:
Apparently you are supposed to use a priority queue.
Write a tiny program that makes a priority queue and stores strings into it, then prints them out.
Define a class and store instances of that class into the priority queue instead of strings.
Modify the sort criteria on the priority queue and notice that the printed sequence changes according to the sort criteria.
Write a function that creates one class instance with random values.
Write a function that creates all 100 class instances.
Declare victory.

A priority queue doesn't store priorities itself. Instead, it provides a hook where it asks "what's the priority of this item?" and your code responds with the priority. Consequently, it's on you to augment the items you're storing with their priorities.
In other words, you'll need to use a richer data format than just plain strings. You should probably store the names and their priorities side by side. It calls for a custom class with fields such as author and priority.
enum Priority {
LOW,
MEDIUM,
HIGH
}
class Ticket {
String author;
String description;
Priority priority;
}
You can assign random priorities when you create each Ticket.
The glue that'll bind the priority queue and the Ticket class is a custom comparator. Writing one is pretty straightforward using -> lambda syntax:
PriorityQueue<Ticket> queue = new PriorityQueue<>(
Comparator.comparing(ticket -> ticket.priority)
);

Related

Which Data Structure would be more suitable for the following task in Java?

Every 5 minutes, within the 20th minute cycle, I need to retrieve the data. Currently, I'm using the map data structure.
Is there a better data structure? Every time I read and set the data, I have to write to the file to prevent program restart and data loss.
For example, if the initial data in the map is:
{-1:"result1",-2:"result2",-3:"result3",-4:"result4"}
I want to get the last -4 period's value which is "result4", and set the new value "result5", so that the updated map will be:
{-1:"result5",-2:"result1",-3:"result2",-4:"result3"}
And again, I want to get the last -4 period's value which is "result3", and set the new value "result6", so the map will be:
{-1:"result6",-2:"result5",-3:"result1",-4:"result2"}
The code:
private static String getAndSaveValue(int a) {
//read the map from file
HashMap<Long,String> resultMap=getMapFromFile();
String value=resultMap.get(-4L);
for (Long i = 4L; i >= 2; i--){
resultMap.put(Long.parseLong(String.valueOf(i - 2 * i)),resultMap.get(1 - i));
}
resultMap.put(-1L,"result" + a);
//save the map to file
saveMapToFile(resultMap);
return value;
}
Based on your requirement, I think LinkedList data structure will be suitable for your requirement:
public class Test {
public static void main(String[] args) {
LinkedList<String> ls=new LinkedList<String>();
ls.push("result4");
ls.push("result3");
ls.push("result2");
ls.push("result1");
System.out.println(ls);
ls.push("result5"); //pushing new value
System.out.println("Last value:"+ls.pollLast()); //this will return `result4`
System.out.println(ls);
ls.push("result6"); //pushing new value
System.out.println("Last value:"+ls.pollLast()); // this will give you `result3`
System.out.println(ls);
}
}
Output:
[result1, result2, result3, result4]
Last value:result4
[result5, result1, result2, result3]
Last value:result3
[result6, result5, result1, result2]
Judging by your example, you need a FIFO data structure which has a bounded size.
There's no bounded general purpose implementation of the Queue interface in the JDK. Only concurrent implementation could be bounded in size. But if you're not going to use it in a multithreaded environment, it's not the best choice because thread safety doesn't come for free - concurrent collections are slower, and also can create confusing for the reader of your code.
To achieve your goal, I suggest you to use the composition by wrapping ArrayDeque, which is an array-based implementation of the Queue and performs way better than LinkedList.
Note that is a preferred approach not to extend ArrayDeque (IS A relationship) and override its methods add() and offer(), but include it in a class as a field (HAS A relationship), so that all the method calls on the instance of your class will be forwarded to the underlying collection. You can find more information regarding this approach in the item "Favor composition over inheritance" of Effective Java by Joshua Bloch.
public class BoundQueue<T> {
private Queue<T> queue;
private int limit;
public BoundQueue(int limit) {
this.queue = new ArrayDeque<>(limit);
this.limit = limit;
}
public void offer(T item) {
if (queue.size() == limit) {
queue.poll(); // or throw new IllegalStateException() depending on your needs
}
queue.add(item);
}
public T poll() {
return queue.poll();
}
public boolean isEmpty() {
return queue.isEmpty();
}
}

Create a java List with maximum of 100 values

I create a list of object with java
public class Cleint {
private int id;
private String user;
private int age;
public static List<Client> last100CleintList;
The list is supposed to be a kind of queue where the last 100 clients are stored. So when the list is empty I just want to add clients but when I reach 100 I want to delete the last one and add the new one. I could do it manually but is there a function for that? Or maybe in arrays, I am not forced to use lists.
There is no built-in library to achieve that (data-structure is there) without creating a utility method yourself.
Since you want to keep the last 100Clients every-time you append; and the list size is 100, you have to remove the first Client. You could try something like this (with Client objects).
import java.util.Queue;
import org.apache.commons.collections4.queue.CircularFifoQueue;`
Queue<String> circularQueue = new CircularFifoQueue<String>(2);
circularQueue.add("Bob");
circularQueue.add("Doe");
circularQueue.add("Joe");
then
System.out.println(circularQueue);
outputs ["Doe", "Joe"];
You can also do this with:
com.google.common.collect.EvictingQueue
MinMaxPriorityQueue by guava

Multi-threaded code in a static initalizer block produces deadlock

I have a class that needs to provide a fast classification service. For example, I want to write code like "classify("Ac Kd Kh 3c 3s")" that quickly returns TWO_PAIR. (This isn't the application but you get the jist)
Because I need the classification to be quick I want to precompute, and then store, a look-up table that lists the classification output for all possible inputs. In the interest of time I want to parallelize this precomputation. HOWEVER, attempting to use "classifySlowly" from a 2nd thread creates a deadlock.
public class Classifcation Service {
enum CLASS {TYPE_A, TYPE_B, ...};
static CLASS[] preComputedClassLookUpTable;
static {
preComputedClassLookUpTable = constructLookUpTableInParallel();
}
//Note: using this method from with constructLookUpTableInParallel causes deadlock
private static CLASS classifySlowly(Object classifyMe) {
//do time intensive work to classify the input
// -- uses no other methods from this class
return classification;
}
public static CLASS classify(Object classifyMe) {
//use the lookup table to do a quick classification
return classification;
}
}
So my question is: Is there a way to precompute this lookup table IN PARALLEL from within the static initalizer block?
The only (poor) alternative I see is to switch from:
preComputedClassLookUpTable = constructLookUpTableInParallel();
To:
preComputeClassLookUpTable = loadLookUpTableFromFile();
if(preComputedClassLookUpTable == null) {
System.out.println("WARNING: Construction incomplete, Must call computeAndSaveLookUpTableFile();}
}
I thought this would be too much but here is the implementation of constructLookUpTableInParallel
private static CLASS[] constructLookUpTableInParallel() {
//build a collection of Runnables by iterating over all possible input Objects
//wrap each possible input in an anonymous Runnable that calls classifySlowly.
//submit the collection of Runnables to a new ExecutorService
//process runnables...
//shutdown executor service
}
////////END OF POORLY WORDED ORIGINAL QUESTION ///////////
The solution that works somewhat cleanly is splitting the classifySlowly(Object classifyMe) and classify(Object classifyMe) methods into two different classes.
This will allow the (first) class that contains "public static CLASS classifySlowly(Object classifyMe)" to be fully loaded by the time the (second) class that contains "public static CLASS classifyQuickly(Object classifyMe)" needs to use the classifySlowly method. Now, that the 2nd static inialization block don't require any of its own static methods it can be fully parallelized.
"So my question is: Is there a way to precompute this lookup table IN PARALLEL from within the static initalizer block?"
Yes, it's practically certain there is a way. Just new the array and launch a Runnable for each array element. Give each Runnable reference to the array, and index it is computing, then have it do the computing without locking, then lock when assigning result to the array element.
Note/disclaimer: this answer is based on the rather incomplete information given in the question...

how to reorder a list of objects?

Firstly, this is going to sound like homework, but it ain't. Just a problem I'm trying to solve at work.
I have a list of objects, the objects have a sequence number which indicates their order in the list in the UI. Example:
public class Task {
Long id;
String name;
Long seq;
}
The table in my UI has "up" and "down" links on each row of the table for moving the tasks up and down in the list.
I'm implementing two methods to handle the reordering. These methods are call by ajax in the web UI.
public void incTaskSeq(List<Task> allTasks, Task taskToMove)
For example; if I have t1.seq=1, t2.seq=2, t3.seq=3, t4.seq=4, t5.seq=5 and I want to increment the place of t3, then t3.seq becomes 4, and t4.seq must become 3.
public void decTaskSeq(List<Task> allTasks, Task taskToMove)
Similarly; if I have t1.seq=1, t2.seq=2, t4.seq=3, t3.seq=4, t5.seq=5 and I want to decrement the place of t4, then t4.seq becomes 2, and t2.seq must become 3. Resulting in:
t1.seq=1, t4.seq=2, t2.seq=3, t3.seq=4, t5.seq=5
I'm a little stuck on the best way to do this.
I was thinking of putting all the tasks in a HashMap and then sort the map by the sequence number. Then locate the taskToMove in the map, change the sequence number, and then change all the affected tasks sequences.
But this approach seems inelegant. Does anyone have any ideas how I should do this?
Thanks, Rob
Use a Comparator, which is the Java interface for sorting non-naturally.
public TaskSequenceComparator implements Comparator<Task> {
public int compare(Task one, Task two) {
return one.getSequence() - two.getSequence();
}
}
...
List<Task> tasks = ...;
Collections.sort(tasks, new TaskSquenceComaprator());
// tasks is now sorted by sequence.
You can create multiple Comparator classes to implement each kind of supported sort. Then you can select from them when you need the list sorted in a particular manner.
Implement a Comparator for each criteria you want to sort for.
Create a new ordered Collection object (maybe a TreeSet) passing it the Comparator needed. Do .addAll of the objects.
Just let the List keep tarck of ordering. (Except You always need to update the seqence number).
public void incTaskSeq(List<Task> allTasks, Task taskToMove){
int movTaskNum = 0;
for(int i=0;i<allTasks.size();i++){
if(allTasks.get(i).equals(taskToMove))
movTaskNum = i;
}
allTasks.remove(taskToMove);
allTasks.add(i-1, taskToMove);
}
sorry for typos
Use a doubly linked list and swap the sequence numbers when you move an item.

Time efficient implementation of generating probability tree and then sorting the results

I have some events, where each of them has a probability to happen, and a weight if they do. I want to create all possible combinations of probabilities of events, with the corresponding weights. In the end, I need them sorted in weight order. It is like generating a probability tree, but I only care about the resulting leaves, not which nodes it took to get them. I don't need to look up specific entries during the creation of the end result, just to create all the values and sort them by weight.
There will be only about 5-15 events,but since there is 2^n resulting possibilities with n events, and this is to be done very often, I don’t want it to take unnecessarily long time. Speed is much more important than the amount of storage used.
The solution I came up with works but is slow. Any idea for a quicker solution or some ideas for improvement?
class ProbWeight {
double prob;
double eventWeight;
public ProbWeight(double aProb, double aeventWeight) {
prob = aProb;
eventWeight = aeventWeight;
}
public ProbWeight(ProbWeight aCellProb) {
prob = aCellProb.getProb();
eventWeight = aCellProb.geteventWeight();
}
public double getProb(){
return prob;
}
public double geteventWeight(){
return eventWeight;
}
public void doesHappen(ProbWeight aProb) {
prob*=aProb.getProb();
eventWeight += aProb.geteventWeight();
}
public void doesNotHappen(ProbWeight aProb) {
prob*=(1-aProb.getProb());
}
}
//Data generation for testing
List<ProbWeight> dataList = new ArrayList<ProbWeight>();
for (int i =0; i<5; i++){
ProbWeight prob = new ProbWeight(Math.random(), 10*Math.random(), i);
dataList.add(prob);
}
//The list where the results will end up
List<ProbWeight> resultingProbList = new ArrayList<ProbWeight>();
// a temporaty list to avoid modifying a list while looping through it
List<ProbWeight> tempList = new ArrayList<ProbWeight>();
resultingProbList.add(dataList.remove(0));
for (ProbWeight data : dataList){ //for each event
//go through the already created event combinations and create two new for each
for(ProbWeight listed: resultingProbList){
ProbWeight firstPossibility = new ProbWeight(listed);
ProbWeight secondPossibility = new ProbWeight(listed);
firstPossibility.doesHappen(data);
secondPossibility.doesNotHappen(data);
tempList.add(firstPossibility);
tempList.add(secondPossibility);
}
resultingProbList = new ArrayList<ProbWeight>(tempList);
}
// Then sort the list by weight using sort and a comparator
It is 50% about choosing an appropriate data structure and 50% about the algorithm. Data structure - I believe TreeBidiMap will do the magic for you. You will need to implement 2 Comparators - 1 for the weight and another for the probability.
Algorithm - trivial.
Good luck!
just a few tricks to try to speed up your code:
- try to avoid non necessary objects allocation
- try to use the right constructor for your collections , in your code sample it seems that you already know the size of the collections, so use it as a parameter in the constructors to prevent useless collections resizing (and gc calls)
You may try to use a Set instead of List in order to see the ordering made on the fly.....
HTH
jerome

Categories