trying to calculate profit in java - java

The first parameter is a HashMap representing the selling price of each item in our store (that is given).
The second parameter is also a HashMap but this one represents our cost for us to purchase each item for our inventory.
The third parameter is also a HashMap but this one representing a customers cart.
This method computes and returns total profit for this day. Note that the profit of selling an item is the cost of a customer (prices in the first parameter) minus our cost to purchase the item our inventory (second parameter). In all computation, use the following prices.
This is what I did, not sure what I did wrong. Also is there a way I can do this without using entryset?
public static double computeProfit(HashMap<String, Double> sellingPrice, HashMap<String, Double> inventory, ArrayList<HashMap<String, Integer>> orders) {
double ans = 0;
for (HashMap<String, Integer> order : orders) {
for (Map.Entry<String, Integer> itemToQuantity : order.entrySet()) {
String item = itemToQuantity.getKey();
Integer quantityPurchased = itemToQuantity.getValue();
inventory.put(item, inventory.get(item) * quantityPurchased);
}
}
for (Entry<String, Double> itemInInventory : inventory.entrySet()) {
String itemName = itemInInventory.getKey();
Double reQuantity = itemInInventory.getValue();
ans = ans -(sellingPrice.get(itemName)+ reQuantity);
}
return ans;
}
public static ArrayList<HashMap<String,Integer>> allOrders(){
ArrayList<HashMap<String, Integer>> allOrders = new ArrayList<>();
HashMap<String, Integer> cart0 = new HashMap<>();
cart0.put("frozen dinner", 4);
cart0.put("yogurt", 4);
cart0.put("milk", 3);
allOrders.add(cart0);
HashMap<String, Integer> cart1 = new HashMap<>();
cart1.put("yogurt", 4);
cart1.put("strawberries", 3);
cart1.put("apples", 4);
allOrders.add(cart1);
return allOrders;
}
public static HashMap<String,Double>sellingPrice(){
HashMap<String,Double>priceList = new HashMap<String,Double>();
priceList.put("eggs", 1.79);
priceList.put("orange juice",2.5);
priceList.put("yogurt",1.99);
priceList.put("bread",2.49);
priceList.put("butter",2.39);
priceList.put("peppers",1.49);
priceList.put("chips",2.95);
priceList.put("chocolate chips",2.39);
priceList.put("popcorn",1.99);
priceList.put("tomato sauce",0.99);
priceList.put("frozen pizza",5.49);
priceList.put("milk",2.09);
priceList.put("bananas",0.49);
priceList.put("hot dog",1.29);
priceList.put("relish",0.99);
priceList.put("frozen dinner",2.5);
priceList.put("cereal",3.25);
priceList.put("tuna fish",0.99);
priceList.put("coffee",2.0);
priceList.put("pasta",0.99);
priceList.put("strawberries",3.5);
priceList.put("apples",1.29);
priceList.put("sugar",1.99);
priceList.put("ketchup",2.89);
return sellingPrice();
}
public static HashMap<String, Double> purchasePrice(){
HashMap<String,Double>cart = new HashMap <String,Double>();
cart.put("eggs", 1.2);
cart.put("orange juice", 1.0);
cart.put("yogurt", 1.0);
cart.put("bread", 1.5);
cart.put("butter", 1.95);
cart.put("peppers", 0.99);
cart.put("chips", 0.9);
cart.put("chocolate chips", 1.79);
cart.put("popcorn", 0.99);
cart.put("tomato sauce", 0.4);
cart.put("frozen pizza", 2.6);
cart.put("milk", 1.89);
cart.put("bananas", 0.39);
cart.put("hot dog", 0.79);
cart.put("relish", 0.49);
cart.put("frozen dinner", 1.5);
cart.put("cereal", 1.55);
cart.put("tuna fish", 0.49);
cart.put("coffee", 0.6);
cart.put("pasta", 0.5);
cart.put("strawberries", 1.99);
cart.put("apples", 0.99);
cart.put("sugar", 1.5);
cart.put("sugar", 0.98);
return purchasePrice();
}
public static void main(String [] args){
computeProfit(sellingPrice(),purchasePrice(),allOrders());
}
I also tried this , what am I doing wrong here?
public static double ComputeProfit(HashMap sellingPrice, HashMap inventory, ArrayList> orders) {
double ans = 0;
int i =0, j = 0;
for(i=0;i< orders.size();i++) {
HashMap<String,Integer> temp = orders.get(i);
for (j=0;j < temp.size();j++) {
String item = temp.getKey(j);
Integer quantityPurchased = temp.getValue(j);
inventory.put(item, inventory.get(item) * quantityPurchased);
}
}
int k=0 ;
for (k =0 ; k< inventory.size();k++) {
HashMap <String,Integer>itemInInventory = inventory.get(k);
String itemName = itemInInventory.getKey(k);
Double reQuantity = itemInInventory.getValue(k);
ans = ans -(sellingPrice.get(itemName)+ reQuantity);
}
return ans;
}
public static ArrayList<HashMap<String,Integer>> allOrders(){
ArrayList<HashMap<String, Integer>> allOrders = new ArrayList<>();
HashMap<String, Integer> cart0 = new HashMap<>();
cart0.put("frozen dinner", 4);
cart0.put("yogurt", 4);
cart0.put("milk", 3);
allOrders.add(cart0);
HashMap<String, Integer> cart1 = new HashMap<>();
cart1.put("yogurt", 4);
cart1.put("strawberries", 3);
cart1.put("apples", 4);
allOrders.add(cart1);
return allOrders;
}
public static HashMap<String,Double>sellingPrice(){
HashMap<String,Double>priceList = new HashMap<String,Double>();
priceList.put("eggs", 1.79);
priceList.put("orange juice",2.5);
priceList.put("yogurt",1.99);
priceList.put("bread",2.49);
priceList.put("butter",2.39);
priceList.put("peppers",1.49);
priceList.put("chips",2.95);
priceList.put("chocolate chips",2.39);
priceList.put("popcorn",1.99);
priceList.put("tomato sauce",0.99);
priceList.put("frozen pizza",5.49);
priceList.put("milk",2.09);
priceList.put("bananas",0.49);
priceList.put("hot dog",1.29);
priceList.put("relish",0.99);
priceList.put("frozen dinner",2.5);
priceList.put("cereal",3.25);
priceList.put("tuna fish",0.99);
priceList.put("coffee",2.0);
priceList.put("pasta",0.99);
priceList.put("strawberries",3.5);
priceList.put("apples",1.29);
priceList.put("sugar",1.99);
priceList.put("ketchup",2.89);
return sellingPrice();
}
public static HashMap<String, Double> purchasePrice(){
HashMap<String,Double>cart = new HashMap <String,Double>();
cart.put("eggs", 1.2);
cart.put("orange juice", 1.0);
cart.put("yogurt", 1.0);
cart.put("bread", 1.5);
cart.put("butter", 1.95);
cart.put("peppers", 0.99);
cart.put("chips", 0.9);
cart.put("chocolate chips", 1.79);
cart.put("popcorn", 0.99);
cart.put("tomato sauce", 0.4);
cart.put("frozen pizza", 2.6);
cart.put("milk", 1.89);
cart.put("bananas", 0.39);
cart.put("hot dog", 0.79);
cart.put("relish", 0.49);
cart.put("frozen dinner", 1.5);
cart.put("cereal", 1.55);
cart.put("tuna fish", 0.49);
cart.put("coffee", 0.6);
cart.put("pasta", 0.5);
cart.put("strawberries", 1.99);
cart.put("apples", 0.99);
cart.put("sugar", 1.5);
cart.put("sugar", 0.98);
return purchasePrice();
}
public static void main(String [] args){
computeProfit(sellingPrice(),purchasePrice(),allOrders());
}
}

