Algorithm

[Algorithm] μž‘μ—… μŠ€μΌ€μ€„λ§

yevdev 2021. 10. 13. 10:54

πŸ’‘μž‘μ—…μŠ€μΌ€μ€„λ§

  • μˆ˜ν–‰ν•΄μ•Όν•  λ‹€μˆ˜μ˜ Job을 μ£Όμ–΄μ§„ λͺ©μ μ—λ”°λΌ μ–΄λ–»κ²Œ μˆ˜ν–‰ν• μ§€λ₯Ό κ²°μ •ν•˜λŠ” 문제
  • μ£Όμ–΄μ§„ λͺ©μ μ—λ”°λΌ μž‘μ—…μŠ€μΌ€μ€„λ§μ„ λ‹€μ–‘ν•˜κ²Œ μ •μ˜ν•  수 μžˆλ‹€. 
  • μ΄λŸ¬ν•œ λ¬Έμ œλ“€μ€ λŒ€λΆ€λΆ„ NP-hardλ¬Έμ œμ΄λ‚˜, 일뢀 λͺ©μ μ— λŒ€ν•΄μ„œ λ˜λŠ” 문제λ₯Ό λ‹¨μˆœν™” μ‹œν‚¬ 경우 polynomial time에 ν•΄κ²°ν•  수 μžˆλ‹€.

 

πŸ’‘μž‘μ—…μŠ€μΌ€μ€„λ§ 문제

  • μž‘μ—…μ˜ μˆ˜ν–‰μ‹œκ°„μ΄ μ€‘λ³΅λ˜μ§€ μ•Šλ„λ‘ λͺ¨λ“  μž‘μ—…μ„ κ°€μž₯ 적은 수의 기계에 λ°°μ •ν•˜λŠ” λ¬Έμ œμ΄λ‹€.
  • n개의 κ°μž‘μ—…μ€ μ‹œμž‘μ‹œκ°„κ³Ό μ’…λ£Œμ‹œκ°„μ΄ μžˆλ‹€.
  • μ£Όμ–΄μ§„ λ¬Έμ œμš”μ†Œ
    1. μž‘μ—…μ˜ 수
    2. 각 μž‘μ—…μ˜ μ‹œμž‘κ³Ό μ’…λ£Œμ‹œκ°„ : μ΄λŠ” μ •ν•΄μ Έ μžˆμœΌλ―€λ‘œ μž‘μ—…μ˜ 길이도 μ£Όμ–΄μ§„ 것이 λœλ‹€.
  • μ‹œκ°μ‹œκ°„, μ’…λ£Œμ‹œκ°„, μž‘μ—…μ˜ 길이에 λŒ€ν•΄ 그리디 μ•Œκ³ λ¦¬μ¦˜μ„ 생각해 λ³Ό 수 μžˆλŠ”λ°
    1. λΉ λ₯Έ μ‹œμž‘μ‹œκ°„ μž‘μ—… μš°μ„  λ°°μ •
    2. λΉ λ₯Έ μ’…λ£Œμ‹œκ°„ μž‘μ—… μš°μ„  λ°°μ •
    3. 짧은 μž‘μ—… μš°μ„  λ°°μ •
    4. κΈ΄ μž‘μ—… μš°μ„  λ°°μ •
  • 이쀑 1번째 μ•Œκ³ λ¦¬μ¦˜λ§Œμ΄ μ΅œμ ν•΄λ₯Ό 찾을 수 μžˆλ‹€.

 

πŸ’‘μ˜μ‚¬μ½”λ“œ

  • μž…λ ₯ : n개의 μž‘μ—… t1~tn
  • 좜λ ₯ : 각 기계에 λ°°μ •λœ μž‘μ—… μˆœμ„œ
  • 1. μ‹œμž‘ μ‹œκ°„μ˜ μ˜€λ¦„μ°¨μˆœμœΌλ‘œ μ •λ ¬ν•œ μž‘μ—… 리슀트 L
    2. while(L!=∅){
    3. 	Lμ—μ„œ κ°€μž₯ 이λ₯Έ μ‹œμž‘μ‹œκ°„μ˜ μž‘μ—… tiλ₯Ό κ°€μ Έμ˜¨λ‹€.
    4. 	if(tiλ₯Ό μˆ˜ν–‰ν•  기계가 μžˆλ‹€λ©΄)
    5. 		tiλ₯Ό μˆ˜ν–‰ν•  수 μžˆλŠ” 기계에 λ°°μ •ν•œλ‹€.
    6. 	else
    7. 		μƒˆλ‘œμš΄ 기계에 tiλ₯Ό λ°°μ •ν•œλ‹€.
    8. 	tiλ₯Ό Lμ—μ„œ μ œκ±°ν•œλ‹€.
    }
    9. return 각 기계에 λ°°μ •λœ μž‘μ—… μˆœμ„œ

 

 

