Java general array Questions - java

I need to put some different size machines in the storage
I am thinking so I have an array of machines with a size of 30 present storge
Machine[] machine = new Machine[30];
Machine has a size in the constructor. eg, Machine m1 = new Machine(10);
Every machine have different size, some machine may need size 5, some may need size 10.
if I insert a size 5 machine into array, it should take the first 5 slots in the array. if I put a machine with size 10 at the third position, it should take slots from 3-13
public class JavaApplication23 {
/**
* #param args the command line arguments
*/
static Machine[] machine= new Machine[30];
public void findSlot(Machine unit)
{
int slot = 0;
for(int i = 0; i < machine.length; i++)
{
if(fit(i,unit)==true)
{
System.out.println("slot "+i+" is empty");
}
else
{
System.out.println("The line is full");
}
}
}
public boolean fit(int num, Machine machine)
{
boolean check = true;
if(machine[num]==null)
{
for(int i = 0; i < machine.getWidth(); i++)
{
if(machine[num+i]!=null)
{
check = false;
}
}
}
if(check == false)
{
System.out.println("machine does not fit");
}
return check;
}
}
The first function is looking for the empty slot where machine can fit. For example, if machine has a size of 10. slots 1-5 is taken, 8-10 is taken. I can't use 6-7 because is too small. so the function should tell me put in position 11, because 11-20 is empty
the second function is helping to check if the machine can fit
Here is my question. since my array is an array of machine. No matter what size of machine i put in, it will only take one slot. I need an an array with a total size of machines, which one size equal to one slot. so i can put machine into storage one by one and fit.

You can add a Class GroupOfMachines, with an int and an array of machines and go through this class and add each machine

Related

How to create an algorithm that will continue running an algorithm until success in Java

