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(); Recipe recipe = b.getRecipe();
System.out.println(recipe); System.out.println(recipe);
//plot(Database.GasFilter, "rubber",1); //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; Item i = Database.AluminumIngot;
//plot2(SumResult.sum(i, 1),"rubber_"); //plot2(SumResult.sum(i, 1),"rubber_");
//plot(i, "rcu_hierarchy",1); //plot(i, "rcu_hierarchy",1);

View File

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

View File

@ -107,6 +107,16 @@ public class Recipe {
return inputs; 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) { public Graph<Item, DefaultWeightedEdge> buildGraph(Item target) {
System.out.println("buildGraph(" + target.getName() + ") @ "+ name); System.out.println("buildGraph(" + target.getName() + ") @ "+ name);
Graph<Item, DefaultWeightedEdge> graph = new DefaultDirectedWeightedGraph<>(DefaultWeightedEdge.class); Graph<Item, DefaultWeightedEdge> graph = new DefaultDirectedWeightedGraph<>(DefaultWeightedEdge.class);
@ -139,6 +149,16 @@ public class Recipe {
return n / r.getProductionRate(target); 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) { public SumResult sum(Item target, int prodPerMinute) {
Graph<Item, DefaultWeightedEdge> buildGraph = buildGraph(target); Graph<Item, DefaultWeightedEdge> buildGraph = buildGraph(target);
Graph<Item, ProductionEdge> production = new DefaultDirectedWeightedGraph<>(ProductionEdge.class); Graph<Item, ProductionEdge> production = new DefaultDirectedWeightedGraph<>(ProductionEdge.class);
@ -148,13 +168,19 @@ public class Recipe {
map.put(target, (double) prodPerMinute); map.put(target, (double) prodPerMinute);
production.addVertex(target); production.addVertex(target);
production.addEdge(target, target, new ProductionEdge(target, target, prodPerMinute, processesNeeded(target, prodPerMinute))); production.addEdge(target, target, new ProductionEdge(target, target, prodPerMinute, processesNeeded(target, prodPerMinute)));
Set<Item> visited = new HashSet<>();
while (!queue.isEmpty()) { while (!queue.isEmpty()) {
Item item = queue.remove(); Item item = queue.remove();
// next items if (visited.contains(item)){
buildGraph.incomingEdgesOf(item) System.out.println("hint: already processed " + item.getName()+ "! Skip!");
.stream() //continue;
.map(buildGraph::getEdgeSource) } else {
.forEach(queue::add); // next items
buildGraph.incomingEdgesOf(item)
.stream()
.map(buildGraph::getEdgeSource)
.forEach(queue::add);
}
// *this* item // *this* item
double sum = 0; double sum = 0;
Set<Item> byProducts = new HashSet<>(); Set<Item> byProducts = new HashSet<>();
@ -162,9 +188,9 @@ public class Recipe {
Item product = buildGraph.getEdgeTarget(edge); Item product = buildGraph.getEdgeTarget(edge);
Double productWantedPerMinute = map.get(product); Double productWantedPerMinute = map.get(product);
System.out.println(item.getName()); 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 // 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); byProducts.add(product);
continue; continue;
} }
@ -173,8 +199,7 @@ public class Recipe {
break; break;
} }
double amountNeeded = buildGraph.getEdgeWeight(edge); double amountNeeded = buildGraph.getEdgeWeight(edge);
int productPerProcess = product.getRecipe().outputs.get(product); double requiredProcesRuns = getRequiredProcessRuns(product, productWantedPerMinute);
double requiredProcesRuns = productWantedPerMinute / productPerProcess;
double requiredInput = amountNeeded * requiredProcesRuns; double requiredInput = amountNeeded * requiredProcesRuns;
sum += requiredInput; sum += requiredInput;
@ -185,12 +210,15 @@ public class Recipe {
map.put(item, sum); map.put(item, sum);
} }
if (!byProducts.isEmpty()) { if (!byProducts.isEmpty()) {
double finalSum = sum;
byProducts.forEach(item1 -> { byProducts.forEach(item1 -> {
production.addVertex(item1); production.addVertex(item1);
// TODO: calculate produced amount // 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) -> { map.forEach((item, aDouble) -> {
System.out.println(item.getName() + ": " + aDouble); System.out.println(item.getName() + ": " + aDouble);