Naloga 4 - greedy works

This commit is contained in:
Gašper Dobrovoljc 2025-05-09 17:24:44 +02:00
parent 2f8a820619
commit 8e8e0d3598
No known key found for this signature in database
GPG Key ID: 0E7E037018CFA5A5
2 changed files with 91 additions and 79 deletions

View File

@ -1,27 +1,37 @@
public class Graf { public class Graf {
private final Node[] nodes; private final MaxHeap<Node>.HeapNode[] nodes;
private final MaxHeap<Node> heap = new MaxHeap<>(); private final MaxHeap<Node> heap = new MaxHeap<>();
@SuppressWarnings("unchecked")
Graf(int n) { Graf(int n) {
this.nodes = new Node[n]; this.nodes = new MaxHeap.HeapNode[n];
for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++) {
Node node = new Node(i); Node node = new Node(i);
nodes[i] = node; nodes[i] = heap.insert(node);
heap.insert(node);
} }
} }
void povezi(int u, int v) { void povezi(int u, int v) {
nodes[u].degree++; nodes[u].value.degree++;
nodes[v].degree++; nodes[u].value.neighbors.add(nodes[v]);
nodes[u].neighbors.add(nodes[v]); heap.siftUp(nodes[u].index);
nodes[v].neighbors.add(nodes[u]);
// heap.heapify(u); nodes[v].value.degree++;
// heap.heapify(v); nodes[v].value.neighbors.add(nodes[u]);
heap.rebuild(); heap.siftUp(nodes[v].index);
}
void grobaSila() {
} }
void pozresni() { void pozresni() {
MaxHeap<Node> heap = new MaxHeap<>(this.heap);
for (var heapNode : nodes) {
var node = heapNode.value;
node.degree = node.neighbors.size();
}
ArrList<Integer> used = new ArrList<>(); ArrList<Integer> used = new ArrList<>();
while (!heap.isEmpty()) { while (!heap.isEmpty()) {
@ -30,12 +40,13 @@ public class Graf {
break; break;
} }
LinkedList<Node>.Node neighbor = node.neighbors.root; for (int i = 0; i < node.neighbors.size(); i++) {
do { var neighbor = node.neighbors.get(i);
neighbor.value.degree--; if (neighbor.value.degree > 0) {
heap.heapify(neighbor.value.id); neighbor.value.degree--;
neighbor = neighbor.next; heap.siftDown(neighbor.index);
} while (neighbor != null); }
}
used.add(node.id); used.add(node.id);
} }
@ -56,7 +67,8 @@ public class Graf {
class Node implements Comparable<Node> { class Node implements Comparable<Node> {
int id; int id;
int degree = 0; int degree = 0;
LinkedList<Node> neighbors = new LinkedList<>(); // LinkedList<MaxHeap<Node>.HeapNode> neighbors = new LinkedList<>();
ArrList<MaxHeap<Node>.HeapNode> neighbors = new ArrList<>();
Node(int id) { Node(int id) {
this.id = id; this.id = id;
@ -78,7 +90,27 @@ class Node implements Comparable<Node> {
} }
class MaxHeap<T extends Comparable<T>> { class MaxHeap<T extends Comparable<T>> {
final private ArrList<T> arr; class HeapNode implements Comparable<HeapNode> {
int index;
T value;
HeapNode(T value, int index) {
this.value = value;
this.index = index;
}
@Override
public int compareTo(HeapNode o) {
return this.value.compareTo(o.value);
}
@Override
public String toString() {
return this.value.toString();
}
}
final private ArrList<HeapNode> arr;
public MaxHeap() { public MaxHeap() {
arr = new ArrList<>(); arr = new ArrList<>();
@ -101,12 +133,15 @@ class MaxHeap<T extends Comparable<T>> {
} }
private void swap(int i, int j) { private void swap(int i, int j) {
T tmp = arr.get(i); HeapNode nodeI = arr.get(i);
arr.set(i, arr.get(j)); HeapNode nodeJ = arr.get(j);
arr.set(j, tmp); nodeI.index = j;
nodeJ.index = i;
arr.set(i, nodeJ);
arr.set(j, nodeI);
} }
public void heapify(int i) { public void siftDown(int i) {
int largest = i; int largest = i;
int left = leftChild(i); int left = leftChild(i);
int right = rightChild(i); int right = rightChild(i);
@ -121,17 +156,30 @@ class MaxHeap<T extends Comparable<T>> {
if (largest != i) { if (largest != i) {
swap(i, largest); swap(i, largest);
heapify(largest); siftDown(largest);
} }
} }
public void insert(T x) { public void siftUp(int i) {
arr.add(x); int parent = parent(i);
if (parent < 0) return;
if (arr.get(i).compareTo(arr.get(parent)) > 0) {
swap(i, parent);
siftUp(parent);
}
}
public HeapNode insert(T x) {
HeapNode node = new HeapNode(x, arr.size());
arr.add(node);
int currentIndex = arr.size() - 1; int currentIndex = arr.size() - 1;
while (currentIndex > 0 && arr.get(currentIndex).compareTo(arr.get(parent(currentIndex))) > 0) { while (currentIndex > 0 && arr.get(currentIndex).compareTo(arr.get(parent(currentIndex))) > 0) {
swap(currentIndex, parent(currentIndex)); swap(currentIndex, parent(currentIndex));
currentIndex = parent(currentIndex); currentIndex = parent(currentIndex);
} }
return node;
} }
public boolean isEmpty() { public boolean isEmpty() {
@ -140,7 +188,7 @@ class MaxHeap<T extends Comparable<T>> {
public void rebuild() { public void rebuild() {
for (int i = parent(arr.size() - 1); i >= 0; i--) { for (int i = parent(arr.size() - 1); i >= 0; i--) {
heapify(i); siftDown(i);
} }
} }
@ -149,38 +197,16 @@ class MaxHeap<T extends Comparable<T>> {
throw new RuntimeException("Heap is empty"); throw new RuntimeException("Heap is empty");
} }
T max = arr.get(0); HeapNode max = arr.get(0);
T lastElement = arr.removeLast(); HeapNode lastElement = arr.removeLast();
if (!arr.isEmpty()) { if (!arr.isEmpty()) {
arr.set(0, lastElement); arr.set(0, lastElement);
lastElement.index = 0;
int currentIndex = 0; siftDown(0);
while (true) {
int left = leftChild(currentIndex);
int right = rightChild(currentIndex);
int largest = currentIndex;
if (left < arr.size() && arr.get(left).compareTo(arr.get(largest)) > 0) {
largest = left;
}
if (right < arr.size() && arr.get(right).compareTo(arr.get(largest)) > 0) {
largest = right;
}
if (largest == currentIndex) {
break;
}
swap(currentIndex, largest);
currentIndex = largest;
}
} }
return max; return max.value;
} }
@Override @Override
@ -193,25 +219,6 @@ class MaxHeap<T extends Comparable<T>> {
} }
} }
class LinkedList<T> {
class Node {
T value;
Node next;
Node(T value) {
this.value = value;
}
}
Node root;
public void add(T value) {
Node node = new Node(value);
node.next = root;
root = node;
}
}
class ArrList<T> { class ArrList<T> {
private T[] array; private T[] array;
private int size; private int size;

View File

@ -2,13 +2,18 @@ import java.util.*;
public class Naloga4 { public class Naloga4 {
public static void main(String[] args) { public static void main(String[] args) {
System.gc(); Graf g = new Graf(8);
Graf g = GrafGenerator.generateBarabasiAlbertGraph(40_000, 10); int[][] povezave = new int[][]{
System.gc(); {1, 2}, {2, 3}, {3, 4}, {4, 5},
long startTime = System.currentTimeMillis(); {5, 6}, {6, 7}, {7, 1}, {0, 1},
{0, 2}, {0, 3}, {0, 4}, {0, 5},
{0, 6}, {0, 7}, {0, 7}, {0, 7}
};
for (int[] povezava : povezave) {
g.povezi(povezava[0], povezava[1]);
}
g.pozresni();
g.pozresni(); g.pozresni();
long endTime = System.currentTimeMillis();
System.out.println(endTime - startTime);
} }
} }