πŸ’‘C++ μ½”λ“œ

#include <iostream>
#include <vector> // 벑터 λ¦¬μŠ€νŠΈμ‹œ μ‚¬μš©
#include <utility> // μž…λ ₯κ°’ -> λ²‘ν„°λ¦¬μŠ€νŠΈ ν•œμŒμœΌλ‘œ
#include <algorithm>

using namespace std;

#define X first
#define Y second

// μž…μΆœλ ₯ 속도 κ°œμ„ 
#define IOFAST ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);

vector<pair<int,int> > task;
vector< vector<int> > machine;
int nMachine = 0;

int Operating(int start)
{
    int i;
    // 업무가 ν• λ‹Ήλœ 기계가 μ‘΄μž¬ν•˜λŠ” 경우
    if (nMachine > 0)
    {
        for (i = 0; i < nMachine; i++)
        {
            // 업무λ₯Ό μˆ˜ν–‰ν•˜κ³  μžˆλŠ” 기계가 있고,
            // κ·Έ 기계가 λ‹€μŒ 업무λ₯Ό μˆ˜ν–‰ν•  수 μžˆλŠ” 경우 ν•΄λ‹Ή 기계λ₯Ό 배치
            if (machine[i].size() > 0 && task[machine[i].back()].second <= start)
            {
                return i;
            }
        }
 
        // 업무λ₯Ό μˆ˜ν–‰ν• λ§Œν•œ 기계가 μ—†μœΌλ©΄ μƒˆ 기계λ₯Ό 배치
        nMachine++;
        return i;
    }
    // 업무가 ν• λ‹Ήλœ 기계가 μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ” 경우
    else
    {
        nMachine++;
        return 0;
    }
}
 
void Scheduling(int nTask)
{
    int i = 0;
    while (i < nTask)
    {
        // 기계 번호λ₯Ό ν• λ‹Ή λ°›κ³ ,
        // ν•΄λ‹Ή 기계에 업무 λ°°μ •
        int machineNum=Operating(task[i].first);
        machine[machineNum].push_back(i);
        i++;
    }
}


int main(){
    IOFAST;
    int N;  // μž‘μ—…μ˜ 수
    
    cin >> N;
    cin.ignore();

    for(int i=0;i<N;i++){
        int a,b;
        cin >> a >> b ;
        task.push_back(make_pair(a,b));
    }

    for (int i = 0; i < N; i++)
    {
        vector<int> element(0);
        machine.push_back(element);
    }

    sort(task.begin(), task.end());
    
    Scheduling(task.size());

    cout<<nMachine;
}

 

β°μ‹œκ°„λ³΅μž‘λ„

  • Line1 : O(nlogn)
  • while-λ£¨ν”„μ—μ„œλŠ” μž‘μ—…μ„ Lμ—μ„œ κ°€μ Έλ‹€κ°€ μˆ˜ν–‰κ°€λŠ₯ν•œ 기계λ₯Ό μ°Ύμ•„μ„œ λ°°μ •ν•˜λŠ” μ‹œκ°„ : O(m) (m은 μ‚¬μš©λœ κΈ°κ³„μ˜ 횟수)
  • while루프가 μˆ˜ν–‰λœ 총 νšŸμˆ˜κ°€ nλ²ˆμ΄λ―€λ‘œ, line2~9κΉŒμ§€λŠ” O(m)xn = O(nm)
  • λ”°λΌμ„œ, O(nlogn) + O(mn)

βž°μ‘μš©

  • λΉ„μ¦ˆλ‹ˆμŠ€ ν”„λ‘œμ„Έμ‹±
  • 곡μž₯ 생산 곡정
  • κ°•μ˜μ‹€/μ„Έλ―Έλ‚˜ λ£Έ λ°°μ •
  • 컴퓨터 νƒœμŠ€ν¬ μŠ€μΌ€μ€„λ§

Reference

μ„œμšΈκ³Όν•™κΈ°μˆ λŒ€ν•™κ΅ 컴퓨터곡학과 μ•Œκ³ λ¦¬μ¦˜ 수μ—