Your answer looks mostly right, there are just a few issues with your type naming (Integer should be int, Double should be double) and you use Map.Entry in one portion of the code and Entry later on. The code below fixes the issues in your computeProfit function and should solve your problem. Let me know if you have any questions!
public static double computeProfit(HashMap<String, double> sellingPrice, HashMap<String, double> inventory, ArrayList<HashMap<String, int>> orders) {
double profit = 0;
for (HashMap<String, int> order: Orders) {
for (Map.Entry<String, int> orderEntry: order.entrySet()) {
double purchasePrice = inventory.get(orderEntry.getKey());
double salePrice = sellingPrice.get(orderEntry.getKey());
int purchaseCount = orderEntry.getValue();
profit += ( salePrice - purchasePrice ) * purchaseCount;
}
}
return profit;
}

Related

Integer Optimization using OjAlgo objective function

I'm trying to use ojAlgo library in Java for Integer Optimization but I'm unable to provide it the objective function I intend to.
I'd like to minimize the function: (A - B.X)'(A - B.X), where A is a (n x 1) matrix, B is a (n x n) diagonal matrix and X is a (n x 1) matrix with the optimization variables. I want the result in X to consist of only integers .
I was able to set a different objective function which was to maximize B.X. How do I change it to (A - B.X)'(A - B.X)? Here is the code so far.
import org.apache.log4j.Logger;
import org.ojalgo.optimisation.Expression;
import org.ojalgo.optimisation.ExpressionsBasedModel;
import org.ojalgo.optimisation.Optimisation;
import org.ojalgo.optimisation.Variable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.InputMismatchException;
import java.util.List;
public class AllocationOptimization {
protected Logger log = Logger.getLogger(AllocationOptimization.class);
// This is the objective function, since weight() is assigned to it. How to change this objective function to what I want?
private List<Variable> makeVariables(HashMap<String, BigDecimal> matrixB) {
List<Variable> result = new ArrayList<>();
for (String assetName : matrixB.keySet()) {
result.add(new Variable(assetName).weight(matrixB.get(assetName)));
}
return result;
}
private ExpressionsBasedModel createExpressionModel(List<Variable> variables) {
final ExpressionsBasedModel model = new ExpressionsBasedModel();
for (Variable v : variables) {
model.addVariable(v);
}
return model;
}
private void addExpressionConstraints(ExpressionsBasedModel model, List<Variable> variables,
HashMap<String, BigDecimal> matrixB,
HashMap<String, BigDecimal> wantedAbsoluteSharesMap,
BigDecimal idealTotalPrice) {
Expression expression = model.addExpression("C1").upper(idealTotalPrice);
int i = 0;
for (String assetName : matrixB.keySet()) {
expression.set(variables.get(i), matrixB.get(assetName));
i += 1;
}
for (Variable v : variables) {
long absShares = wantedAbsoluteSharesMap.get(v.getName()).longValue();
v.lower((long) Math.max(0, 0.8 * absShares)).upper((long) Math.max(Math.max(0, 1.2 * absShares), 5));
}
}
private void setIntegerSolving(ExpressionsBasedModel model) {
for (Variable v : model.getVariables()) {
v.setInteger(true);
}
}
private HashMap<String, Long> getIntegerOptimizationResult(ExpressionsBasedModel model, HashMap<String, BigDecimal> matrixB) {
Optimisation.Result result = model.maximise();
return prepareResult(result, matrixB);
}
private HashMap<String, Long> prepareResult(Optimisation.Result result, HashMap<String, BigDecimal> matrixB) {
int i = 0;
HashMap<String, Long> optimizedResult = new HashMap<>();
BigDecimal sumAssetPrices = new BigDecimal("0.0");
for (String assetName : matrixB.keySet()) {
long sharesCount = result.get(i).longValue();
log.debug(assetName + ": " + sharesCount);
optimizedResult.put(assetName, sharesCount);
sumAssetPrices = sumAssetPrices.add(matrixB.get(assetName).multiply(BigDecimal.valueOf(sharesCount)));
i += 1;
}
log.debug("Total assets value after converting shares to integer numbers: " + sumAssetPrices);
return optimizedResult;
}
public HashMap<String, Long> optimizeSharesCount(HashMap<String, BigDecimal> constraint1,
HashMap<String, BigDecimal> matrixB,
BigDecimal constraint2) throws InputMismatchException {
List<Variable> variableList = makeVariables(matrixB);
ExpressionsBasedModel model = createExpressionModel(variableList);
addExpressionConstraints(model, variableList, matrixB, constraint1, constraint2);
setIntegerSolving(model);
HashMap<String, Long> resultMap = getIntegerOptimizationResult(model, matrixB);
return resultMap;
}
private HashMap<String, BigDecimal> createWantedAbsoluteSharesTest1() {
HashMap<String, BigDecimal> absShares = new HashMap<>();
absShares.put("NFLX", new BigDecimal("2"));
absShares.put("MSFT", new BigDecimal("4"));
absShares.put("GOOG", new BigDecimal("0"));
absShares.put("AAPL", new BigDecimal("25"));
return absShares;
}
private HashMap<String, BigDecimal> createAssetPricesMapTest1() {
HashMap<String, BigDecimal> assetPrices = new HashMap<>();
assetPrices.put("NFLX", new BigDecimal("601.06"));
assetPrices.put("MSFT", new BigDecimal("296.75"));
assetPrices.put("GOOG", new BigDecimal("2843.78"));
assetPrices.put("AAPL", new BigDecimal("149.07"));
return assetPrices;
}
public static void main(String[] args) {
AllocationOptimization allocationOptimization = new AllocationOptimization();
// For testing
HashMap<String, BigDecimal> constr1 = allocationOptimization.createWantedAbsoluteSharesTest1();
HashMap<String, BigDecimal> matrixB = allocationOptimization.createAssetPricesMapTest1();
BigDecimal constr2 = new BigDecimal("5348.25");
HashMap<String, Long> optimizedResult = null;
try {
optimizedResult = allocationOptimization.optimizeSharesCount(constr1, matrixB, constr2);
} catch (Exception e) {
e.printStackTrace();
}
assert optimizedResult != null;
allocationOptimization.log.info("optimizedResult size: " + optimizedResult.size());
}
}
You assigned weights to the Variable:s. That makes them part of the objective function. You can also assign weights to Expression:s. Anything/everything that has a weight is summed up to form the objective function.
Expression objective = model.addExpression("Whole Objective").weight(BigDecimal.ONE);
for (Variable variableR : variables) {
objective.set(variableR, linearParameter);
for (Variable variableC : variables) {
objective.set(variableR, variableC, quadraticParameter);
}
}
Is equivalent to:
Expression objective = model.addExpression("Objective Part").weight(BigDecimal.ONE);
for (Variable variableR : variables) {
variableR.weight(linearParameter);
for (Variable variableC : variables) {
objective.set(variableR, variableC, quadraticParameter);
}
}
I modified the objective function and added necessary constraints, following #apete's comments. Posting my solution here for others.
private List<Variable> makeVariables(HashMap<String, BigDecimal> matrixB) {
List<Variable> result = new ArrayList<>();
for (String assetName : matrixB.keySet()) {
result.add(new Variable(assetName));
}
return result;
}
private ExpressionsBasedModel createObjective(ExpressionsBasedModel model, List<Variable> variables,
HashMap<String, BigDecimal> matrixA,
HashMap<String, BigDecimal> matrixB) {
// Anything and everything with that has a weight is summed up to form the objective function
Expression objective = model.addExpression("Objective function").weight(BigDecimal.ONE);
for (Variable variable : variables) {
String assetName = variable.getName();
objective.set(variable, new BigDecimal("-2").multiply(matrixA.get(assetName)).multiply(matrixB.get(assetName)));
objective.set(variable, variable, matrixB.get(assetName).pow(2));
}
return model;
}
private void addExpressionConstraints(ExpressionsBasedModel model, List<Variable> variables,
HashMap<String, BigDecimal> matrixB,
HashMap<String, BigDecimal> wantedAbsoluteSharesMap,
HashMap<String, BigDecimal> matrixA,
BigDecimal idealTotalPrice, BigDecimal accountBalance) {
Expression expression1 = model.addExpression("C1").upper(idealTotalPrice);
for (Variable variable : variables) {
expression1.set(variable, matrixB.get(variable.getName()));
}
for (Variable v : variables) {
// No negative values constraint
v.lower(0);
}
// This constraint is used to compensate for the constants arising in the quadratic objective function
BigDecimal sumSquaresUserAllocation = new BigDecimal("0.0");
for (String assetName : this.assetsList) {
sumSquaresUserAllocation = sumSquaresUserAllocation.add(matrixA.get(assetName).pow(2));
}
Expression expression2 = model.addExpression("C2").upper(new BigDecimal("1.01").multiply(sumSquaresUserAllocation.multiply(new BigDecimal("-1"))));
expression2.lower(new BigDecimal("0.99").multiply(sumSquaresUserAllocation.multiply(new BigDecimal("-1"))));
for (Variable variable : variables) {
String assetName = variable.getName();
expression2.set(variable, new BigDecimal("-2").multiply(matrixA.get(assetName)).multiply(matrixB.get(assetName)));
expression2.set(variable, variable, matrixB.get(assetName).pow(2));
}
}
Finally, instead of using the model.maximise() function, I used model.minimise() to minimize the objective function.

