I'm making a program that calculates the population for a year given the start year (2011) and increases the population by 1.2% every year. The population for 2011 is 7.000 (I'm using decimals, instead of billions). Here is the working part of my code
package src;
import java.util.Scanner;
import java.text.DecimalFormat;
public class Demographics {
public static void main(String[] args) {
Scanner user_input= new Scanner(System.in);
//Part 1
System.out.println("===--- Part 1 ---===");
System.out.println("Population in 2011: 7.000");
System.out.print("What is the desired year? ( > 2011) ");
int startYear = 2011;
int endYear = user_input.nextInt();
while (endYear <= startYear){
System.out.println("Invalid end year.");
System.out.print("What is the desired year? ( > 2011) ");
endYear = user_input.nextInt();
break;
}
double t = 0.012;
double nbr = (endYear - startYear);
double pStart = 7.000;
double pEnd = pStart * Math.exp(nbr * t);
DecimalFormat nf = new DecimalFormat("#.000");
System.out.println("Population in " + endYear + ":(nf.format(pEnd)));
//Part 2
System.out.println("===--- Part 2 ---===");
System.out.print("What is the target population? ( > 7.000) ");
double pTarget = user_input.nextDouble();
while (pTarget <= pStart){
System.out.println("Invalid target population.");
System.out.print("What is the target population? ( > 7.000) ");
pTarget = user_input.nextDouble();
break;
}
while (pStart < pTarget){
startYear++;
pStart = pStart + (pStart * 0.012);
System.out.println("Population in " + startYear + ": " + nf.format((pStart)));
}
}
}
Part 1 of my code calculates the population of a year when the user enters it, then part 2 shows the calculations of how many years it will take when a user enters a population to get to that point.
Here is the code that doesn't work
//Part 3
System.out.println("===--- Part 3 ---===");
t = 1.2;
pStart = 7.000;
pEnd = pStart * Math.exp(nbr * t);
while (pStart < pTarget){
startYear++;
pEnd = pStart + (pStart * 0.012);
if (pEnd >= pStart * 2 ){
System.out.println("Population in " + startYear + ": " + nf.format((pEnd)) + " Population growth rate " + ": " + (t / 2));
}else{
System.out.println("Population in " + startYear + ": " + nf.format((pEnd)) + " Population growth rate " + ": " + t);
}
}
Currently when i have part 3 in my code it does an infinite loop without multiplying the population. What I'm trying to do in part 3 is pretty much the same thing in part 2, but in part 3 it will display the population growth rate (t) and divide it by 2 every time the population doubles. For example:
Population in 2019 : 7.705 ; population growth rate : 1.2%
Population in 2020 : 7.798 ; population growth rate : 1.2%
Population in 2021 : 7.892 ; population growth rate : 1.2%
...
Population in 2068 : 13.873 ; population growth rate : 1.2%
Population in 2069 : 14.040 ; population growth rate : 0.6%
Anyone have any ideas on how to achieve this?
if you have problems in the loop the reason is in the condition!
while (pStart < pTarget){
so to end this code, inside the loop one of this situation has to happen:(according with your condition)
A)pStart should increase in value
B)pTarget should decrement in value
C)a "break;" have to occur
in your code you increase: startYear and pEnd, but this are not the condition to close the loop according with your condition. (i write it before:A,B,C)
1) also startYear are not re initialize it before the loop, and start already at a high value. you have to add bedore the loop:
startYear = 2011;
2) you should as far as possible to create new variables for the segment 3, is not to have problems like the one just described, is to be clear about what you are doing.
my advice for part three is this:
(Considering that I have no clear what I wanted to do reading your code, you have to cange it and make it good for you)
System.out.println("===--- Part 3 ---===");
t = 1.2;
startYear = 2011; // I add it
double pEveryYear = 7000;
while (pEveryYear < pTarget){
startYear++;
pEveryYear = pEveryYear + (pEveryYear * 0.012);
if (pEveryYear >= pTarget ){ // this condition cange only the print in the console
System.out.println("Population in " + startYear + ": " + nf.format((pEveryYear)) + " Population growth rate " + ": " + (t / 2));
break; // if you write it before the system.out you can't read it in the console.
}else{
System.out.println("Population in " + startYear + ": " + nf.format((pEveryYear)) + " Population growth rate " + ": " + t);
}
}
}
this the console output for input like "8000":
===--- Part 3 ---===
Population in 2012: 7084.000 Population growth rate : 1.2
Population in 2013: 7169.008 Population growth rate : 1.2
Population in 2014: 7255.036 Population growth rate : 1.2
Population in 2015: 7342.097 Population growth rate : 1.2
Population in 2016: 7430.202 Population growth rate : 1.2
Population in 2017: 7519.364 Population growth rate : 1.2
Population in 2018: 7609.596 Population growth rate : 1.2
Population in 2019: 7700.912 Population growth rate : 1.2
Population in 2020: 7793.323 Population growth rate : 1.2
Population in 2021: 7886.842 Population growth rate : 1.2
Population in 2022: 7981.485 Population growth rate : 1.2
Population in 2023: 8077.262 Population growth rate : 0.6
It seems you have two variables in the while loop that you try to compare however these do not actually get updated while iterating in the while loop. So after every iteration within the loop, the while condition just stays true.
See the last few lines below for a minor change to your part 3 code :
System.out.println("===--- Part 3 ---===");
t = 1.2;
pStart = 7.000;
pEnd = pStart * Math.exp(nbr * t);
while (pStart < pTarget){
startYear++;
pEnd = pStart + (pStart * 0.012);
if (pEnd >= pStart * 2 ){
System.out.println("Population in " + startYear + ": " + nf.format((pEnd)) + " Population growth rate " + ": " + (t / 2));
} else {
System.out.println("Population in " + startYear + ": " + nf.format((pEnd)) + " Population growth rate " + ": " + t);
}
pStart = startYear; // <-- NEW, you can probably use pStart instead of startYear in this code
}
The only missing thing I see in your code is that you are not updating pStart every time you go through the loop. This will not only make your loop infinite but it's also doing a wrong calculation every time except the first iteration. I added only one line from your code:
System.out.println("===--- Part 3 ---===");
t = 1.2;
pStart = 7.000;
pEnd = pStart * Math.exp(nbr * t);
while (pStart < pTarget){
startYear++;
pEnd = pStart + (pStart * 0.012);
if (pEnd >= pStart * 2 ){
System.out.println("Population in " + startYear + ": " + nf.format((pEnd)) + " Population growth rate " + ": " + (t / 2));
}else{
System.out.println("Population in " + startYear + ": " + nf.format((pEnd)) + " Population growth rate " + ": " + t);
}
pStart = pEnd;
}
Related
Im having some trouble with my fairness constraint, I want to make sure employees get:
Even amount of shifts during weeks.
Even amount of shifts in total.
Basically I want to avoid that fairness is only checking weeks (so that if there's 2 extra shifts, it won't be the same two employees getting those every week, potentially)
And I want to avoid fairness checking only the total (so that maybe one employee get much more shifts one week, then none the next, but overall theyd all still get even hours)
So I tried to follow what the docs for Optaplanner said in regards to a fairness constraint, and made two constraints for that, but unlike the docs preview that uses shifts, I need mine to be estimated in hours... So now, my code:
public int accumulateFairnessInHoursPerEmployeePerWeek(Week week)
{
//System.out.println("WEEK FAIRNESS CONSTRAINT:");
int actualWorkload = 0;
int totalAssignmentsDuringWeek = 0;
for(Employee emp : getEmployees())
{
List<Assignment> assignmentsForEmployeeDuringWeek = new ArrayList<>();
for(Assignment currentAss : getAssignmentsForSpecificWeek(week))
{
if(currentAss.getEmployee() == emp)
{
assignmentsForEmployeeDuringWeek.add(currentAss);
}
}
totalAssignmentsDuringWeek += getDurationForAssignments(assignmentsForEmployeeDuringWeek)/3600;
actualWorkload += (int) Math.pow(getDurationForAssignments(assignmentsForEmployeeDuringWeek)/3600, 2);
//System.out.println(emp.getName() + " has " + getDurationForAssignments(assignmentsForEmployeeDuringWeek)/3600 + " hours. Score: " + actualWorkload + " total: " + actualWorkload + " " + ass.getShift().getStartDate());
}
int idealWorkLoad = (int) Math.pow(totalAssignmentsDuringWeek, 2)/getEmployees().size();
//System.out.println("IDEAL: " + idealWorkLoad + " ACTUAL: " + actualWorkload + " FAIRNESS: " + (actualWorkload -idealWorkLoad));
return (actualWorkload - idealWorkLoad);
}
public int accumulateFairnessInHoursPerEmployeeInTotal()
{
System.out.println("TOTAL FAIRNESS CONSTRAINT:");
int actualWorkload = 0;
int totalDuration = 0;
for(Employee emp : getEmployees())
{
List<Assignment> assignmentsForEmployee = new ArrayList<>();
for(Assignment currentAss : getAssignments())
{
if(currentAss.getEmployee() == emp)
{
assignmentsForEmployee.add(currentAss);
}
}
totalDuration += getDurationForAssignments(assignmentsForEmployee)/3600;
actualWorkload += (int) Math.pow(getDurationForAssignments(assignmentsForEmployee)/3600, 2);
System.out.println(emp.getName() + " has " + getDurationForAssignments(assignmentsForEmployee)/3600 + " hours. Score: " + actualWorkload);
}
int idealWorkLoad = (int) Math.pow(totalDuration, 2)/getEmployees().size();
System.out.println("IDEAL: " + idealWorkLoad + " ACTUAL: " + actualWorkload + " FAIRNESS: " + (actualWorkload - idealWorkLoad));
return (actualWorkload - idealWorkLoad);
}
And here's the drools:
rule "EvenWorkloadPerEmployeeTotal"
when
$service : Service
(
$service.accumulateFairnessInHoursPerEmployeeInTotal() != 0
)
then
if(isDroolActivated(kcontext.getRule().getName(), $service))
{
setDroolRating(scoreHolder, kcontext, $service.getDroolStrength(drools), $service.accumulateFairnessInHoursPerEmployeeInTotal());
}
end
rule "EvenWorkloadPerEmployeePerWeek"
when
$week : Week()
$service : Service
(
$service.accumulateFairnessInHoursPerEmployeePerWeek($week) != 0
)
then
if(isDroolActivated(kcontext.getRule().getName(), $service))
{
setDroolRating(scoreHolder, kcontext, $service.getDroolStrength(drools), $service.accumulateFairnessInHoursPerEmployeePerWeek($week));
}
end
It seemingly works most of the time, especially in smaller datasets... However, when I use a bigger dataset...
This is my results:
A has 76.0 hours. Score: 5776
B has 118.0 hours. Score: 19700
C has 76.0 hours. Score: 25476
D has 83.0 hours. Score: 32365
E has 88.0 hours. Score: 40109
F has 72.0 hours. Score: 45293
G has 68.0 hours. Score: 49917
H has 64.0 hours. Score: 54013
I has 96.0 hours. Score: 63229
J has 94.0 hours. Score: 72065
K has 92.0 hours. Score: 80529
L has 67.0 hours. Score: 85018
M has 98.0 hours. Score: 94622
N has 95.0 hours. Score: 103647
O has 101.0 hours. Score: 113848
P has 90.0 hours. Score: 121948
Q has 93.0 hours. Score: 130597
R has 108.0 hours. Score: 142261
S has 124.0 hours. Score: 157637
T has 116.0 hours. Score: 171093
IDEAL: 157560 ACTUAL: 171093 FAIRNESS: 13533
The numbers go pretty high...
And I doubt anyone finds it fair that G and H gets only 64-68 hours, but S must work for 124 hours
I'm wondering if theres another/better way to estimate fairness when using time instead of shifts to calculate fairness?
EDIT: Probably worth noting that I tried with days as well, but the numbers seemed far too small using those, it was like it didn't care much for a single day too much on one employee compared to another.
I'm using these constraints at the same time, but not with other constraints involved
Take a look at the tennis example, specifically this line.
rule "fairAssignmentCountPerTeam"
when
accumulate(
$t : Team()
and accumulate(
TeamAssignment(team == $t);
$assignmentCount : count() // This could be a sum of hours too
);
$result : loadBalance($assignmentCount)
)
then
scoreHolder.addMediumConstraintMatch(kcontext, - (int) $result.getMeanDeviationSquaredSumRootMillis());
end
Suppose that the tuition for a university is $10,000 this year and increases 5% every year. In one year, the tuition will be $10,500. Write a program that computes the tuition in ten years and the total cost of four years' worth of tuition after the tenth year.
I can calculate the tenth year tuition easily enough. What has me stumped is how to add the unique tuition values at years 11, 12, 13 and 14.
double Fee = 10000;
double Year = 1;
double TotalFee;
double Rate = 5;
double TotalCost = 15000 + 15500 + 16000 + 16500;
System.out.println("Year " + " Total Fee ");
System.out.println();
while (Year <= 14) {
TotalFee = Fee + ((Fee * ((Year * Rate) - Rate)) / 100);
System.out.println(Year + " " + " "+ TotalFee);`
Year++;
}
System.out.println("Total cost tuition of 4 years starting 10 years from now is " + TotalCost);
The last while loop is my attempt at adding the 4 years. How could I pull out the unique values of TotalCost at iterations 11 to 14 and add them?
Since you want to increase the amount 5% every year, instead of having rate = 5
You should have rate = 1.05.
With the rate as 1.05 you can do this
FeeAtYear1 = 10000*1.05^0 = 10000
FeeAtYear2 = 10000*1.05^1 = 10500
FeeAtYear3 = 10000*1.05^2 = 11025
FeeAtYear4 = 10000*1.05^3 = 11576.25
...
FeeAtYear10 = 10000*1.05^9 = ~16288.95
You don't even need a while loop.
TotalCost = 10000 *1.05^10 + 10000 *1.05^11 + 10000 *1.05^12 + 10000 *1.05^13;
I'm making a program for my java class that calculates the population for a year given the start year (2011) and increases the population by 1.2% every year. The population for 2011 is 7.000 (I'm using decimals, instead of billions). I currently have this code.
int startYear = 2011;
int endYear = user_input.nextInt();
double t = 1.2; //Population percent increase anually
double nbr = (endYear - startYear); //Number of years increased
double pStart = 7.000; //Starting population of 2011
double pEnd = pStart * Math.exp(nbr * t); // Ending population of user input
DecimalFormat nf = new DecimalFormat("2");
System.out.println("Population in " + endYear + ": " (nf.format(pEnd)));
There's no errors in the code, everything works, but I'm having troubles with the pEnd equation. Currently when I enter 2016 for the end year, i get 22824. I've tried googling a formula, but i can't find anything. Do any of you guys have an idea of the formula? If you enter 2016 for the end year, it should be around 7.433
You're incrementing by a factor of 1.2, which would represent 120% instead of 1.2%. I think what you want is :
double t = 0.012;
This change gives me an exact value of 7.4328558258175175 from 2011 to 2016.
EDIT : here's the code as requested by the author :
public static void main(String args[]){
int startYear = 2011;
int endYear = 2016;
double t = 0.012; //Population percent increase anually
double nbr = (endYear - startYear); //Number of years increased
double pStart = 7.000; //Starting population of 2011
double pEnd = pStart * Math.exp(nbr * t); // Ending population of user input
System.out.println("Population in " + endYear + ": " + pEnd);
}
Use Math.pow(1 + t / 100, nbr) instead of Math.exp(nbr * t) because you need (1+t/100)^nbr (i.e. multiply 1 + t / 100 on itself nbr times), not exp^(nbr*t):
double pEnd = pStart * Math.pow(1 + t / 100, nbr); // Ending population of user input
Try this.
double pEnd = pStart * Math.pow(1.0 + t / 100, nbr);
I am writing a desktop application which will be used to calculate the monthly depreciation and Accumulation of an asset.
The accumulation is based on the number of months the user specifies.
therefore if the user specified 12 months, it should accumulate over those months.
Also the user should be able to view the accumulation value for for every month so far it is in the specified number of months. e.g if i select January it should give me the accumulated value for January and so on......
CHALLENGES : first challenge is getting the accumulation values for all the user specified months 2nd one is how to link this concept with my j form and my database since the codes i have works but how to fuse it into my program is a problem.
Depreciation Method: Straight line
below is a sample code
private void getAccumulation() {
try {
for (int row = 0; row <= 5; row++) {
double Cost_Of_Acquisition = 2000;
double Estimated_Residual_Value = 250;
int Estimated_Useful_Life = 5;
int depreciationMethod = 1;
System.out.println(" acquisition cost of asset = " + (int) Cost_Of_Acquisition);
System.out.println(" salvage value = " + (int) Estimated_Residual_Value);
System.out.println(" number of months = " + Estimated_Useful_Life);
System.out.println(" depreciation method = " + depreciationMethod);
for (int y = 1; y <= 5; y++) {
switch (depreciationMethod) {
case 1:
System.out.println(" straight line depreciation ");
double StraightLineDepreciation = ((Cost_Of_Acquisition - Estimated_Residual_Value) / Estimated_Useful_Life);
double AccumulatedDeprecaitionSL = (StraightLineDepreciation * y);
System.out.println("Asset number " + "1" + " uses straight line depreciation");
System.out.println(" depreciation charge for asset number " + "1" + " in month " + y + "=" + StraightLineDepreciation);
System.out.println("accumulated depreciation is " + AccumulatedDeprecaitionSL);
break;
case 2:
System.out.println(" sum of months digits depreciation ");
int SumofMonths = (0);
break;
}
}
}
}
}
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I am working on a function where I am calculating meter units to amount. Rules for meter calcualtions are :
Minimum fare on 1.6km amt - 12/-
Subsequent 1 km amt - 7/-
25% additional fare for journey for midnight
The function I have written is :
public static void CalculateAutoFare(int kmIndex) {
double fare = 12.00;
double night = 15.00;
double subseIncre = 1.50;
double nightIncre = 0.25;
int j=0;
for (int i=1; i <= kmIndex; i++) {
if (i == 3 || j == 4) {
fare += 1.00f;
j =0;
}
else {
fare += subseIncre;
j++;
}
fare = Math.round(fare*2f)/2f;
double extra = ((double) fare * nightIncre);
night = fare + extra;
night = Math.round(night*2f)/2f;
System.out.println("I = " + i + " Fare = " + fare + " Night = " + night + " 25%Extra = " + extra);
}
System.out.println("Day = " + fare + " Night = " + night);
}
kmIndex is the index of km. Meter readings are as 1.00, 1.10, 1.20, 1.30...1.90, 2.00.... Thus kmIndex for 1.00 = 0, 1.10 = 1, 1.20 - 3 and so on.
Results that I get as per code and should be is mentioned below :
I have worked till 4.00 and where the results are not right are declared undet Should Be of relevant to Day or Night.
I worked a lot on this but couldn't get results as expected. If I try to correct 1 thing then other gets wrong or doesn't give expected results. Can anyone help me out with this. Have spent almost whole day trying to solve this.
I've analyzed the worksheet and I haven't found a formula that gives the results shown there. It seems that some values have some rounding differences. I've realized that only the values with 25 or 75 cents were different. For example, you calculated 18,5 and it should be 19 (the result was 18,75 and you rounded down to 18,5, but it should be rounded up to 19).
So, if you don't have the original formula that was used to create the table, I think the only way to be sure that the results will match the worksheet is to hardcode it. It's not an elegant solution, but it guarantees the correct result.
Small tweak in the code did the trick. You wanted .75 round as .5 so instead of multiply by 2 multiply by it's immediate smaller float.
{
double fare = 12.00;
double night = 15.00;
double subseIncre = 1.50;
double nightIncre = 0.25;
int j=0;
for (int i=1; i <= 22; i++) {
if (i == 3 || j == 4) {
fare += 1.00f;
j =0;
}
else {
fare += subseIncre;
j++;
}
double extra = ((double) fare * nightIncre);
night = fare + extra;
;
System.out.println("I = " + i + " Fare = " + fare + " Night = " + night + " 25%Extra = " + extra);
}
System.out.println("actual Day = " + fare + " Night = " + night);
fare = Math.round(fare*1.99f)/2f;
night = Math.round(night*1.99f)/2f;
System.out.println("rounded Day = " + fare + " Night = " + night);
}