I have a package (https://github.com/skjolber/3d-bin-container-packing/) that will pack items into a container for me. However, if there are too many items for example a quantity of 1000 shirts, and only 500 fit in the biggest container we have, it won't try to pack the remaining 500 the result simply returns null and does not try to combine the containers available.
I am tackling a bin-packing-problem. Note that this doesn't need to be an exact solution as we are just putting together a cost calculator for freight. I stumbled upon a package that handles most of the problem. Basically I have 5 containers that are usable. The API receives a request with products and I gather the dimensions and pack them. My initial thought was to check if the pack was successful and if it was then add it to the List packingResults object so that I have a list. But the way this package is set up I suspect that it will not work without losing integrity of the products.
Here is the service constructor
public PackingService(List<Product> products)
{
containers = SetContainers();
this.packer = new LargestAreaFitFirstPackager(containers);
this.products = products;
PrepareProductsToPack(products);
}
the actual packingMethod
public List<Container> PackItems()
{
packedResultContainers = new ArrayList<Container>();
Container results = packer.pack(productsToPack);
return this.packedResultContainers;
}
and finally, here is me taking my list of Product entitys and preparing them for the packing algorithm.
productsToPack = new ArrayList<BoxItem>();
for(Product product : products)
{
for(int i = 1; i < product.getQuantity(); i++)
{
productsToPack.add(new BoxItem(new Box(product.getSku(),
product.getProductDimensions().getRoundedWidth(),
product.getProductDimensions().getRoundedDepth(),
product.getProductDimensions().getRoundedHeight(),
product.getProductDimensions().getRoundedWeight())));
}
}
The reason I am confused is because if the inital request fails to pack, then I would need to break apart my List into ,2,3,4 depending on how many items there are and there would be no way for me to know how many lists i need to have.
Can anyone provide some insight on how I can adjust my algorithm to handle this?
I should also state that the reason I am doing it this way, is that once I have my list of results, I make making a UPS Api request to gather shipping methods and their rates.
I am updating my answer for future users, this is how I solved the bin-packing-problem
public ArrayList<Container> PackItems()
{
this.packingResults = new ArrayList<Container>();
productSetsToPack = chopped(productsToPack, getInitBoxCount(productsToPack));
int hashMapId = 0;
for(int i = productSetsToPack.size()-1; i >= 0; i--)
{
ArrayList<BoxItem> itemsToPack = productSetsToPack.get(i);
productSetsMap.put(hashMapId, itemsToPack);
pack(itemsToPack, hashMapId, 5); //pack largest sized boxs
++hashMapId;
};
for (Map.Entry<Integer, Container> entry : packedContainerMap.entrySet()) {
int containerKey = entry.getKey();
Container packedContainer = entry.getValue();
int smallestBoxSize = getSmallestBox(productSetsMap.get(containerKey), Integer.parseInt(packedContainer.getName()));
packingResults.add(pack(productSetsMap.get(containerKey), smallestBoxSize));
// ...
}
return packingResults;
}
boo,
What you want is very possible. It will be quite an undertaking, especially if you have 5 different package sizes. I would suggest using recursion.
create a method that finds the smallest number of the largest packages that your order can fit into. lets say it fits into 4 large boxes. then take each large box and attempt to pack it into smaller boxes. the runs would look something like where box 5 is the biggest box and box 1 is the smallest box.
box5 - box5 - box5- box5
box5 - box5 - box5- box4
box5 - box5 - box5- box3
box5 - box5 - box5- box2
box5 - box5 - box5- box1
that run would fit into 3 large boxes and 1 small box.
The code to find the largest box would probably be a while loop like such
int boxCount = getInitBoxCount(products);
public int getInitBoxCount(ArrayList<BoxItems> items)
{
if(productsFit(products,sizeLarge) == null)
{
ArrayList<BoxItems> temp1 = new ArrayList<BoxItems>();
ArrayList<BoxItems> temp2 = new ArrayList<BoxItems>();
for(int x = 0; x < items.length ; x++)
{
if(x > items.length/2)
{
temp1.add(items.get(x))
}
else
{
temp2.add(items.get(x))
}
}
return getInitBoxCount(temp1) + getInitBoxCount(temp2);
}
return 1;
}
This will continually split your list of BoxItems in half until it fits into the number of boxes
so now we have determined a shipping arrangement that will work but also probably have lots of extra space.
The next 2 steps would be to create a recursive way to trim down the box size such as
// 5 is the largest
public int getSmallestBox(int boxsize,ArrayList<BoxItems> items)
{
if(productsFit(boxsize -1)!= null)
{
return getSmallestBox(boxsize -1, items)
}
else
return boxsize;
}
And that will get the smallest box that we can fit the items into. The last thing you need to check for is combining boxes. you may find that you have 4 small boxes and you could combine those into 2 medium boxes. after you can combine and shrink boxes then you sould be able to monitor the results after each run. so the overall program flow would look like this in rough pseudo code.
Container[getInitBoxCount()] shipments //create an array of containers with the size of the inital box count
for(Container c : shipments)
{
c = new LargeContainer();
}
Container[] check; //create new objects into the check array. dont set one array = to anoter
do
{
check = shipments //create new objects into the check array. dont set one array = to anoter
for(Container c: shipments)
getSmallestBox(5, c);
combineBoxes(shipments);
}
while(check == shipments)
See if Spring retry can be of any use.
To have retrial and different logic in the method where you doubt you will not get your first list and so on.
You could generate all possible subsets of your collection of Items, then iterate over those in sorted order (starting with the largest and decreasing size) until you succeed.
This would of course not scale very well. Id also generate the subsets using list indeces instead of references (Add all items to a list, create a set of numbers from 0 to list.size(), then generate all subsets of this set.)
With the current version, this works:
#Test
void testIssue158() {
List<Container> containers = new ArrayList<>();
containers.add(new Container("X",10, 10, 5, 1000));
List<BoxItem> products = new ArrayList<>();
for(int i = 0; i < 1000; i++) {
products.add(new BoxItem(new Box(Integer.toString(i), 1, 1, 1, 1)));
}
LargestAreaFitFirstPackager packager = new LargestAreaFitFirstPackager(containers, false, true, true);
List<Container> fits = packager.packList(products, 50, Long.MAX_VALUE);
assertNotNull(fits);
assertEquals(fits.size(), 2);
}
Hopefully that means no custom workaround for multi-container fits!

Java - Why void when I'm storing value in variable

So, the question is. If I'm calling method guess from class - Player and it is a void-type method without return statement in it, how come I'm able to store result of number = (int)(Math.random() * 10) in number variable for 3 different objects (p1, p2, p3)?
I'm little confused about when should I use return statement or void-type methods, because if number = (int)(Math.random() * 10) is giving some results which I want to use, why then I don't need to return this results from a method to pass them to the number variable which I declared in int number = 0;
public class Player {
int number = 0;
public void guess() {
number = (int)(Math.random() * 10);
System.out.println("I'm guessing " + number);
}
}
A void method does not return anything, but it still allows you to do things. (Print to the console, modify variables etc) The void keyword just means that it doesn't return a value. (In void methods you can still use a blank return; to end the method) And because you are modifying your number variable in the GuessGame object the changes you make will stay even though you don't return a variable. Try this simple test to see what I mean:
//In your GuessGame class
int number = 0;
public void foo() {
number++;
}
public static void main(String[] args) {
GuessGames games = new GuessGames();
games.foo();
System.out.println(games.number);
//Outputs 1
}
docs for the return statement
The point is: where is the result of Math.random() * 10 physically stored on your computer when your program is run? You list two options.
Options 1: Instance field
In this case the compiler instructs your operating system to reserve space for a int variable for the whole life of the Player object. The player object may live for microseconds, seconds, minutes, hours, days, months, ... it depends! This storage space is usually find in the RAM of the computer and from Java you can access it with the syntax myPlayer.number as long as you have a Player reference somewhere.
Options 2: Return value
In this case the compiler finds the space to store the result of the computation in a register of the Java virtual machine, that you can mentally map to a register of the physical processor. This value will only at best survive for a couple of processor cycles (there are gazillinos in a GHz CPU, so it's really a tiny little fracion of a second) if you don't store it somewhere else - and if you don't it's lost forever. See the following example:
private int someRandom;
private int gimmeARandom() {
return Math.random() * 10;
}
private int test() {
int someRandom = gimmeARandom(); // --> store the value until end of method
this.someRandom = someRandom; // --> further keep it so we can read it later
gimmeARandom(); // --> what did it returned? We'll never know
}
Void is different than static - void just means the function does not return anything, but it can still be a instance method, i.e. one that is associated with each new instance of a class. I think you're confusing this with the functionality of static, which allows methods to be called without an instance of the class.

How do apps measure CPU usage (as a %)?

So I'm trying to write an app that measures CPU usage (ie, the time CPU is working vs the time it isn't). I've done some research, but unfortunately there are a bunch of different opinions on how it should be done.
These different solutions include, but aren't limited to:
Get Memory Usage in Android
and
http://juliano.info/en/Blog:Memory_Leak/Understanding_the_Linux_load_average
I've tried writing some code myself, that I though might do the trick, because the links above don't take into consideration when the core is off (or do they?)
long[][] cpuUseVal = {{2147483647, 0} , {2147483647, 0} , {2147483647, 0} ,
{2147483647, 0} , {2147483647, 0}};
public float[] readCPUUsage(int coreNum) {
int j=1;
String[] entries; //Array to hold entries in the /proc/stat file
int cpu_work;
float percents[] = new float[5];
Calendar c = Calendar.getInstance();
// Write the dataPackage
long currentTime = c.getTime().getTime();
for (int i = 0; i <= coreNum; i++){
try {
//Point the app to the file where CPU values are located
RandomAccessFile reader = new RandomAccessFile("/proc/stat", "r");
String load = reader.readLine();
while (j <= i){
load = reader.readLine();
j++;
}
//Reset j for use later in the loop
j=1;
entries = load.split("[ ]+");
//Pull the CPU working time from the file
cpu_work = Integer.parseInt(entries[1]) + Integer.parseInt(entries[2]) + Integer.parseInt(entries[3])
+ Integer.parseInt(entries[6]) + Integer.parseInt(entries[6]) + Integer.parseInt(entries[7]);
reader.close();
percents[i] = (float)(cpu_work - cpuUseVal[i][1]) / (currentTime - cpuUseVal[i][0]);
cpuUseVal[i][0] = currentTime;
cpuUseVal[i][1] = cpu_work;
//In case of an error, print a stack trace
} catch (IOException ex) {
ex.printStackTrace();
}
}
//Return the array holding the usage values for the CPU, and all cores
return percents;
}
So here is the idea of the code I wrote...I have a global array with some dummy values that should return negative percentages the first time the function is run. The values are being stored in a database, so I would know to disregard anything negative. Anyway, the function runs, getting values of time the cpu is doing certain things, and comparing it to the last time the function is run (with the help of the global array). These values are divided by the amount of time that has passed between the function runs (with the help of the calendar)
I've downloaded some of the existing cpu usage monitors and compared them to values I get from my app, and mine are never even close to what they get. Can someone explain what I'm doing wrong?
Thanks to some help I have changed my function to look like the following, hope this helps others who have this question
// Function to read values from /proc/stat and do computations to compute CPU %
public float[] readCPUUsage(int coreNum) {
int j = 1;
String[] entries;
int cpu_total;
int cpu_work;
float percents[] = new float[5];
for (int i = 0; i <= coreNum; i++) {
try {
// Point the app to the file where CPU values are located
RandomAccessFile reader = new RandomAccessFile("/proc/stat","r");
String load = reader.readLine();
// Loop to read down to the line that corresponds to the core
// whose values we are trying to read
while (j <= i) {
load = reader.readLine();
j++;
}
// Reset j for use later in the loop
j = 1;
// Break the line into separate array elements. The end of each
// element is determined by any number of spaces
entries = load.split("[ ]+");
// Pull the CPU total time on and "working time" from the file
cpu_total = Integer.parseInt(entries[1])
+ Integer.parseInt(entries[2])
+ Integer.parseInt(entries[3])
+ Integer.parseInt(entries[4])
+ Integer.parseInt(entries[5])
+ Integer.parseInt(entries[6])
+ Integer.parseInt(entries[7]);
cpu_work = Integer.parseInt(entries[1])
+ Integer.parseInt(entries[2])
+ Integer.parseInt(entries[3])
+ Integer.parseInt(entries[6])
+ Integer.parseInt(entries[7]);
reader.close();
//If it was off the whole time, say 0
if ((cpu_total - cpuUseVal[i][0]) == 0)
percents[i] = 0;
//If it was on for any amount of time, compute the %
else
percents[i] = (float) (cpu_work - cpuUseVal[i][1])
/ (cpu_total - cpuUseVal[i][0]);
//Save the values measured for future comparison
cpuUseVal[i][0] = cpu_total;
cpuUseVal[i][1] = cpu_work;
// In case of an error, print a stack trace
} catch (IOException ex) {
ex.printStackTrace();
}
}
// Return the array holding the usage values for the CPU, and all cores
return percents;
}
Apps don't measure CPU usage, the kernel does by interrupting the process 100 times per second (or some other frequency depending on how the kernel is tuned) and incrementing a counter which corresponds to what it was doing when interrupted.
If in the process => increment the user counter.
If in the kernel => increment the system counter
If waiting for disk or network or a device => increment the waiting for IO
Otherwise increment the idle counter.
The uptime is determined by the decaying average length of the run queue i.e. how many threads are waiting to run. The first number is the average length over the last minute. You can get the load average via JMX.

Count beepers in stacks in Java

Need to write method called clearStacks() that moves the most recently created robot forward until it reaches a wall picking up all beepers at it goes. The method should return no value
and take no parameters.
It also has a side-effect: the method prints how many beepers the robot picked up in each stack. Supposing there were 3 stacks on a row, the output might look like this:
Beepers: 4
Beepers: 1
Beepers: 7
My problem that I can not write how many beepers the robot picked up in each stack. Only overall amount. I am new in Java..
My code:
void clearStacks() {
int beepers=0;
while(isSpaceInFrontOfRobotClear()) {
moveRobotForwards();
while(isItemOnGroundAtRobot()) {
pickUpItemWithRobot();
++beepers;
println(beepers);
}
}
}
Before checking for a stack, you'll want to reset your count. You'll then need to use a conditional statement to see if any beepers were picked up after clearing a stack (or determining that a stack was not there).
void clearStacks() {
int beepers=0;
while(isSpaceInFrontOfRobotClear()) {
moveRobotForwards();
/* Reset the count of beepers. */
beepers = 0;
/* Pick up any beepers at current spot. */
while(isItemOnGroundAtRobot()) {
/* Pick up beeper, and increment counter. */
pickUpItemWithRobot();
++beepers;
}
/* Check to see if we picked up any beepers.
* if we did, print the amount.
*/
if(beepers > 0){
println(beepers);
}
}
}
Maybe try implementing an array? You could use the first 3 elements to represent the first 3 stacks and then the value could represent how many beepers were picked up in each stack.
int[] beepers = new int[3];
int count = 0;
while(isSpaceInFrontOfRobotClear()) {
moveRobotForwards();
while(isItemOnGroundAtRobot()) {
pickUpItemWithRobot();
beepers[0]++;
if (count > #numberOfBeepers) {
break;
}
}
for (int i: beepers) {
System.out.print(beepers[i] + " ")
}
}
}
Let me know if this answers your question or if it didn't