Addition table guava and arraylist

I have this program and I want to gather values in ArrayList operatCible and values in Table employeeYearsOfService and I want to stock the result in HashMap<String,integer> witch contains RowKey and result.
I don't know how to do it. This what I want
Code
public class collaborativAlgorithme {
Table<String, String, Double> employeeYearsOfService =
HashBasedTable.create();
public static void main(String[] args) {
List<Double> operatCible = new ArrayList<Double>();
operatCible.add(4.1);
operatCible.add(5.0);
System.out.println(operatCible);
Table<String, String, Double> employeeYearsOfService =
HashBasedTable.create();
employeeYearsOfService.put("AT&T", "Stacy Lerner", 1.4);
employeeYearsOfService.put("Microsoft", "Stacy Lerner", 3.5);
employeeYearsOfService.put("Microsoft", "Bill Smith", 13.2);
employeeYearsOfService.put("Google", "Stacy Lerner", 11.5);
employeeYearsOfService.put("AT&T", "Bill Smith", 2.0);
employeeYearsOfService.put("Google", "Bill Smith", 9.75);
System.out.println(employeeYearsOfService.rowKeySet());
HashMap<String,Integer> result=new HashMap<String,Integer>;
System.out.println(employeeYearsOfService);
Map<String, Double> attEmployees = employeeYearsOfService.row("AT&T");
for (Map.Entry<String, Double> employee : attEmployees.entrySet()) {
// what i do??
// sum values arraylist and values table
System.out.println("Employee Name: " + employee.getKey() + ", Years
of Service: " + employee.getValue());
}
}
}
I solved my problem
And I add something else as (sqrt)....
this is the code
int k = 0;
Double sum = 0.0;//cosine similarity
Double sum2 = 0.0;
System.out.println(employeeYearsOfService);
for (String key : employeeYearsOfService.rowKeySet()) {
HashMap<String, Double> hm = new HashMap<String, Double>();
for (Entry<String, Double> employee :
employeeYearsOfService.row(key).entrySet()) {
sum += employee.getValue() * operatCible.get(k);
sum2+=employee.getValue();
k++;
}
k = 0;
System.out.println(sum);
System.out.println("----");
System.out.println(sqrt(sum2));
hm.put(key, sum);
sum = 0.0;
System.out.println(hm);
}
}
you ca dou that
HashMap<String, Double> hm = new HashMap<String, Double>();
System.out.println(employeeYearsOfService);
for (String key : employeeYearsOfService.rowKeySet()) {
for (Entry<String, Double> employee :
employeeYearsOfService.row(key).entrySet()) {
sum += employee.getValue() + operatCible.get(k);
k++;
}
k = 0;
System.out.println(sum);
hm.put(key, sum);
}

