use closed list to avoid loops

master
agp8x 2021-07-28 13:08:43 +02:00
parent 5d57f9dd1d
commit bddbdb715c
3 changed files with 43 additions and 11 deletions

View File

@ -99,7 +99,10 @@ public class Test {
Recipe recipe = b.getRecipe();
System.out.println(recipe);
//plot(Database.GasFilter, "rubber",1);
plot(Database.RadioControlUnit, "alu", 1);
plot(Database.AluminumCasing, "aluCase", 1);
SumResult ac = SumResult.sum(new Production(Database.AluminumCasing,1));
plot2(ac.getProduction(), "aluCase_sum");
//System.exit(128);
Item i = Database.AluminumIngot;
//plot2(SumResult.sum(i, 1),"rubber_");
//plot(i, "rcu_hierarchy",1);

View File

@ -105,4 +105,5 @@ public abstract class Item {
public Recipe getPreference() {
return preference;
}
}

View File

@ -107,6 +107,16 @@ public class Recipe {
return inputs;
}
public Map<Item,Integer> getByProducts(Item reference){
if (!outputs.containsKey(reference)){
return null;
}
return outputs.entrySet().stream().filter(itemIntegerEntry -> isByProduct(reference, itemIntegerEntry.getKey())).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}
public boolean isByProduct(Item reference, Item test){
return !reference.equals(test) && outputs.containsKey(reference) && outputs.containsKey(test);
}
public Graph<Item, DefaultWeightedEdge> buildGraph(Item target) {
System.out.println("buildGraph(" + target.getName() + ") @ "+ name);
Graph<Item, DefaultWeightedEdge> graph = new DefaultDirectedWeightedGraph<>(DefaultWeightedEdge.class);
@ -139,6 +149,16 @@ public class Recipe {
return n / r.getProductionRate(target);
}
private double getRequiredProcessRuns(Item product, Double productWantedPerMinute) {
int productPerProcess = product.getRecipe().outputs.get(product);
return productWantedPerMinute / productPerProcess;
}
private double getByproductRate(Item main, Item product, double production){
double runs = getRequiredProcessRuns(main, production);
return product.getRecipe().outputs.get(product) * runs;
}
public SumResult sum(Item target, int prodPerMinute) {
Graph<Item, DefaultWeightedEdge> buildGraph = buildGraph(target);
Graph<Item, ProductionEdge> production = new DefaultDirectedWeightedGraph<>(ProductionEdge.class);
@ -148,13 +168,19 @@ public class Recipe {
map.put(target, (double) prodPerMinute);
production.addVertex(target);
production.addEdge(target, target, new ProductionEdge(target, target, prodPerMinute, processesNeeded(target, prodPerMinute)));
Set<Item> visited = new HashSet<>();
while (!queue.isEmpty()) {
Item item = queue.remove();
if (visited.contains(item)){
System.out.println("hint: already processed " + item.getName()+ "! Skip!");
//continue;
} else {
// next items
buildGraph.incomingEdgesOf(item)
.stream()
.map(buildGraph::getEdgeSource)
.forEach(queue::add);
}
// *this* item
double sum = 0;
Set<Item> byProducts = new HashSet<>();
@ -162,9 +188,9 @@ public class Recipe {
Item product = buildGraph.getEdgeTarget(edge);
Double productWantedPerMinute = map.get(product);
System.out.println(item.getName());
if (item.getRecipe().outputs.containsKey(product)) {
if (item.getRecipe().outputs.containsKey(product)) { // TODO: method isByProduct
// product is by-product, no forward dependency
System.out.println("BY-PRODUCT " + item.getName() + " -> " + product.getName());
System.out.println("BY-PRODUCT " + item.getName() + " -> " + product.getName() + "... "+ queue);
byProducts.add(product);
continue;
}
@ -173,8 +199,7 @@ public class Recipe {
break;
}
double amountNeeded = buildGraph.getEdgeWeight(edge);
int productPerProcess = product.getRecipe().outputs.get(product);
double requiredProcesRuns = productWantedPerMinute / productPerProcess;
double requiredProcesRuns = getRequiredProcessRuns(product, productWantedPerMinute);
double requiredInput = amountNeeded * requiredProcesRuns;
sum += requiredInput;
@ -185,12 +210,15 @@ public class Recipe {
map.put(item, sum);
}
if (!byProducts.isEmpty()) {
double finalSum = sum;
byProducts.forEach(item1 -> {
production.addVertex(item1);
// TODO: calculate produced amount
production.addEdge(item, item1, new ProductionEdge(item, item1, 0, 0));
double byproductRate = getByproductRate(item, item1, finalSum);
production.addEdge(item, item1, new ProductionEdge(item, item1, byproductRate, processesNeeded(item, finalSum)));
});
}
visited.add(item);
}
map.forEach((item, aDouble) -> {
System.out.println(item.getName() + ": " + aDouble);