Web caching algorithm (hashmaps keys-values issue?) - java

I am newbee in programming in general and in Java in particular. The last few months I am working on a project regarding a Web caching algorithm. After a lot of work I have done everything (and since this is my first real project, I am very happy about that) except one little but important detail. Let me be more precise on that.
In the code I generate random Zipf-distributed requests. Each requested item is distinguished by its numeric ID (reqID). The cache is implemented as a doubly linked list (a Java LinkedList). The caching algorithm is called WeightLFU and it works as follows:
Each request is assigned a weight which is given by the formula
weight = Math.pow(1/p, reqIndex);
where p is a weight factor and reqIndex is the numeric index of the request (1st, 2nd, 3rd etc.).
The score (which I call weighted frequency, weightFreq) of each cached item is given as the sum of its weights. Let us see an example to illustrate this. Assume that we have the following request stream (the reqIDs are given):
ReqIndex: 1 | 2 | 3 | 4 | 5
ReqID: 7 | 3 | 7 | 1 | 3
Assuming p= 0.5 (just a convenient value), the weights assigned to each request are:
ReqIndex: 1 | 2 | 3 | 4 | 5
Weight: 1 | 2 | 4 | 8 | 16
Therefore, the score of the requested item with reqID 7 is 1 + 4 = 5, the score of the item with reqID 3 is 2 + 16 = 18 and finally the score of the item with reqID 1 is 8.
Now here is what I do wrong. In this example, I would have the following: the score of item 3 would be 16+8+4+2+1 = 31, the score of item 1 would be 8+4+2+1 = 15 etc., i.e. the code sums all the previous weights irrespective of the request ID. Here are the relevant parts of the code:
Class WeightLFU
public class WeightLFU {
//////////////////////////////////////////
// member attributes
/** weightLFU cache */
private List<Request> weightLFU = new LinkedList<Request>();
/** Max cache size */
private int M;
/** Fading factor */
private double p;
/** Weight */
private double weight;
/** Score (weightFreq) */
private double weightFreq;
/** Map of reqID (K) and weight (V) */
private Map<Integer, Double> weights;
/** Map of reqID (K) and weightFreq (V) */
private Map<Integer, Double> weightFreqs;
//////////////////////////////////////////
// member methods
// constructor, printing methods, initializers etc.
/**
* Getter for weight of request
* #param request The requested item
* #param reqIndex The index of the request
* #return this.weights.get(request.reqID) The weight of the request
*/
public double getWeight(Request request, int reqIndex) {
// calculate weight
weight = Math.pow(1/p, reqIndex);
// put request along with its weight to the weights map
weights.put(request.reqID, weight);
// return weight of requested item
return this.weights.get(request.reqID);
}
/**
* Calculate weightFreq of requested item
* #param request The requested item
* #param reqIndex Index of the request
*/
public void calcWeightFreq(Request request, int reqIndex) {
// initialize weightFreq
initWeightFreqs(request);
// calculate weight freq
weightFreq += getWeight(request, reqIndex);
// put reqID along with its weightFreq into the weightFreqs map
weightFreqs.put(request.reqID, weightFreq);
}
/**
* Getter for weightFreq of requested item
* #param request The requested item
* #return this.weightFreqs.get(request.reqID); weightFreq of req. item
*/
public double getWeightFreq(Request request) {
// return weightFreq of requested item
return this.weightFreqs.get(request.reqID);
}
// other stuff (cache lookup, insertion, replacement etc.)
}
The reason I use a method calcWeightFreq and another method as getter instead of combining them in a single getter method is just to avoid using as parameter the reqIndex when I call the getter method in cache insertion and replacement operations latter on. It is irrelevant of my issue.
Main class:
// several irrelevant stuff
// scan the request list
for(int ir = 0; ir < reqs.size(); ir++) {
// assign the item in position ir in the reqs list to a Request item r
Request r = reqs.get(ir);
// other stuff
}
// other stuff
}
I understand that this abnormal behavior makes sense. I assume that in the calcWeightFreq method I have to scan the weights map in order to get the sum of the weights only for the specific reqID, but this does not work either (I get 0 value for all the weightFreq values).
I hope I have clearly stated the issue. I assume that it needs only 5-10 lines of additional code to be addressed, but I don't know how to do it. Any guidance would be appreciated. Thank you in advance.