Efficient way to allot the next available VM

The method getNextAvailableVm() allots virtual machines for a particular data center in a round-robin fashion. (The integer returned by this method is the machine allotted)
In a data center there could be virtual machines with different set of configurations. For example :
5 VMs with 1024 memory
4 VMs with 512 memory
Total : 9 VMs
For this data center a machine with 1024 memory will get task 2 times as compared to machine with 512 memory.
So machines for this data center are returned by the getNextAvailableVm() in the following way :
0 0 1 1 2 2 3 3 4 4 5 6 7 8
This is the current way, the machines are being returned.But there is a problem.
There could be cases, when a particular machine is busy and cannot be allotted the task.Instead the next machine available with the highest memory must be allotted the task.I have not been able to implement this.
For example :
0 (allotted first time)
0 (to be allotted the second time)
but if 0 is busy..
allot 1 if 1 is not busy
next circle check if 0 is busy
if not busy allot 0 (only when machine numbered 0 has not handled the requests it is entitled to handle)
if busy, allot the next
cloudSimEventFired method in the following class is called when ever the machine gets freed or is allotted.
public class TempAlgo extends VmLoadBalancer implements CloudSimEventListener {
/**
* Key : Name of the data center
* Value : List of objects of class 'VmAllocationUIElement'.
*/
private Map<String,LinkedList<DepConfAttr>> confMap = new HashMap<String,LinkedList<DepConfAttr>>();
private Iterator<Integer> availableVms = null;
private DatacenterController dcc;
private boolean sorted = false;
private int currentVM;
private boolean calledOnce = false;
private boolean indexChanged = false;
private LinkedList<Integer> busyList = new LinkedList<Integer>();
private Map<String,LinkedList<AlgoAttr>> algoMap = new HashMap<String, LinkedList<AlgoAttr>>();
private Map<String,AlgoHelper> map = new HashMap<String,AlgoHelper>();
private Map<String,Integer> vmCountMap = new HashMap<String,Integer>();
public TempAlgo(DatacenterController dcb) {
confMap = DepConfList.dcConfMap;
this.dcc = dcb;
dcc.addCloudSimEventListener(this);
if(!this.calledOnce) {
this.calledOnce = true;
// Make a new map using dcConfMap that lists 'DataCenter' as a 'key' and 'LinkedList<AlgoAttr>' as 'value'.
Set<String> keyst =DepConfList.dcConfMap.keySet();
for(String dataCenter : keyst) {
LinkedList<AlgoAttr> tmpList = new LinkedList<AlgoAttr>();
LinkedList<DepConfAttr> list = dcConfMap.get(dataCenter);
int totalVms = 0;
for(DepConfAttr o : list) {
tmpList.add(new AlgoAttr(o.getVmCount(), o.getMemory()/512, 0));
totalVms = totalVms + o.getVmCount();
}
Temp_Algo_Static_Var.algoMap.put(dataCenter, tmpList);
Temp_Algo_Static_Var.vmCountMap.put(dataCenter, totalVms);
}
this.algoMap = new HashMap<String, LinkedList<AlgoAttr>>(Temp_Algo_Static_Var.algoMap);
this.vmCountMap = new HashMap<String,Integer>(Temp_Algo_Static_Var.vmCountMap);
this.map = new HashMap<String,AlgoHelper>(Temp_Algo_Static_Var.map);
}
}
#Override
public int getNextAvailableVm() {
synchronized(this) {
String dataCenter = this.dcc.getDataCenterName();
int totalVMs = this.vmCountMap.get(dataCenter);
AlgoHelper ah = (AlgoHelper)this.map.get(dataCenter);
int lastIndex = ah.getIndex();
int lastCount = ah.getLastCount();
LinkedList<AlgoAttr> list = this.algoMap.get(dataCenter);
AlgoAttr aAtr = (AlgoAttr)list.get(lastIndex);
indexChanged = false;
if(lastCount < totalVMs) {
if(aAtr.getRequestAllocated() % aAtr.getWeightCount() == 0) {
lastCount = lastCount + 1;
this.currentVM = lastCount;
if(aAtr.getRequestAllocated() == aAtr.getVmCount() * aAtr.getWeightCount()) {
lastIndex++;
if(lastIndex != list.size()) {
AlgoAttr aAtr_N = (AlgoAttr)list.get(lastIndex);
aAtr_N.setRequestAllocated(1);
this.indexChanged = true;
}
if(lastIndex == list.size()) {
lastIndex = 0;
lastCount = 0;
this.currentVM = lastCount;
AlgoAttr aAtr_N = (AlgoAttr)list.get(lastIndex);
aAtr_N.setRequestAllocated(1);
this.indexChanged = true;
}
}
}
if(!this.indexChanged) {
aAtr.setRequestAllocated(aAtr.getRequestAllocated() + 1);
}
this.map.put(dataCenter, new AlgoHelper(lastIndex, lastCount));
//System.out.println("Current VM : " + this.currentVM + " for data center : " + dataCenter);
return this.currentVM;
}}
System.out.println("--------Before final return statement---------");
return 0;
}
#Override
public void cloudSimEventFired(CloudSimEvent e) {
if(e.getId() == CloudSimEvents.EVENT_CLOUDLET_ALLOCATED_TO_VM) {
int vmId = (Integer) e.getParameter(Constants.PARAM_VM_ID);
busyList.add(vmId);
System.out.println("+++++++++++++++++++Machine with vmID : " + vmId + " attached");
}else if(e.getId() == CloudSimEvents.EVENT_VM_FINISHED_CLOUDLET) {
int vmId = (Integer) e.getParameter(Constants.PARAM_VM_ID);
busyList.remove(vmId);
//System.out.println("+++++++++++++++++++Machine with vmID : " + vmId + " freed");
}
}
}
In the above code, all the lists are already sorted with the highest memory first.The whole idea is to balance the memory by allocating more tasks to a machine with higher memory.
Each time a machine is allotted request allocated is incremented by one.Each set of machines have a weight count attached to it, which is calculated by dividing memory_allotted by 512.
The method getNextAvailableVm() is called by multiple threads at a time. For 3 Data Centers 3 threads will simultaneously call getNextAva...() but on different class objects.The data center returned by the statement this.dcc.getDataCenterName() in the same method is returned according to the data center broker policy selected earlier.
How do I make sure that the machine I am currently returning is free and if the machine is not free I allot the next machine with highest memory available.I also have to make sure that the machine that is entitled to process X tasks, does process X tasks even that machine is currently busy.
This is a general description of the data structure used here :
The code of this class is hosted here on github.
This is the link for the complete project on github.
Most of the data structures/classes used here are inside this package
Perhaps you are over thinking the problem. A simple strategy is to have a broker which is aware of all the pending tasks. Each task worker or thread asks the broker for a new message/task to work on. The broker gives out work in the order it was asked for. This is how JMS queues works. For the JVMs which can handle two tasks you can start two threads.
There is many standard JMS which do this but I suggest looking at ActiveMQ as it is simple to get started with.
note in you case, a simpler solution is to have one machine with 8 GB of memory. You can buy 8 GB for a server for very little ($40 - $150 depending on vendor) and it will be used more efficiently in one instance by sharing resource. I assume you are looking at much larger instances. Instances smaller than 8 GB are better off just upgrading it.
How do I make sure that the machine I am currently returning is free
This is your scenario, if you don't know how to tell if a machine is free, I don't see how anyone would have more knowledge of you application.
and if the machine is not free I allot the next machine with highest memory available.
You need to look at the free machines and pick the one with the most available memory. I don't see what the catch is here other than doing what you have stated.
I also have to make sure that the machine that is entitled to process X tasks, does process X tasks even that machine is currently busy.
You need a data source or store for this information. What is allowed to run where. In JMS you would have multiple queues and only pass certain queues to the machines which can process those queue.

Categories

Resources