* 곡λΆλ₯Ό νλ©° μ 리ν κΈμ λλ€. μμ ν μ μ΄ μλ€λ©΄ λκΈ λ¨κ²¨μ£ΌμΈμ.
μμ μ€μΌμ€λ§μ΄λ?
μκ³ λ¦¬μ¦ λ¬Έμ λ₯Ό νλ€λ³΄λ©΄ μμ μκ°κ³Ό μ’ λ£ μκ°μ΄ μ§μ λ μ΄λ ν μμ λ€μ μννλ λ¬Έμ μ λ§μ£ΌμΉ λκ° μλ€. μ΄λ λ¬Έμ λ₯Ό ν΄κ²°νκΈ° μν΄μ μ λ ¬μ΄λ λ§΅ κ°μ μλ£κ΅¬μ‘°λ₯Ό μ°λ©΄ λ κ² κ°μλ°.. λ§μ ꡬνν΄λ³΄λ©΄ μ½μ§ μμ κ²μ΄λ€.
λ°λΌμ μ΄λ¬ν λ¬Έμ μ νμ λν΄μλ μ΄λμ λ νμ κ°μ§κ³ νΈλ κ²μ΄ μ’λ€. μ§κΈκΉμ§ λ΄κ° λ³Έ λ°λ‘λ κ²°κ΅ κ·Έ ν λ΄μμ ν¬κ² λ²μ΄λμ§ μκΈ° λλ¬Έμ΄λ€.
κ·Έλμ μμ μ€μΌμ€λ§μ΄ 무μμΈκ° νλ©΄, λͺ¨λ μμ μ μννλ λ¬Έμ μ΄λ€. λ¬Όλ‘ κ·Έλ₯ μννλ κ²μ΄ μλλΌ ν΄λΉ μμ λ€μ μν μκ°μ΄ λ€μ£½λ°μ£½ μμ΄μ§ μκ³ μ΅μνμΌλ‘ κΈ°κ³λ₯Ό μ¬μ©ν΄μΌ νλ€. κΈ°κ³κ° μλμ΄λ κ°μμ€ λ°°μΉ, μ»΄ν¨ν° λ± μμ μ μνν μ μλ μν 주체면 λͺ¨λ κ°λ₯νλ€.
λ€μλ§ν΄, μμ μ€μΌμ€λ§μ κ° μμ μ μμμκ°, μ’ λ£ μκ°μ΄ μ‘΄μ¬ν λ μ΅μνμ κΈ°κ³(κ°μμ€, μ»΄ν¨ν°...)λ₯Ό μ¬μ©νμ¬ λͺ¨λ μμ μ μννλ κ²μ΄λ€.
μ μ΄μ , μμ μ€μΌμ€λ§μ΄ λ¬΄μ¨ μκ³ λ¦¬μ¦μΈμ§λ λμΆ© μκ² κ³ , μ΄λ»κ² ν΄μΌ μ΅μ μ ν΄λ₯Ό 보μ₯ν μ μμ μ§ μκ°ν΄μΌ νλ€. μ¬κΈ°μ λ§νλ μ΅μ μ ν΄λ, μ΅μνμ κΈ°κ³λ‘ λͺ¨λ μμ μ μνν μ μμμ λ§νλ€.
κ·Έλ¬ν λ°©λ²μΌλ‘λ ν¬κ² λ€ κ°μ§ μ λκ° μλ€.
1οΈβ£ λΉ λ₯Έ μμμκ° μμ μ°μ (Earliest start time first) λ°°μ
2οΈβ£ λΉ λ₯Έ μ’ λ£μκ° μμ μ°μ (Earliest finish time first) λ°°μ
3οΈβ£ μ§§μ μμ μ°μ (Shortest job first) λ°°μ
4οΈβ£ κΈ΄ μμ μ°μ (Longest job first) λ°°μ
μ΄ μ€μμ κ°μ₯ λ§μ΄ μ¬μ©νλ κ²μ 1λ²μ κ²½μ°μ΄λ€. μ΅μ ν΄λ₯Ό μμ νκ² λ³΄μ₯νλ μκ³ λ¦¬μ¦μ΄ 1λ²λ°μ μκΈ° λλ¬Έμ΄λ€. λ¬Όλ‘ μν©μ λ°λΌμ μ΅μ ν΄λ₯Ό 보μ₯νμ§ μλλΌλ μ¬μ©ν΄μΌλ§ νλ λλ μκΈ΄ ν κ²μ΄μ§λ§ μμ£Ό μ¬μ©νμ§λ μλλ€.
μμ μ€μΌμ€λ§μ μλ μ½λ(Pseudo Code)
λ€μμΌλ‘ μ΄ν΄λ³Ό κ²μ μμ¬ μ½λμ΄λ€. κ·Έ λ‘μ§λ§ μΆ©λΆν νμ νκ³ μλ€λ©΄ μ΄λ ν μΈμ΄λΌλ μ½κ² μ μ©ν μ μμ κ²μ΄λ€.
μ λ ₯ : n κ°μ μμ (t1 ~ tn)
μΆλ ₯ : κ° κΈ°κ³μ λ°°μ λ μμ μμ
μμ μκ°μΌλ‘ μ λ ¬ν μμ 리μ€νΈ: L(μ€λ¦ μ°¨μ μ λ ¬)
whlie Lμ΄ λΉμ΄μμ§ μλ€λ©΄
Lμμ κ°μ₯ μ΄λ₯Έ μμ μκ° μμ tiλ₯Ό κ°μ Έμ¨λ€.
if tiλ₯Ό μνν μ μλ κΈ°κ³κ° μλ€λ©΄
tiλ₯Ό μνν μ μλ κΈ°κ³μ λ°°μ νλ€.
else
μ κΈ°κ³μ tiλ₯Ό λ°°μ νλ€.
tiλ₯Ό Lμμ μ κ±°νλ€.
return κ° κΈ°κ³μ λ°°μ λ μμ μμ
μμ λ€μ μ λ ¬νκ³ , κ° μμ μκ°λλ₯Ό μ²λ¦¬ν μ μλ μ΅μνμ κΈ°κ³λ₯Ό μ°Ύμ λ°°μ νλ κ². κ·Έκ²μ΄ μ λΆμ΄κΈ΄ νλ€. μ΄ λλ¬Έμ μκ° λ³΅μ‘λλ μ λ ¬ μκ° O(nlogn)μ κΈ°κ³λ₯Ό μ°Ύκ³ whileλ¬ΈμΌλ‘ μμ μ λ°°μ νλ κ³Όμ μΈ O(mn)μ λν κ°μ΄λ€.(O(nlogn) + O(mn)
μλλ μμ μ€μΌμ€λ§μ μλ μ½λλ₯Ό Javaλ‘ κ΅¬νν μμμ΄λ€. μλ μ½λλ₯Ό μ€μ μ½λλ₯Ό ꡬννλ κ³Όμ λ λ΄λ¬μΌ λμ€μ λ νλ€ μ μλ€. ν λ²μ© μ΄ν΄λ³΄μ.
π μμ μ€μΌμ€λ§ μ½λ μμ(Java)
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
class Job {
int id;
int startTime;
int endTime;
public Job(int id, int startTime, int endTime) {
this.id = id;
this.startTime = startTime;
this.endTime = endTime;
}
}
public class JobScheduling {
public static List<List<Job>> scheduleJobs(List<Job> jobs) {
Collections.sort(jobs, Comparator.comparingInt(job -> job.startTime));
int numMachines = 1;
List<List<Job>> machineSchedule = new ArrayList<>();
machineSchedule.add(new ArrayList<>(Arrays.asList(jobs.get(0))));
for (int i = 1; i < jobs.size(); i++) {
Job currentJob = jobs.get(i);
boolean assigned = false;
for (int j = 0; j < numMachines; j++) {
List<Job> machine = machineSchedule.get(j);
Job lastJob = machine.get(machine.size() - 1);
if (currentJob.startTime >= lastJob.endTime) {
machine.add(currentJob);
assigned = true;
break;
}
}
if (!assigned) {
List<Job> newMachine = new ArrayList<>(Arrays.asList(currentJob));
machineSchedule.add(newMachine);
numMachines++;
}
}
return machineSchedule;
}
public static void main(String[] args) {
List<Job> jobs = new ArrayList<>();
jobs.add(new Job(1, 7, 8));
jobs.add(new Job(2, 3, 7));
jobs.add(new Job(3, 1, 5));
jobs.add(new Job(4, 5, 9));
jobs.add(new Job(5, 0, 2));
jobs.add(new Job(6, 6, 8));
jobs.add(new Job(7, 1, 6));
List<List<Job>> machineSchedule = scheduleJobs(jobs);
for (int i = 0; i < machineSchedule.size(); i++) {
System.out.println("Machine " + (i + 1));
for (Job job : machineSchedule.get(i)) {
System.out.println("Job " + job.id + " ("+job.startTime + "," + job.endTime + ")");
}
}
}
}
π² class Jobμ μμ μκ°, μ’ λ£ μκ°, id κ°μ κ°μ§λ€.
π² Comparatorλ₯Ό ν΅ν΄μ μμ μκ°μ κΈ°μ€μΌλ‘ μ€λ¦μ°¨μ μ λ ¬νλ€.
π² νμ¬ Job(currentJob)μ΄ κΈ°μ‘΄μ κ°μ§κ³ μλ machineλ€λ‘ μ²λ¦¬κ° κ°λ₯ν μ§ μμλ³Έλ€. μ΄ λ μκ°λκ° κ²ΉμΉλ μ§μ μ¬λΆμ λ°λΌ κ°λ₯νμ§ μλμ§ νμΈν μ μλ€. κ²°κ΅μλ μ€λ³΅μ΄ μμ΄μΌ νλ€λ κ²μ΄ μ΄ μμ μ€μΌμ€λ§μ λͺ©μ μ΄κΈ° λλ¬Έμ΄λ€.
π² λ§μ½ νμ¬ κ°μ§κ³ μλ machineλ€λ‘ μ²λ¦¬κ° λΆκ°λ₯νλ€λ©΄, μλ‘μ΄ newMachineμ λ§λ€μ΄μ μ²λ¦¬ν΄μΌ νλ€.
ννλ§ μ½λ©(HuffmanCoding)
μ°λ¦¬λ νμ λΉ λ₯Έ μκ°, κ·Έλ¦¬κ³ μ’μ ν¨μ¨μ μΆκ΅¬νλ€. μ΄λ μ€λ Ή νμΌμ λκ΅°κ°μκ² μ μ‘νλ€κ³ ν λλ λ§μ°¬κ°μ§λ‘ μ μ©λλ€. λ§μ½ μ μ‘νκ³ μ νλ νμΌμ ν¬κΈ°λ₯Ό μ€μΌ μ μλ€λ©΄ λ©λͺ¨λ¦¬ 곡κ°μ ν¨μ¨μ μΌλ‘ μ¬μ©ν μ μμΌλ©°, νμΌ μ μ‘ μκ°λ κ΅μ₯ν μ§§μμ§ κ²μ΄λ€.
μ΄λ₯Ό μν "νμΌ μμΆ"μ κΈ°λ²μ μμ΄μλ λ€μν λ°©λ²λ€μ΄ μμ§λ§, μ°λ¦¬λ μκ³ λ¦¬μ¦μ μΌλ‘ μ κ·ΌνκΈ° μ¬μ΄ "ννλ§ μμΆ"μ λνμ¬ μμ보μ.
"ννλ§ μμΆ"μ ν° νΉμ§ μ€ νλλ μ λλΆ νΉμ±μ΄λΌλ κ²μ΄λ€. ννλ§ μμΆ κΈ°λ²μ΄ μλ λ€λ₯Έ μμΆ κΈ°λ²μ μ½λμ μ½λ μ¬μ΄λ₯Ό κ΅¬λΆ μ§κΈ° μν΄ νΉλ³ν λ¬Έμλ₯Ό μ¬μ©νλ€. μλ₯Ό λ€μ΄ 101#10#1#111 λ± #μ μ¬μ©νμ¬ κ° μ½λλ₯Ό κ΅¬λΆ μ§μλ€. μ΄μ λ¬λ¦¬ ννλ§ μ½λλ κ° λ¬Έμμ ν λΉλ μ΄μ§ μ½λκ° λ€λ₯Έ λ¬Έμμ ν λΉλ μ΄μ§ μ½λμ μ λλΆκ° λμ§ μλλ€.
μ¦, ννλ§ μμΆμ μμ΄μλ #κ³Ό κ°μ΄ ꡬλΆμ μν λ¬Έμμ νμκ° μλ€. κ·Έλ κΈ° λλ¬Έμ νμΌμ μμΆκ³Ό ν΄μ μ μμ΄μλ λ³λ€λ₯Έ μ½λκ° νμνμ§ μλ€.
κ·Έλ λ€λ©΄ ννλ§ μμΆμ μ΄λ ν λ°©μμΌλ‘ μμΆμ νλ κ²μΌκΉ? μ¬κΈ°μ μμ΄μλ κ° λ¬Έμμ λΉλ μμ κΈ°λ°μ λ μ΄μ§ νΈλ¦¬λ₯Ό λ§λ€μ΄ κ° λ¬Έμμ μ΄μ§ μ½λλ₯Ό ν λΉνλ λ°©λ²μ μ¬μ©νλ€. μ΄λ κ² λ§λ€μ΄μ§ μ΄μ§ μ½λλ₯Ό ννλ§ μ½λλΌκ³ νλ€.
ννλ§ μ½λ©(HuffmanCoding)μ μλ μ½λ(Pseudo code)
μ λ ₯ : μ λ ₯ νμΌ nκ°μ λ¬Έμμ λν κ°κ°μ λΉλ μ
μΆλ ₯ : ννλ§ νΈλ¦¬
κ° λ¬Έμ λΉ λ Έλλ₯Ό λ§λ€κ³ , κ·Έ λ¬Έμμ λΉλ μλ₯Ό λ Έλμ μ μ₯νλ€.
n λ Έλμ λΉλ μμ λν΄ μ°μ μμ νλ₯Ό λ§λ λ€.
while Qμ μλ λ Έλ μ >= 2
λΉλ μκ° κ°μ₯ μ μ 2κ°μ λ Έλ(Aμ B)λ₯Ό Qμμ μ κ±°νλ€.
μ λ Έλ Nμ λ§λ€κ³ , Aμ Bλ₯Ό Nμ μμλ Έλλ‘ λ§λ λ€.
Nμ λΉλ μ = Aμ λΉλ μ + Bμ λΉλ μ
λ Έλ Nμ Qμ μ½μ νλ€.
return Q
π² μ°μ μμ νλ₯Ό μ λ§λλ κ°?
λΉλ μμ λν μ λ ¬μ νμ¬μΌ ν¨μ¨μ μΈ ννλ§ μ½λλ₯Ό λ§λ€ μ μλ€. μλ₯Ό λ€μ΄ AλΌλ λ¬Έμκ° BλΌλ λ¬Έμλ³΄λ€ λΉλ μκ° λ§λ€κ³ ν λ, μ΄μ λν ννλ§ μ½λλ₯Ό "1010"μΌλ‘ μ μ₯νλ κ²λ³΄λ¨ "10"μΌλ‘ μ μ₯νλ κ²μ΄ ν¨μ¬ μ’λ€.
μ¦, μ λ ¬μ ν¨μ¨μ μΈ ννλ§ μ½λλ₯Ό λ§λλλ° μμ΄ νμμ μΈ μμμ΄λ―λ‘ μ°μ μμ νλ₯Ό μ¬μ©νλ€.
μλλ ννλ§ μ½λ©μ Javaλ‘ κ΅¬νν μμμ΄λ€. μμ λ‘μ§μ΄ μ΄λ λΆλΆμμ μ¬μ©λλ μ§ μ΄ν΄λ³΄μ.
π ννλ§ μ½λ μμ(Java)
import java.util.Arrays;
import java.util.PriorityQueue;
import java.util.Arrays;
class Entry {
private int frequency; // λΉλ
private String word; // λ¬Έμ λλ λ¨μ΄
private Entry left; // μΌμͺ½ μμ λ
Έλ
private Entry right; // μ€λ₯Έμͺ½ μμ λ
Έλ
private String code; // Huffman μ½λ
public Entry(int newFreq, String newValue, Entry l, Entry r, String s) {
frequency = newFreq;
word = newValue;
left = l;
right = r;
code = s;
}
public int getKey() {
return frequency;
}
public String getValue() {
return word;
}
public String getCode() {
return code;
}
public Entry getLeft() {
return left;
}
public Entry getRight() {
return right;
}
public void setCode(String newCode) {
code = newCode;
}
}
public class Huffman {
private static Entry[] minHeap;
private static int size;
public Huffman(Entry[] entries, int n) {
minHeap = new Entry[n + 1];
size = 0;
for (int i = 1; i <= n; i++) {
minHeap[++size] = entries[i];
}
}
public void createHeap() {
// μ΅μ νμΌλ‘ λ³ν
for (int i = size / 2; i >= 1; i--) {
minHeapify(i);
}
}
public Entry createTree() {
while (size >= 2) {
Entry a = extractMin();
Entry b = extractMin();
Entry n = new Entry(a.getKey() + b.getKey(), "", a, b, "");
insert(n);
}
return minHeap[1];
}
private void minHeapify(int i) {
int left = 2 * i;
int right = 2 * i + 1;
int smallest = i;
if (left <= size && minHeap[left].getKey() < minHeap[i].getKey()) {
smallest = left;
}
if (right <= size && minHeap[right].getKey() < minHeap[smallest].getKey()) {
smallest = right;
}
if (smallest != i) {
swap(i, smallest);
minHeapify(smallest);
}
}
private Entry extractMin() {
if (size < 1) {
return null;
}
Entry min = minHeap[1];
minHeap[1] = minHeap[size--];
minHeapify(1);
return min;
}
private void insert(Entry entry) {
if (size >= minHeap.length - 1) {
minHeap = Arrays.copyOf(minHeap, minHeap.length * 2);
}
minHeap[++size] = entry;
int i = size;
while (i > 1 && minHeap[i].getKey() < minHeap[i / 2].getKey()) {
swap(i, i / 2);
i = i / 2;
}
}
private void swap(int i, int j) {
Entry temp = minHeap[i];
minHeap[i] = minHeap[j];
minHeap[j] = temp;
}
public void preorder(Entry root) {
if (root != null) {
if (!root.getValue().isEmpty()) {
System.out.print(root.getValue() + ": " + root.getCode() + " ");
}
preorder(root.getLeft());
preorder(root.getRight());
}
}
public static void print() {
for (int i = 1; i <= size; i++) {
System.out.print("[" + minHeap[i].getKey() + " " + minHeap[i].getValue() + "] ");
}
System.out.println();
}
public static void main(String[] args) {
Entry[] a = new Entry[7];
a[1] = new Entry(60, "a", null, null, null);
a[2] = new Entry(20, "b", null, null, null);
a[3] = new Entry(30, "c", null, null, null);
a[4] = new Entry(35, "d", null, null, null);
a[5] = new Entry(40, "e", null, null, null);
a[6] = new Entry(90, "f", null, null, null);
Huffman h = new Huffman(a, 6);
System.out.println("μ΅μ ν λ§λ€κΈ° μ ");
print();
h.createHeap();
System.out.println("μ΅μ ν:");
print();
System.out.println("ννλ§ μ½λ:");
Entry root = h.createTree();
h.generateHuffmanCodes(root, "");
h.preorder(root);
System.out.println();
}
public void generateHuffmanCodes(Entry root, String code) {
if (root != null) {
root.setCode(code);
generateHuffmanCodes(root.getLeft(), code + "0");
generateHuffmanCodes(root.getRight(), code + "1");
}
}
}
π² Entry ν΄λμ€λ Huffman Treeμ λ Έλλ₯Ό λνλΈλ€.
π² Entryλ λ¨μ΄, λ¨μ΄μ λΉλμ, μΌμͺ½ μμ, μ€λ₯Έμͺ½ μμμ λν μ 보λ₯Ό κ°μ§λ€.
π² μμ μ€λͺ μμλ μ°μ μμ νλ₯Ό ν΅ν΄μ μ΅μ κ°μ μ°Ύλλ€κ³ νμμ§λ§, ν΄λΉ μμ μμλ μ΅μ νμ μ¬μ©νμλ€.
π² minHeapfy λ©μλλ₯Ό ν΅ν΄μ μκΈ° μμ λ Έλμ μΌμͺ½, μ€λ₯Έμͺ½ μμμ λν΄ μ΅μ κ°μ μ°Ύμ μμ λ Έλλ‘ μ§μ νλ€.
π² extractMin λ©μλλ μ΅μ κ°μ λ½λ ν¨μμ΄λ€.
π² createTree λ©μλμμ λκ°μ μ΅μ κ° λ Έλλ₯Ό μ κ±°νκ³ , μ λ Έλλ₯Ό λ§λ€μ΄ μ½μ νλ€.

π² generateHuffmancodesλ₯Ό ν΅ν΄μ ννλ§ μ½λλ₯Ό μ»μ μ μλ€. λ£¨νΈ λ Έλλ‘ λΆν° μ¬κ·μ μΌλ‘ νμν΄ λκ°λ©°, μ½λλ₯Ό λΆμΌ μ μμΌλ©° λ§μ§λ§ λ¨λ§λ Έλμμ νλνλ μ½λκ° κ° λ¬Έμμ ννλ§ μ½λμμ μ μ μλ€.