Related

How do you put integers within a range in Java?

Though I am sure that this answer is simple, I am not sure that is asked of me for this assignment. Here is the full code that I have written (so just a return!) as well as the instructions that were given:
package code;
/**
* This class contains a variety of methods that will be used throughout the Ratings and Reviews
* project.
*/
public class Utilities{
/**
* Computes the average of two ratings
*
* #param rating0 An integer rating in the range of 1-5 inclusive
* #param rating1 An integer rating in the range of 1-5 inclusive
* #return the average of rating0 and rating1 as a double
*/
public double averageRating(int rating0, int rating1){
return ((rating0 + rating1) / 2); // Don't forget to replace this return statement with your own
}
Sorry for bad structure upon pasting it. I think my return is suitable for what is being done, provided that the rating could be just anything. I know that it can only be between 1-5, though, so how would one go about specifying that?
How about throwing an InvalidArgumentException if the range is violated?
e.g.
public double averageRating(int rating0, int rating1){
if (rating0 < 1 || rating0 > 5 || rating1 < 1 || rating1 > 5) {
throw new InvalidArgumentException("Rating out of range");
}
return ((rating0 + rating1) / 2.0); // Don't forget to replace this return statement with your own
}

Getting the unicode value of the first character in a string

I am basically being asked to take the Unicode value of a string, multiply it by 10% and add whatever level the object currently has. It's frustrating because as it turns out I have the logic down including the code yet I still get an error that says: expected:<0> but was:<8>. Any suggestions, maybe it's just a slight nuance I have to make in the logic, although I'm fairly certain it's right. Take note of the getLevel method because that's where the error is
public class PouchCreature implements Battleable {
private String name;
private int strength;
private int levelUps;
private int victoriesSinceLevelUp;
/**
* Standard constructor. levelUps and victoriesSinceLevelUp start at 0.
*
* #param nameIn desired name for this PouchCreature
* #param strengthIn starting strength for this PouchCreature
*/
public PouchCreature(String nameIn, int strengthIn) {
this.name = nameIn;
this.strength = strengthIn;
this.levelUps = 0;
this.victoriesSinceLevelUp = 0;
}
/**
* Copy constructor.
*
* #param other reference to the existing object which is the basis of the new one
*/
public PouchCreature(PouchCreature other) {
this.name=other.name;
this.strength=other.strength;
this.levelUps=other.levelUps;
this.victoriesSinceLevelUp=other.victoriesSinceLevelUp;
}
/**
* Getter for skill level of the PouchCreature, which is based on the
* first character of its name and the number of levelUps it has.
* Specifically, the UNICODE value of the first character in its name
* taken %10 plus the levelUps.
*
* #return skill level of the PouchCreature
*/
public int getLevel() {
int value = (int)((int)(getName().charAt(0)) * 0.1);
return value + this.levelUps;
}
You've said you're supposed to increase the value by 10%. What you're actually doing, though, is reducing it 90% by taking just 10% of it (and then truncating that to an int). 67.0 * 0.1 = 6.7, which when truncated to an int is 6.
Change the 0.1 to 1.1 to increase it by 10%:
int value = (int)((int)(getName().charAt(0)) * 1.1);
// --------------------------------------------^
There, if getName() returns "Centaur" (for instance), the C has the Unicode value 67, and value ends up being 73.
We need to see the code you're calling the class with and that is generating your error message. Why is it expecting 0? 8 seems like a valid return value from the information you've given.

Is this MVC method a good way to program a Sudoku Game?

I'm building a Sudoku Game. I came here to get some help because I'm completely stuck in my code. I'm not asking for you to complete my code, I know that's not your job. Just few hints as what to do next would be great!
I use MVC and Swing Components for GUI to make the code lighter. I divided each field and method so I can understand what to do next but I'm confused. I'm particularly having trouble understanding how to do the following methods:
initializeGrid
chooseGameDifficulty
makeMove
cancelMove
Model
public class GameSudokuModel {
// states -- fields
Scanner userInput = new Scanner (System.in); // accept user input
// int levelDifficulty = 0; // level of difficulties
int [] gridSize ; // Sudoku 9x9 == 81 cells -- used to initialize grid or solve puzzle --
int [] subGridSize ; // a sub-grid = 9 cells
int gameMove = 0; // calculate the total number of moves per game // ++makeMove and --cancelMove
int [] gameCell = {1, 2, 3, 4, 5, 6, 7, 8, 9}; // a cell contain a list of choices numbers 1-9
int currentGameTime = 0; // calculates the total time to complete a puzzle
String currentPlayerName = userInput.nextLine(); // player name
// end of fields
//behaviors -- methods
/******************************************************
*
* Method calculateGameTime (initialiserGrille)
*
*
* Calculates time
*
* The stopwatch starts when the player makes ​​his first move
*
*
*
******************************************************/
public class calculateGameTime{
}
/******************************************************
*
* Method initializeGrid (initialiserGrille)
*
*
* Used to initialize a grid
*
* Reset the grid ( back to the original Sudoku grid ) using the list of moves .
*
*
*
*
*
******************************************************/
public class initializeGrid {
}
/******************************************************
*
* Method levelDifficulty
*
*
* Established the parameters of level of difficulty
*
*
* #param beginner
* #param expert
* #return
******************************************************/
public int levelDifficulty (int beginner, int expert){
while(true)
{
int levelDifficulty = 0;
levelDifficulty= userInput.nextInt();
System.out.println (" ");
if(levelDifficulty < beginner || levelDifficulty> expert){
System.out.print (" You must choose 1, 2 or 3." + "Please try again : ");
System.out.println (" ");
}
else
return levelDifficulty;
}
}
/****************************************************
* Method chooseGameDifficulty (chosisirNiveauDifficulte)
*
* The method makes possible to choose the level of complexity of a grid
*
* (1) beginner: the player starts the game with a grid made ​​up to 75% (81 * 0.75)
*
* (2) Intermediate : the player starts the game with a grid made ​​up to 50% (81 * 0.50)
*
* (3) Expert : the player starts the game with a grid made ​​up to 25% (81 * 0.25)
*
* Numbers are set randomly on the grid every new game
*
* #param beginner
* #param intermediate
* #param expert
******************************************************/
public void chooseGameDifficulty(int beginner, int intermediate, int expert){
boolean entreeValide;
int levelDifficulty;
String reponse;
levelDifficulty= levelDifficulty(beginner,expert); // call function levelDifficulty()
if(levelDifficulty==beginner)
//get easy level grid (getter)
//set easy level grid (setter)
if(levelDifficulty==intermediate)
//get intermediate level grid (getter)
//set intermediate level grid (setter)
if(levelDifficulty==expert)
//get expert level grid (getter)
//set easy expert grid (setter)
}
/****************************************************
* Method solvePuzzle (resoudrePuzzle)
*
* This method makes possible to solve the entire grid meaning all the 81 cells
*
******************************************************/
public class solvePuzzle {
}
/****************************************************
* Method makeMove (fairePlacement)
*
* Save a record of the player's actions on the grid.
*
*
*
* (1) make move on the grid ;
* (2) save moves in an array list
*
******************************************************/
public class makeMove {
//choose a cell , enter a number on the cell and confirm the selection
// adds move to the array list
int makeMove = gameMove++;
}
/****************************************************
* Method cancelMove (annulerPlacement)
*
*
*
* (1) retrieve the last instance in the arraylist (using the remove method and the size method to determine the number of elements )
* (2) cancel the move in the grid.
*
******************************************************/
public class cancelMove {
//choose a cell , remove the number on the cell and confirm the cancellation
//substracts move from array list
int cancelMove = gameMove--;
}
}
initializeGrid and chooseGameDifficulty aren't really features of the model. The model maintains the current state of the data and the rules uses to manage it.
Technically, these features should be functions of some kind of factory that given a difficult level will return a instance of the model
public class SudokuFactory {
public enum Difficulty {
HARD,
MODERATE,
EASY
}
public SudokuModel createModel(Difficulty difficult) {
// Make a new model based on the rules for your difficulty
// settings
}
}
The model would then simply contain the information and functionality to manage it
You should also avoid static where practically possible, it should never be used as a cross class communication mechanism, if you need to share data, you should pass it. static just makes the whole thing a lot more difficult to manage and debug
The view would get the information from the user (like the difficulty level), which would be used by the controller to build a new model. The model would then be passed to a new controller, which would generate a new view, which should present the current state of the model.
The controller would then respond to changes in the view, updating the model and the controller would respond to changes in the model and update the view.
You should also prefer using interfaces over implementation
So, based on my (rather pathetic) understanding of Sudoku you could use a model as simple as ...
public interface SudokuModel {
public void setValueAt(int value, int row, int col) throws IllegalArgumentException;
public int getValueAt(int row, int col);
}
Now, me, personally, I'd have an implementation that had two buffers, one which represents the actual game/solution and one which represents the player data (pre-filled based on the difficulty level), now you could have a single buffer, but you'd have constantly scan the grid to see if the new value was valid and I'm just too lazy ;)

How to implement an interface

I have a populate interface that will be getting the current population, setting the population and increasing the population. I have a main that has my planets set in an array list so now what I need to do is to implement the code that will help me to increase the population of that planet based on that planets methods. Here is the population interface.
/**
* This interface models the behavior of planets when travelers arrive
* and when they try to leave.
* #author
*
*/
public interface Populate {
/**
* Get the current population of the planet
* #return the current population of the planet
* #throws Exception if the value of the currentPopulation is none of your business
*/
public int getCurrentPopulation() throws Exception;
/**
* Initialize the current population to a value
* #param currentPopulation The value to initialize to
* #return The new value of the current population, will be currentPopulation
* #throws Exception if the value of the currentPopulation argument is negative
*/
public int setCurrentPopulation(int currentPopulation) throws Exception;
/***
* Increase the population of the planet as travelers arrive.
* #param populationIncrease The amount to increase the current population. Can be negative.
* #return The new current population
*/
public int IncreasePopulation(int populationIncrease);
}
Here is the main:
public class Main {
public static void main(String[] args) {
//this class will run calculations for planets
ArrayList<WorldOfAdams> myPlanets = new ArrayList<WorldOfAdams>();
myPlanets.add(new AllosimaniusSyneca());
myPlanets.add(new BlagulonKappa());
myPlanets.add(new Damogran());
myPlanets.add(new Traal());
//Get current population for each of the planets
for (int i=0; i<myPlanets.size(); i++) {
myPlanets.get(i).getCurrentPopulation();
And each planet has its own set of instructions. There is Allosimanius Syneca, Blagulon Kappa, Damogran and Traal.
Instruction for Allosimanius Syneca are
/**
* This class models the planet Allosimanius Syneca. On this planet travelers are not
*welcome. Anyone landing on the planet at any of the 3 spaceports is immediately put
*to work in the cinnamon mines. No one is ever allowed to leave.
*/
Based of the method of this planet it would appear that the current population would be set to 0 since no one is ever allowed to visit this planet but in the increase population I would need to reflect that there is an increase but that the traveler will go straight to the cinnamon mine. How can I implement this? I know that I need to create code that will increase population and then print statement showing that the increase in population goes "to the cinnamon mines". Do I put this code in the main?
The instructions for Blagulon Kappa:
/***
* All travelers who arrive on this planet are treated with kindness. They may stay as
* long as they like and leave whenever they like. However, they will not reveal the
*current population to anyone. All inquiries are ignored.
Based on this information I would need to print a statement reflecting that the population may increase but the output is "none of their business". Would this planet have a simple print statement and no code to increase population since the output isn't allowed to be known?
The instructions for Damogran:
/***
* Damogran is a mostly peaceful planet that has completely run out of livable land.
*They do not allow anyone to visit the planet or leave it. Ever.
So for this planet I would set the current population at 0 and there is no increase in population.
And lastly the instruction for Traal:
/***
* 10% of the travelers arriving on this planet are immediately fed to the Ravenous
* Bugblatter Beast. Survivors are allowed to come and go as they wish.
For this planet I would need to increase the population but divide that increase by 10% and print a statement with that remaining number that states "fed to Bugblatter Beast"
Just learning how to use interfaces and abstract classes and having a difficult time understanding how to implement all of these classes to run together and be able to give different results. Any help or guidance that you can give is much appreciated!!
Since I didn't want to seem rude, I'll make a guess and suggest your Increase population function should look like this :
#Override
public int IncreasePopulation(int populationIncrease) {
CinnamonMines CM = getCinnamonMines(); //must be defined somewhere in your code
CM.IncreasePopulation(populationIncrease);
return 0;
}

How to avoid infinite loop while creating a scheduler

Intro to problem:
I am given recipes how to craft items. Recipe is in format : {element that is being crafter}: {list of elements, that is needed}. Before I can craft element x, I need to know how to craft elements it's made of. So I want to find in what order do I have to learn recipes.
For valid input, like following everything works:
// Input:
{
"F1: F2 F3 F4", "F5: F6 F4", "F6: F7 F8 F4", "F2: F3 F8 F4", "F8: F4",
"F9: F4", "F7: F4", "F10: F7 F4", "F11: F4", "F4:", "F3: F6"
}
// Output:
[F4, F7, F8, F6, F3, F2, F1, F5, F9, F10, F11]
The problem is, that task is more complex. Time to time I have some recipes missing or thy are invalid. Example of invalid input: { "F1: F2", "F2: F1" }.
Code example:
mp contains recipe name as key and elements as value, labels are unique mp keys and result will contain answer. I'm looking for a way to return empty result if infinite loop is met.
private void getArray(HashMap<String, ArrayList<String>> mp,
ArrayList<String> result, ArrayList<String> labels) {
for (String a : labels) {
if (mp.get(a) != null)
for (String label : mp.get(a))
getArray(mp, result, label);
if (!result.contains(a))
result.add(a);
}
}
private void getArray(HashMap<String, ArrayList<String>> mp,
ArrayList<String> result, String label) {
if (result.contains(label))
return;
if (mp.get(label) == null) {
result.add(label);
return;
}
for (String l : mp.get(label))
getArray(mp, result, l);
if (!result.contains(label))
result.add(label);
}
Edit
Problem solved.
For any Google's that stumble up this, this is what I came up with:
/** <p>
* <b>Topological sort</b> solves a problem of - finding a linear ordering
* of the vertices of <i>V</i> such that for each edge <i>(i, j) ∈ E</i>,
* vertex <i>i</i> is to the left of vertex <i>j</i>. (Skiena 2008, p. 481)
* </p>
*
* <p>
* Method is derived from of <a
* href="http://en.wikipedia.org/wiki/Topological_sort#Algorithms" > Kahn's
* pseudo code</a> and traverses over vertices as they are returned by input
* map. Leaf nodes can have null or empty values. This method assumes, that
* input is valid DAG, so if cyclic dependency is detected, error is thrown.
* tSortFix is a fix to remove self dependencies and add missing leaf nodes.
* </p>
*
* <pre>
* // For input with elements:
* { F1=[F2, F3, F4], F10=[F7, F4], F11=[F4], F2=[F3, F8, F4], F3=[F6],
* F4=null, F5=[F6, F4], F6=[F7, F8, F4], F7=[F4], F8=[F4], F9=[F4]}
*
* // Output based on input map type:
* HashMap: [F4, F11, F8, F9, F7, F10, F6, F5, F3, F2, F1]
* TreeMap: [F4, F11, F7, F8, F9, F10, F6, F3, F5, F2, F1]
* </pre>
*
* #param g
* <a href="http://en.wikipedia.org/wiki/Directed_acyclic_graph"
* > Directed Acyclic Graph</a>, where vertices are stored as
* {#link java.util.HashMap HashMap} elements.
*
* #return Linear ordering of input nodes.
* #throws Exception
* Thrown when cyclic dependency is detected, error message also
* contains elements in cycle.
*
*/
public static <T> ArrayList<T> tSort(java.util.Map<T, ArrayList<T>> g)
throws Exception
/**
* #param L
* Answer.
* #param S
* Not visited leaf vertices.
* #param V
* Visited vertices.
* #param P
* Defined vertices.
* #param n
* Current element.
*/
{
java.util.ArrayList<T> L = new ArrayList<T>(g.size());
java.util.Queue<T> S = new java.util.concurrent.LinkedBlockingDeque<T>();
java.util.HashSet<T> V = new java.util.HashSet<T>(),
P = new java.util.HashSet<T>();
P.addAll(g.keySet());
T n;
// Find leaf nodes.
for (T t : P)
if (g.get(t) == null || g.get(t).isEmpty())
S.add(t);
// Visit all leaf nodes. Build result from vertices, that are visited
// for the first time. Add vertices to not visited leaf vertices S, if
// it contains current element n an all of it's values are visited.
while (!S.isEmpty()) {
if (V.add(n = S.poll()))
L.add(n);
for (T t : g.keySet())
if (g.get(t) != null && !g.get(t).isEmpty() && !V.contains(t)
&& V.containsAll(g.get(t)))
S.add(t);
}
// Return result.
if (L.containsAll(P))
return L;
// Throw exception.
StringBuilder sb = new StringBuilder(
"\nInvalid DAG: a cyclic dependency detected :\n");
for (T t : P)
if (!L.contains(t))
sb.append(t).append(" ");
throw new Exception(sb.append("\n").toString());
}
/**
* Method removes self dependencies and adds missing leaf nodes.
*
* #param g
* <a href="http://en.wikipedia.org/wiki/Directed_acyclic_graph"
* > Directed Acyclic Graph</a>, where vertices are stored as
* {#link java.util.HashMap HashMap} elements.
*/
public static <T> void tSortFix(java.util.Map<T, ArrayList<T>> g) {
java.util.ArrayList<T> tmp;
java.util.HashSet<T> P = new java.util.HashSet<T>();
P.addAll(g.keySet());
for (T t : P)
if (g.get(t) != null || !g.get(t).isEmpty()) {
(tmp = g.get(t)).remove(t);
for (T m : tmp)
if (!P.contains(m))
g.put(m, new ArrayList<T>(0));
}
}
The problem you are solving is known as topological sort. Kahn's algorithm solves the problem while also detecting invalid input (that is, containing cycles).
The quick way to do this is to remember the set of items that you've already seen, and simply throw an exception if you're about to work out the requirements for an item already in that list. This will definitely indicate some kind of circularity which we can probably assume is a bad thing.
A more advanced solution, if loops in the object graph are allowable, would be to not just store the items, but also map them to their solution. Since you're in the process of calculating the solutions, this would perhaps need to be a Future that you pop in the map to indicate that the evaluation may not be complete yet. Then you can add the "solution placeholders" in the map as soon as you visit a given item. Consequently infinite loops work fine (looking at your trivial invalid case):
Visit F1. Put a Future for this in the map. Recurse to work out F2.
Visit F2. Put a Future for this in the map. See that F1 has already been "solved", and record the concrete solution for F2 as simply creating an F1.
This of course represents a loop in the solution's object model, but that's actually a legitimate representation of the input. If you were displaying this graphically, perhaps as a tree that gets expanded one level at a time, this would render appropriately too ("How do I create an F1? You need to make an F2. How do I create that? You need to make an F1", and so on for as many levels as the user expanded the tree).
(Note that while this sounds silly it can actually reflect some valid scenarios; e.g. in Fallout: New Vegas, several crafting recipes convert between different energy ammo types. Thus to make a Microfusion Cell you need three Small Energy Cells. And to make three Small Energy Cells you need a Microfusion Cell. This would create a loop in the graph, but in this case is actually valid input. I'm just pointing this out in case you're assuming that loops are always wrong input.)
If it is possible for a recipe to have alternatives, perhaps somewhere between these two approaches is the best bet. Follow all of the alternative paths, but if you get into an infinite loop, stop following that one and go with the others.

Categories