Return the key of the smallest difference after substracting two values from hashmap?

How can I return the key of the smallest difference after substracting two values from a hashmap?
Example
first loop -> 10 - 8 = 2;
second loop -> 10 - 9 = 1;
third loop -> 10 - 7 = 3;
therefore second loop -> 10 - 9 = 1 is the smallest, so the key is "Three".
Code
import java.util.HashMap;
public class Difference {
HashMap<String,Double> hashMap = new HashMap<>();
double firstValue = 0;
double secondValue = 0;
double difference = 0;
public Difference() {
hashMap.put("One", 10.0);
hashMap.put("Two", 8.0);
hashMap.put("Three", 9.0);
hashMap.put("Four", 7.0);
firstValue = hashMap.get("One");
for (String key : hashMap.keySet()) {
if(!key.equals("One")) {
secondValue = hashMap.get(key);
difference = Math.abs(secondValue - firstValue);
}
}
}
public static void main(String[] args) {
new Difference();
}
}
Please Help. Thanks.
You can achieve that using something like the following:
public class MainTest {
public static void main(String[] args) {
HashMap<String,Double> hashMap = new HashMap<>();
hashMap.put("One", 10.0);
hashMap.put("Two", 8.0);
hashMap.put("Three", 9.0);
hashMap.put("Four", 7.0);
hashMap.put("Five", 10.1);
System.out.println(getSmallestDiffKeyJava8(hashMap, "One"));
}
/* This works only with java 8 */
private static String getSmallestDiffKeyJava8(Map<String, Double> map, String constantKey) {
double constant = map.get(constantKey);
return map.entrySet().stream()
.filter(entry -> !constantKey.equals(entry.getKey())) // Remove the constant from the values we process
.map(entry -> new SimpleEntry<>(entry.getKey(), Math.abs(entry.getValue() - constant))) // Map to a new entry with the key and the diff
.min((o1, o2) -> (int)(o1.getValue() - o2.getValue())) // Find the min
.map(Entry::getKey)
.get();
}
/* This works with older versions as well */
private static String getSmallestDiffKey(Map<String, Double> map, String constantKey) {
double constant = map.get(constantKey);
String key = null;
Double diff = null;
for (Entry<String, Double> entry : map.entrySet()) {
if (!constantKey.equals(entry.getKey())) {
double d = Math.abs(entry.getValue() - constant);
if (diff == null || diff > d) {
diff = d;
key = entry.getKey();
}
}
}
return key;
}
}
Try to use code something like that:
String smallestKey;
if(difference !=0 && difference < Math.abs(secondValue - firstValue);){
difference = Math.abs(secondValue - firstValue);
smallestKey = key;
}
I think your problem is simpler than you think. I know it's not the best one but here's a solution :
import java.util.HashMap;
public class Difference {
HashMap<String,Double> hashMap = new HashMap<>();
double firstValue = 0;
double secondValue = 0;
double difference = 0;
HashMap<Double, String> theMap = new HashMap<Double, String>();
public Difference() {
hashMap.put("One", 10.0);
hashMap.put("Two", 8.0);
hashMap.put("Three", 9.0);
hashMap.put("Four", 7.0);
firstValue = hashMap.get("One");
for (String key : hashMap.keySet()) {
if(!key.equals("One")) {
secondValue = hashMap.get(key);
difference = Math.abs(secondValue - firstValue);
theMap.put(difference, key);
}
}
Set<Double> dbl = theMap.keySet();
Double smallestDifference = findSmallest(dbl);
String smallestValue = hashMap.get(smallestDifference);
}
public Double findSmallest(Set<Double> setDbl){
Double smallest = 99999999.0;
for(Double d : setDbl){
if(d < smallest)
smallest = d;
}
return smallest;
}
public static void main(String[] args) {
new Difference();
}
}

