Optimation
This commit is contained in:
parent
e4d54619f6
commit
7cd4664974
4 changed files with 123 additions and 116 deletions
Binary file not shown.
|
@ -34,7 +34,7 @@ public class LinearSystem {
|
|||
while (tries-- > 0) {
|
||||
int[] lambdaValues = new int[indipendentVariables];
|
||||
for (int i = 0; i < indipendentVariables; i++) {
|
||||
lambdaValues[i] = (rand.nextInt(m) + 1); // valori tra 1 e 9
|
||||
lambdaValues[i] = (rand.nextInt(m) + 1); // valori tra 1 e m
|
||||
}
|
||||
|
||||
solutions = constructSolution(extendedMatrix, lambdaValues, rank);
|
||||
|
@ -111,9 +111,9 @@ public class LinearSystem {
|
|||
int b = mat[row][col];
|
||||
if (a == 0) continue;
|
||||
|
||||
int lcm = lcm(Math.abs(a), Math.abs(b));
|
||||
int f1 = lcm / Math.abs(a);
|
||||
int f2 = lcm / Math.abs(b);
|
||||
int mcm = mcm(Math.abs(a), Math.abs(b));
|
||||
int f1 = mcm / Math.abs(a);
|
||||
int f2 = mcm / Math.abs(b);
|
||||
if (a * b < 0) f2 = -f2;
|
||||
|
||||
for (int j = col; j <= m; j++) {
|
||||
|
@ -126,11 +126,11 @@ public class LinearSystem {
|
|||
return row;
|
||||
}
|
||||
|
||||
private int gcd(int a, int b) {
|
||||
return b == 0 ? a : gcd(b, a % b);
|
||||
private int mcd(int a, int b) {
|
||||
return b == 0 ? a : mcd(b, a % b);
|
||||
}
|
||||
|
||||
private int lcm(int a, int b) {
|
||||
return a / gcd(a, b) * b;
|
||||
private int mcm(int a, int b) {
|
||||
return a / mcd(a, b) * b;
|
||||
}
|
||||
}
|
||||
|
|
24
src/Pair.java
Normal file
24
src/Pair.java
Normal file
|
@ -0,0 +1,24 @@
|
|||
package it.arnaldo.unibs.tamagolem;
|
||||
|
||||
// Utility pair class
|
||||
public class Pair {
|
||||
private final Element first;
|
||||
private final Element second;
|
||||
Pair(Element first, Element second) {
|
||||
this.first = first;
|
||||
this.second = second;
|
||||
}
|
||||
|
||||
public Element getFirst() {
|
||||
return first;
|
||||
}
|
||||
|
||||
public Element getSecond() {
|
||||
return second;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
return "(" + first.toString() + ", " + second.toString() + ")";
|
||||
}
|
||||
}
|
|
@ -3,141 +3,124 @@ package it.arnaldo.unibs.tamagolem;
|
|||
import java.util.*;
|
||||
|
||||
public class WorldBuilder {
|
||||
|
||||
public static ElementGraph buildWorld() {
|
||||
Element[] allElements = Element.values();
|
||||
Random rand = new Random();
|
||||
// da cambiare il numero a 8
|
||||
//int numElements = 3 + rand.nextInt(8);
|
||||
int numElements = (int)(Math.random() * 10);
|
||||
|
||||
// numero di elementi estratti a caso
|
||||
int numElements = 5;
|
||||
List<Element> selectedElements = new ArrayList<>(Arrays.asList(allElements));
|
||||
|
||||
// elementi scelti
|
||||
Collections.shuffle(selectedElements);
|
||||
selectedElements = selectedElements.subList(0, numElements);
|
||||
|
||||
ElementGraph world = new ElementGraph();
|
||||
|
||||
// mappa che contiene una mappa in modo che dato un elemento ti da una mappa con chiave un secondo elemento il cui valore è 1 se l'elemento infligge o -1 se l'elemento subisce
|
||||
HashMap<Element, HashMap<Element, Integer>> linkDirections = new HashMap<>();
|
||||
for (Element element : selectedElements) {
|
||||
HashMap<Element, Integer> links = new HashMap<>();
|
||||
Element followingElement = selectedElements.get((selectedElements.indexOf(element) + 1) % selectedElements.size());
|
||||
for (Element el : selectedElements) {
|
||||
if (el == followingElement) {
|
||||
links.put(el, 1);
|
||||
} else if (el != element) {
|
||||
links.put(el, 0);
|
||||
}
|
||||
}
|
||||
|
||||
linkDirections.put(element, links);
|
||||
}
|
||||
|
||||
for (Element element : selectedElements) {
|
||||
HashMap<Element, Integer> elementLinks = linkDirections.get(element);
|
||||
for (Element el : selectedElements) {
|
||||
if (el == element) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// controllo anche prima per evitare che magari da un estrazione si vada a togliere
|
||||
if (elementLinks.get(el) == 1){
|
||||
linkDirections.get(el).put(element, -1);
|
||||
}
|
||||
|
||||
if (elementLinks.get(el) == 0) {
|
||||
if (Math.random() < 0.5) {
|
||||
linkDirections.get(el).put(element, 1);
|
||||
} else {
|
||||
linkDirections.get(el).put(element, -1);
|
||||
}
|
||||
}
|
||||
|
||||
if (elementLinks.get(el) == 1){
|
||||
linkDirections.get(el).put(element, -1);
|
||||
} else {
|
||||
linkDirections.get(el).put(element, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
System.out.println(linkDirections);
|
||||
|
||||
// hashmap che dato una coppia di element (è un set cosi AB = BA) ti torna la posizione all0interno dell'array di valori passato al sistema lineare
|
||||
HashMap<Set<Element>, Integer> pairIndex = new HashMap<>();
|
||||
// Mappa delle direzioni tra elementi (1 = attacca, -1 = subisce)
|
||||
Map<Element, Map<Element, Integer>> linkDirections = generateValidDirections(selectedElements);
|
||||
|
||||
// Mappa indice per ogni coppia (non ordinata) di elementi
|
||||
Map<Set<Element>, Integer> pairIndex = new HashMap<>();
|
||||
int index = 0;
|
||||
for (int i = 0; i < selectedElements.size(); i++) {
|
||||
for (int j = i + 1; j < selectedElements.size(); j++) {
|
||||
Set<Element> pair = Set.of(selectedElements.get(i), selectedElements.get(j));
|
||||
|
||||
pairIndex.put(pair, index++);
|
||||
for (int i = 0; i < numElements; i++) {
|
||||
for (int j = i + 1; j < numElements; j++) {
|
||||
pairIndex.put(Set.of(selectedElements.get(i), selectedElements.get(j)), index++);
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println(pairIndex);
|
||||
|
||||
// matrice incognite
|
||||
int[][] A = new int[numElements][numElements * (numElements - 1) / 2];
|
||||
|
||||
// matrice termini noti
|
||||
// Costruzione del sistema lineare Ax = b (b = 0)
|
||||
int[][] A = new int[numElements][pairIndex.size()];
|
||||
int[] b = new int[numElements];
|
||||
|
||||
// popolo le 2 matrici
|
||||
int i = 0;
|
||||
for (Element element : selectedElements) {
|
||||
int[] line = new int[numElements * (numElements - 1) / 2];
|
||||
HashMap<Element, Integer> elementLinks = linkDirections.get(element);
|
||||
for (Element el : selectedElements) {
|
||||
if (el == element) {
|
||||
continue;
|
||||
} else {
|
||||
int idx = getIndex(element, el, pairIndex);
|
||||
line[idx] = elementLinks.get(el);
|
||||
}
|
||||
|
||||
for (int i = 0; i < numElements; i++) {
|
||||
Element e1 = selectedElements.get(i);
|
||||
int[] row = new int[pairIndex.size()];
|
||||
for (Element e2 : selectedElements) {
|
||||
if (e1 == e2) continue;
|
||||
int dir = linkDirections.get(e1).get(e2);
|
||||
int pos = pairIndex.get(Set.of(e1, e2));
|
||||
row[pos] = dir;
|
||||
}
|
||||
A[i] = line;
|
||||
A[i] = row;
|
||||
b[i] = 0;
|
||||
i++;
|
||||
}
|
||||
|
||||
|
||||
// creo e risolvo il sistema lineare associato
|
||||
// sistema lineare per trovare le soluzioni che verificano l'equilibrio
|
||||
LinearSystem system = new LinearSystem(numElements, A, b);
|
||||
|
||||
|
||||
int[] solution = system.resolve();
|
||||
System.out.println("Soluzione trovata:");
|
||||
for (int x : solution) {
|
||||
System.out.printf(String.format("%d ", x));
|
||||
}
|
||||
System.out.println();
|
||||
|
||||
|
||||
// popola il grafo in base ai risultati del sistema lineare
|
||||
for (Element element : selectedElements) {
|
||||
GraphElement graphElement = new GraphElement(element);
|
||||
for (Element el : selectedElements) {
|
||||
if (el == element) {
|
||||
continue;
|
||||
}
|
||||
int direction = linkDirections.get(element).get(el);
|
||||
graphElement.addLink(new ElementLink(solution[getIndex(element, el, pairIndex)] * direction, el));
|
||||
// dalle soluzioni del sistema popolo il grafo
|
||||
ElementGraph world = new ElementGraph();
|
||||
for (Element e1 : selectedElements) {
|
||||
GraphElement graphElement = new GraphElement(e1);
|
||||
for (Element e2 : selectedElements) {
|
||||
if (e1 == e2) continue;
|
||||
int dir = linkDirections.get(e1).get(e2);
|
||||
int val = solution[pairIndex.get(Set.of(e1, e2))];
|
||||
graphElement.addLink(new ElementLink(dir * val, e2));
|
||||
}
|
||||
world.addElement(graphElement);
|
||||
}
|
||||
world.printGraph();
|
||||
|
||||
world.printGraph();
|
||||
return world;
|
||||
}
|
||||
|
||||
private static int getIndex(Element e1, Element e2, HashMap<Set<Element>, Integer> pairIndex) {
|
||||
return pairIndex.get(Set.of(e1, e2));
|
||||
private static Map<Element, Map<Element, Integer>> generateValidDirections(List<Element> elements) {
|
||||
int n = elements.size();
|
||||
Random rand = new Random();
|
||||
Map<Element, Map<Element, Integer>> linkDirections = new HashMap<>();
|
||||
|
||||
for (Element e : elements) {
|
||||
linkDirections.put(e, new HashMap<>());
|
||||
}
|
||||
|
||||
// creo le varie coppie (l'ordine conta successivamente)
|
||||
List<Pair> pairs = new ArrayList<>();
|
||||
for (int i = 0; i < n; i++) {
|
||||
for (int j = i + 1; j < n; j++) {
|
||||
pairs.add(new Pair(elements.get(i), elements.get(j)));
|
||||
}
|
||||
}
|
||||
|
||||
boolean valid;
|
||||
// controllo che ci sia almeno un arco entrante e uno uscente
|
||||
do {
|
||||
valid = true;
|
||||
Map<Element, Integer> exitingArcs = new HashMap<>();
|
||||
Map<Element, Integer> enteringArcs = new HashMap<>();
|
||||
|
||||
// resetto i valori per evitare che cicli precedenti abbiano variato qualcosa
|
||||
for (Element e : elements) {
|
||||
linkDirections.get(e).clear();
|
||||
exitingArcs.put(e, 0);
|
||||
enteringArcs.put(e, 0);
|
||||
}
|
||||
|
||||
// mescolo le coppie e determino i collegamenti (1 uscente, -1 entrante)
|
||||
Collections.shuffle(pairs);
|
||||
for (Pair pair : pairs) {
|
||||
Element e1 = pair.getFirst();
|
||||
Element e2 = pair.getSecond();
|
||||
boolean dir = rand.nextBoolean();
|
||||
if (dir) {
|
||||
linkDirections.get(e1).put(e2, 1);
|
||||
linkDirections.get(e2).put(e1, -1);
|
||||
enteringArcs.put(e1, enteringArcs.get(e1) + 1);
|
||||
exitingArcs.put(e2, exitingArcs.get(e2) + 1);
|
||||
} else {
|
||||
linkDirections.get(e2).put(e1, 1);
|
||||
linkDirections.get(e1).put(e2, -1);
|
||||
enteringArcs.put(e2, enteringArcs.get(e2) + 1);
|
||||
exitingArcs.put(e1, exitingArcs.get(e1) + 1);
|
||||
}
|
||||
}
|
||||
|
||||
// controllo se la struttura è valida
|
||||
for (Element e : elements) {
|
||||
if (exitingArcs.get(e) == 0 || enteringArcs.get(e) == 0) {
|
||||
valid = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} while (!valid);
|
||||
return linkDirections;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue