From 2f8a8206192efada61bc0e8425c6b0d77aaf6280 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C5=A1per=20Dobrovoljc?= Date: Fri, 9 May 2025 15:46:49 +0200 Subject: [PATCH] Naloga 4 WIP --- naloga4/.gitignore | 29 ++ naloga4/.idea/.gitignore | 10 + naloga4/.idea/dictionaries/project.xml | 7 + .../inspectionProfiles/Project_Default.xml | 19 ++ naloga4/.idea/misc.xml | 6 + naloga4/.idea/modules.xml | 8 + naloga4/.idea/vcs.xml | 6 + naloga4/naloga4.iml | 11 + naloga4/src/Graf.java | 280 ++++++++++++++++++ naloga4/src/Naloga4.java | 53 ++++ 10 files changed, 429 insertions(+) create mode 100644 naloga4/.gitignore create mode 100644 naloga4/.idea/.gitignore create mode 100644 naloga4/.idea/dictionaries/project.xml create mode 100644 naloga4/.idea/inspectionProfiles/Project_Default.xml create mode 100644 naloga4/.idea/misc.xml create mode 100644 naloga4/.idea/modules.xml create mode 100644 naloga4/.idea/vcs.xml create mode 100644 naloga4/naloga4.iml create mode 100644 naloga4/src/Graf.java create mode 100644 naloga4/src/Naloga4.java diff --git a/naloga4/.gitignore b/naloga4/.gitignore new file mode 100644 index 0000000..f68d109 --- /dev/null +++ b/naloga4/.gitignore @@ -0,0 +1,29 @@ +### IntelliJ IDEA ### +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/naloga4/.idea/.gitignore b/naloga4/.idea/.gitignore new file mode 100644 index 0000000..7bc07ec --- /dev/null +++ b/naloga4/.idea/.gitignore @@ -0,0 +1,10 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Environment-dependent path to Maven home directory +/mavenHomeManager.xml +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/naloga4/.idea/dictionaries/project.xml b/naloga4/.idea/dictionaries/project.xml new file mode 100644 index 0000000..83ac57d --- /dev/null +++ b/naloga4/.idea/dictionaries/project.xml @@ -0,0 +1,7 @@ + + + + graf + + + \ No newline at end of file diff --git a/naloga4/.idea/inspectionProfiles/Project_Default.xml b/naloga4/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..5b739d1 --- /dev/null +++ b/naloga4/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,19 @@ + + + + \ No newline at end of file diff --git a/naloga4/.idea/misc.xml b/naloga4/.idea/misc.xml new file mode 100644 index 0000000..49c5998 --- /dev/null +++ b/naloga4/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/naloga4/.idea/modules.xml b/naloga4/.idea/modules.xml new file mode 100644 index 0000000..6571374 --- /dev/null +++ b/naloga4/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/naloga4/.idea/vcs.xml b/naloga4/.idea/vcs.xml new file mode 100644 index 0000000..6c0b863 --- /dev/null +++ b/naloga4/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/naloga4/naloga4.iml b/naloga4/naloga4.iml new file mode 100644 index 0000000..c90834f --- /dev/null +++ b/naloga4/naloga4.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/naloga4/src/Graf.java b/naloga4/src/Graf.java new file mode 100644 index 0000000..8221065 --- /dev/null +++ b/naloga4/src/Graf.java @@ -0,0 +1,280 @@ +public class Graf { + private final Node[] nodes; + private final MaxHeap heap = new MaxHeap<>(); + + Graf(int n) { + this.nodes = new Node[n]; + for (int i = 0; i < n; i++) { + Node node = new Node(i); + nodes[i] = node; + heap.insert(node); + } + } + + void povezi(int u, int v) { + nodes[u].degree++; + nodes[v].degree++; + nodes[u].neighbors.add(nodes[v]); + nodes[v].neighbors.add(nodes[u]); +// heap.heapify(u); +// heap.heapify(v); + heap.rebuild(); + } + + void pozresni() { + ArrList used = new ArrList<>(); + + while (!heap.isEmpty()) { + Node node = heap.pop(); + if (node.degree == 0) { + break; + } + + LinkedList.Node neighbor = node.neighbors.root; + do { + neighbor.value.degree--; + heap.heapify(neighbor.value.id); + neighbor = neighbor.next; + } while (neighbor != null); + + used.add(node.id); + } + + print(used); + } + + private void print(ArrList arr) { + int idxStart = arr.size() > 100 ? arr.size() - 100 : 0; + for (int i = idxStart; i < arr.size(); i++) { + System.out.print(arr.get(i)); + if (i < arr.size() - 1) System.out.print(" "); + } + System.out.println(); + } +} + +class Node implements Comparable { + int id; + int degree = 0; + LinkedList neighbors = new LinkedList<>(); + + Node(int id) { + this.id = id; + } + + @Override + public int compareTo(Node other) { + int deg = Integer.compare(this.degree, other.degree); + if (deg == 0) { + return Integer.compare(other.id, this.id); + } + return deg; + } + + @Override + public String toString() { + return "Node [id=" + id + ", degree=" + degree + "]"; + } +} + +class MaxHeap> { + final private ArrList arr; + + public MaxHeap() { + arr = new ArrList<>(); + } + + public MaxHeap(MaxHeap heap) { + this.arr = new ArrList<>(heap.arr); + } + + private int parent(int i) { + return (i - 1) / 2; + } + + private int leftChild(int i) { + return 2 * i + 1; + } + + private int rightChild(int i) { + return 2 * i + 2; + } + + private void swap(int i, int j) { + T tmp = arr.get(i); + arr.set(i, arr.get(j)); + arr.set(j, tmp); + } + + public void heapify(int i) { + int largest = i; + int left = leftChild(i); + int right = rightChild(i); + + 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 != i) { + swap(i, largest); + heapify(largest); + } + } + + public void insert(T x) { + arr.add(x); + int currentIndex = arr.size() - 1; + while (currentIndex > 0 && arr.get(currentIndex).compareTo(arr.get(parent(currentIndex))) > 0) { + swap(currentIndex, parent(currentIndex)); + currentIndex = parent(currentIndex); + } + } + + public boolean isEmpty() { + return arr.isEmpty(); + } + + public void rebuild() { + for (int i = parent(arr.size() - 1); i >= 0; i--) { + heapify(i); + } + } + + public T pop() { + if (arr.isEmpty()) { + throw new RuntimeException("Heap is empty"); + } + + T max = arr.get(0); + T lastElement = arr.removeLast(); + + if (!arr.isEmpty()) { + arr.set(0, lastElement); + + int currentIndex = 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; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < arr.size(); i++) { + sb.append(arr.get(i)).append(" "); + } + return sb.toString(); + } +} + +class LinkedList { + 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 { + private T[] array; + private int size; + + @SuppressWarnings("unchecked") + public ArrList() { + array = (T[]) new Object[64]; + size = 0; + } + + @SuppressWarnings("unchecked") + public ArrList(ArrList list) { + this.size = list.size; + this.array = (T[]) new Object[list.array.length]; + System.arraycopy(list.array, 0, this.array, 0, list.size); + } + + private boolean isFull() { + return size == array.length; + } + + private void resize() { + @SuppressWarnings("unchecked") + T[] tmp = (T[]) new Object[array.length * 2]; + System.arraycopy(array, 0, tmp, 0, size); + array = tmp; + } + + public T get(int i) { + return array[i]; + } + + public void add(T t) { + if (isFull()) { + resize(); + } + array[size++] = t; + } + + public void set(int i, T t) { + array[i] = t; + } + + public T removeLast() { + T tmp = array[--size]; + array[size] = null; + return tmp; + } + + public int size() { + return size; + } + + public boolean isEmpty() { + return size == 0; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < size; i++) { + sb.append(array[i]).append(" "); + } + return sb.toString(); + } +} diff --git a/naloga4/src/Naloga4.java b/naloga4/src/Naloga4.java new file mode 100644 index 0000000..bfdf952 --- /dev/null +++ b/naloga4/src/Naloga4.java @@ -0,0 +1,53 @@ +import java.util.*; + +public class Naloga4 { + public static void main(String[] args) { + System.gc(); + Graf g = GrafGenerator.generateBarabasiAlbertGraph(40_000, 10); + System.gc(); + long startTime = System.currentTimeMillis(); + g.pozresni(); + long endTime = System.currentTimeMillis(); + System.out.println(endTime - startTime); + } +} + +class GrafGenerator { + public static Graf generateBarabasiAlbertGraph(int n, int m) { + if (m < 1 || m >= n) { + throw new IllegalArgumentException("Neveljaven 'm'"); + } + + Graf graph = new Graf(n); + List nodePool = new ArrayList<>(); + + // Zacnem z polnim grafom velikosti m + for (int i = 0; i < m; i++) { + for (int j = i + 1; j < m; j++) { + graph.povezi(i, j); + nodePool.add(i); + nodePool.add(j); + } + } + + Random rand = new Random(5); + + // Povezi preostala vozlisca + for (int newNode = m; newNode < n; newNode++) { + Set targets = new HashSet<>(); + + while (targets.size() < m) { + int selected = nodePool.get(rand.nextInt(nodePool.size())); + targets.add(selected); + } + + for (int target : targets) { + graph.povezi(newNode, target); + nodePool.add(newNode); + nodePool.add(target); + } + } + + return graph; + } +} \ No newline at end of file