Greedy Algorithm java in map

I'm working on emulator of ATM in java. The overall pattern in project is Command.
So I have 4 commands - getInfo, deposit,withdraw and exit.
I'm facing problems with an implementation of greedy algorithm in withdrawal method. It should return Map were first Integer is "denomination" and second Integer is "amount" left in ATM after we withdrew.
public Map<Integer, Integer> withdrawAmount(int expectedAmount)
So it takes expected amount as an argument and has to subtract it from ATM with the least possible amount of bills.
public class CurrencyManipulator
{
// denominations is a map where each denomination and it's quantity stored
private String currencyCode;
private Map<Integer, Integer> denominations = new HashMap<>();
public String getCurrencyCode()
{
return currencyCode;
}
public CurrencyManipulator(String currencyCode)
{
this.currencyCode = currencyCode;
}
public void addAmount(int denomination, int count)
{
if (denominations.containsKey(denomination))
{
denominations.put(denomination, denominations.get(count) + count);
} else
{
denominations.put(denomination, count);
}
}
public int getTotalAmount()
{
int sum = 0;
for (Map.Entry<Integer, Integer> pair : denominations.entrySet())
{
sum = pair.getKey() * pair.getValue();
}
return sum;
}
public boolean hasMoney()
{
return denominations.size() != 0;
}
public boolean isAmountAvailable(int expectedAmount)
{
return expectedAmount <= getTotalAmount();
}
public Map<Integer, Integer> withdrawAmount(int expectedAmount) throws NotEnoughMoneyException
{
}
}
So I need this method to return a map or throw exception if amount asked "expectedAmount" is higher then money available in ATM.
If we take $600 it could be - three bills: $500 + $50 + $50 OR $200 + $200 + $200, the preferred option is $500 + $50 + $50
Example, you have to give $600
The ATM has the following bill-count:
500 - 2
200 - 3
100 - 1
50 - 12
The result should be:
500 - 1
100 - 1
This what I came up with:
public Map<Integer, Integer> withdrawAmount(int expectedAmount) throws NotEnoughMoneyException
{
denominations.put(50,1);
denominations.put(500,1);
denominations.put(200,3);
HashMap<Integer, Integer> map = new HashMap<>();
TreeMap<Integer, Integer> sortedMap = new TreeMap<>(Collections.reverseOrder());
sortedMap.putAll(denominations);
ArrayList<Integer> bills = new ArrayList<>();
bills.addAll(sortedMap.keySet());
int num;
for (int i = 0; i < bills.size(); i++)
{
if (bills.get(i) <= expectedAmount)
{
num = expectedAmount / bills.get(i);
map.put(bills.get(i), num);
expectedAmount -= num * bills.get(i);
}
}
System.out.println(map);
return map;
}
It returns the map of needed bills and their quantity.
Now my question is..how do i compare it with the "denominations" map i have and subtract new map from it?
seems to be working code if someone ever needs it
public Map<Integer, Integer> withdrawAmount(int expectedAmount) throws NotEnoughMoneyException
{
denominations.put(50,2);
denominations.put(500,1);
denominations.put(100,1);
HashMap<Integer, Integer> map = new HashMap<>();
TreeMap<Integer, Integer> sortedDenominations = new TreeMap<>(Collections.reverseOrder());
sortedDenominations.putAll(denominations);
ArrayList<Integer> bills = new ArrayList<>();
bills.addAll(sortedDenominations.keySet());
int num;
for (int i = 0; i < bills.size(); i++)
{
if (bills.get(i) <= expectedAmount)
{
num = expectedAmount / bills.get(i);
map.put(bills.get(i), num);
expectedAmount -= num * bills.get(i);
}
}
System.out.println(map);
for (Map.Entry<Integer,Integer> denominPresent:sortedDenominations.entrySet()){
int value;
for (Map.Entry<Integer,Integer> deominNeeded:map.entrySet()){
if(denominPresent.getKey().equals(deominNeeded.getKey())){
value = denominPresent.getValue()-deominNeeded.getValue();
if (value>=0) sortedDenominations.put(denominPresent.getKey(),value);
else throw new NotEnoughMoneyException();
}
}
}
System.out.println(sortedDenominations);
return sortedDenominations;
}
Another solution. Will work if you initialize the denominations variable using TreeMap
...
private Map<Integer, Integer> denominations = new TreeMap<>(Comparator.reverseOrder());
...
public Map<Integer, Integer> withdrawAmount(int expectedAmount) throws NotEnoughMoneyException {
final Map<Integer, Integer> map = new TreeMap<>(Comparator.reverseOrder());
// calculate denomination map to cash
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
int denomination = entry.getKey();
if (denomination <= expectedAmount) {
int num = Math.min(expectedAmount / denomination, entry.getValue());
map.put(denomination, num);
expectedAmount -= num * denomination;
}
if (expectedAmount == 0) {
break;
}
}
if (expectedAmount != 0) {
throw new NotEnoughMoneyException();
}
map.forEach((key, value) -> {
denominations.compute(key, (denomination, count) -> {
return (count == value) ? null : count - value;
});
});
return map;
}

Viterbi algorithm, unhardcode for general case Java

my task is to find the most probable sequences of words in a sentence using viterbi algorithm.
The given sequence of states is here:
I have to introduce initial probabilities and transition probabilities and then print the most likely sequence of parts of the speech the words of the sentence are.
The out should be smth like N P V ART, probability 0.0000123
I've hardcoded it in Java, but is there a general case or already prepared solutions in different MATH programs? thanks, here is what I have so far:
import java.util.Hashtable;
public class Main
{
//We hard-code start states and consequent observations.
static final String NOUN = "Noun";
static final String ARTICLE = "Article";
static final String VERB = "Verb";
static final String ADJECTIVE = "Adjective";
static final String ADVERB = "Adverb";
public static void main(String[] args)
{
//We put them in array
String[] states = new String[] {NOUN, ARTICLE};
String[] observations = new String[] {VERB, ADJECTIVE, ADVERB};
//Define a hashtable where we’ll keep initial states and their probabilities
Hashtable<String, Float> start_probability = new Hashtable<String, Float>();
start_probability.put(NOUN, 0.6f);
start_probability.put(ARTICLE, 0.4f);
// A hashtable with transition_probabilities which contains initial probablilities
Hashtable<String, Hashtable<String, Float>> transition_probability =
new Hashtable<String, Hashtable<String, Float>>();
Hashtable<String, Float> t1 = new Hashtable<String, Float>();
t1.put(NOUN, 0.7f);
t1.put(ARTICLE, 0.3f);
Hashtable<String, Float> t2 = new Hashtable<String, Float>();
t2.put(NOUN, 0.4f);
t2.put(ARTICLE, 0.6f);
transition_probability.put(NOUN, t1);
transition_probability.put(ARTICLE, t2);
// Here we put hashtables with consequent observed emission_probability
Hashtable<String, Hashtable<String, Float>> emission_probability =
new Hashtable<String, Hashtable<String, Float>>();
Hashtable<String, Float> e1 = new Hashtable<String, Float>();
e1.put(VERB, 0.1f);
e1.put(ADJECTIVE, 0.4f);
e1.put(ADVERB, 0.5f);
Hashtable<String, Float> e2 = new Hashtable<String, Float>();
e2.put(VERB, 0.6f);
e2.put(ADJECTIVE, 0.3f);
e2.put(ADVERB, 0.1f);
emission_probability.put(NOUN, e1);
emission_probability.put(ARTICLE, e2);
//We return the most probabilistic sequence with function forward fiterb described below
Object[] ret = forward_viterbi(observations,
states,
start_probability,
transition_probability,
emission_probability);
System.out.println(((Float) ret[0]).floatValue());
System.out.println((String) ret[1]);
System.out.println(((Float) ret[2]).floatValue());
}
//Function to go
//As argument we get nested hashtables
public static Object[] forward_viterbi(String[] obs, String[] states,
Hashtable<String, Float> start_p,
Hashtable<String, Hashtable<String, Float>> trans_p,
Hashtable<String, Hashtable<String, Float>> emit_p)
{
Hashtable<String, Object[]> T = new Hashtable<String, Object[]>();
for (String state : states)
T.put(state, new Object[] {start_p.get(state), state, start_p.get(state)});
for (String output : obs)
{
Hashtable<String, Object[]> U = new Hashtable<String, Object[]>();
for (String next_state : states)
{
float total = 0;
String argmax = "";
float valmax = 0;
float prob = 1;
String v_path = "";
float v_prob = 1;
for (String source_state : states)
{
Object[] objs = T.get(source_state);
prob = ((Float) objs[0]).floatValue();
v_path = (String) objs[1];
v_prob = ((Float) objs[2]).floatValue();
float p = emit_p.get(source_state).get(output) *
trans_p.get(source_state).get(next_state);
prob *= p;
v_prob *= p;
total += prob;
if (v_prob > valmax)
{
argmax = v_path + "," + next_state;
valmax = v_prob;
}
}
U.put(next_state, new Object[] {total, argmax, valmax});
}
T = U;
}
float total = 0;
String argmax = "";
float valmax = 0;
float prob;
String v_path;
float v_prob;
for (String state : states)
{
Object[] objs = T.get(state);
prob = ((Float) objs[0]).floatValue();
v_path = (String) objs[1];
v_prob = ((Float) objs[2]).floatValue();
total += prob;
if (v_prob > valmax)
{
argmax = v_path;
valmax = v_prob;
}
}
return new Object[]{
total, argmax, valmax
};
}
}

Categories

Resources