নিম্নলিখিত সমস্যাটিতে বহুবর্ষের মধ্যে একটি অনুক্রম বিদ্যমান কিনা তা খুঁজে পাওয়া সম্ভব?


27

আমি এক সময়ের জন্য নিম্নলিখিত সমস্যাটি নিয়ে ভাবছিলাম, এবং এর কোনও বহুবর্ষের সমাধান আমি পাইনি। শুধু ব্রুট-ফোরস আমিও কোনও ব্যয় ছাড়াই একটি এনপি-কমপ্লিট সমস্যা এটিতে হ্রাস করার চেষ্টা করছি।

সমস্যাটি এখানে :


আপনি একটি আছে সাজানো সেট {(A1,B1),(A2,B2),,(An,Bn)} ধনাত্মক পূর্ণসংখ্যা যুগলের।

(Ai,Bi)<(Aj,Bj)Ai<Aj(Ai=AjBi<Bj) (Ai,Bi)=(Aj,Bj)Ai=AjBi=Bj

নিম্নলিখিত অপারেশন একজোড়া প্রয়োগ করা যেতে পারে: Swap(pair)। এটি জুটির উপাদানগুলিকে অদলবদল করে, সুতরাং (10,50) হয়ে যাবে (50,10)

যখন সেটটিতে একটি জুটি অদলবদল করা হয়, সেটটি স্বয়ংক্রিয়ভাবে আবার বাছাই হয়ে যায় (অদলবদল করা জুটির জায়গাটি বাইরে থেকে যায় এবং এটি সেটে তার জায়গায় চলে যাবে)।

সমস্যাটি এমন একটি দেখার অনুক্রম রয়েছে যা কিছু জোড় থেকে শুরু করে নিম্নলিখিত শর্তটি সহ পুরো সেটটি অদলবদল করে:

একটি জোড়া অদলবদল হওয়ার পরে, পরবর্তী জুটিটি অদলবদলের জন্য সেটটির উত্তরসূরি বা পূর্বসূরি জুটি হতে হবে।


এই সমস্যাটির একটি বহুপদী সময় সমাধান, বা এটিতে এনপি-কমপ্লিট সমস্যা হ্রাস করা খুব ভাল হবে।

দ্রষ্টব্য:
এটি ইতিমধ্যে সিদ্ধান্তের সমস্যা। সিকোয়েন্সটি কোনটি আমি তা জানতে চাই না: কেবল যদি সিক্যুয়েন্স বিদ্যমান থাকে।

একটি জুড়ি অদলবদলের পরে সেটটি কীভাবে সাজানো হয় তার উদাহরণ

(6, 5)
(1,2)
(3,4)
(7,8)

যদি আমি প্রথম জুটিটি অদলবদল করি তবে তা হয়ে যায়: (5,6) , এবং সেটটি বাছাই করার পরে (সাজানো জোড়টিকে তার নতুন অবস্থানে রেখে), আমাদের কাছে:

(1,2)
(3,4)
(5,6)
(7,8)

(3,4)(7,8)

গুরুত্বপূর্ণ:
আপনি ইতিমধ্যে অদলবদল জোড়াটি অদলবদল করতে পারবেন না।
যদি 'অদলবদল' ক্রিয়াকলাপগুলির ক্রম থাকে তবে সমস্ত জোড়া একবার এবং কেবল একবারে নামকরণ করতে হবে।

উদাহরণস্বরূপ যেখানে সমস্ত জুটি অদলবদল করা সম্ভব নয়

(0,0)
(1,4)
(3,2)
(5,5)


1
(A,B,C)<(A,B,C)A<AA=AB<BA=AB=BC<C)?
এমজেকিউএক্সএক্সএক্সএক্সএক্সএক্সএক্সএক্সএক্স

3
অ্যাসাইনমেন্ট সমস্যাগুলি সাধারণভাবে cstheory.stackexchange.com এ স্বাগত নয়।
সোসোশি ইটো

3
হুম, আমি নিশ্চিত নই। সাধারণত এখানে যুক্তিটি হ'ল সাধারণ গৃহকর্মের প্রশ্নের উত্তর দেওয়া ভাল অনুশীলন নয় কারণ এটি করা ভবিষ্যতের কারও জন্য হোমওয়ার্কের উদ্দেশ্যকে নষ্ট করে দেবে। তবে এক্ষেত্রে সমস্যাটি সাধারণ সমস্যার মতো দেখায় না ।
সোসোশি ইটো

2
যদি আপনি "এটি একটি হোমওয়ার্ক ছিল" এর চেয়ে আলাদা কোনও অনুপ্রেরণা দেন তবে লোকেরা আগ্রহী হতে পারে এবং এটি বন্ধ হবে না। এর সম্ভাব্য প্রয়োগ কী হতে পারে?
মার্কোস ভিলাগ্রা

2
A={(x1,y1),,(xn,yn)}

উত্তর:


16

... আমি এনপিসি সমস্যা থেকে হ্রাস তৈরি করতে কিছু নিদর্শন অনুসন্ধান করেছি, তবে "কাঁটাচামচ" দিয়ে "প্রবাহ" উপস্থাপনের উপায় খুঁজে পাইনি ...

সুতরাং (কিছু কাজের পরে) এটি একটি বহুপদী আলগোরিদিম ...

অ্যালগরিদম

N2(aj,bj)bjajajbjbjajbjbkbjbjbkN

  • (aj,bj)bjajstart

    • (ak,bk),akajakendakbk

      • startend

bjLRLRRL

  • edgesLR
  • edgesRL
  • flowedgesLRedgesRL

মামলা:

|flow|>1

end>bjendR

flow=1Lend

flow=1end

flow=0Rend

end<bjendL

endRend(start,end)

প্রতিটি পদক্ষেপে একই অনুরণন প্রয়োগ করুন।

জটিলতা

প্রতিটি গর্তের উপরের প্রবাহকে ও (এন) এ পূর্বরূপে গণনা করা যায় এবং প্রতিটি স্ক্যানে পুনরায় ব্যবহার করা যেতে পারে।

লুপগুলি হ'ল:

for start = 1 to N
  for end = 1 to N
    for move = 1 to N
      make a move (fix a peg and update flows)
      check if another move can be done using flow     

O(N3)

কোড

এটি অ্যালগরিদমের কার্যকরী জাভা বাস্তবায়ন:

public class StrangeSort {
    static int PEG = 0xffffff, HOLE = 0x0;
    static int M = 0, N = 0, choices = 0, aux = 0, end;
    static int problem[][], moves[], edgeflow[], field[];    
    boolean is_hole(int x) { return x == HOLE; }
    boolean is_peg(int x) { return x == PEG; }
    boolean is_ele(int x) { return ! is_peg(x) && ! is_hole(x); };
    int []cp(int src[]) { // copy an array
        int res[] = new int[src.length];
        System.arraycopy(src, 0, res, 0, res.length);
        return res;
    }    
    /* find the first element on the left (dir=-1) right (dir=1) */
    int find(int pos, int dir, int nm) {
        pos += dir;
        while (pos >= 1 && pos <= M ) {
            int x = field[pos];
            if ( is_peg(x) || (pos == end && nm < N-1) ) return 0;
            if ( is_ele(x) ) return pos;
            pos += dir;
        }
        return 0;
    }
    void build_edges() {
        edgeflow = new int[M+1];
        for (int i = 1; i<=M; i++) {
            int start = i;
            int b = field[start];
            if (! is_ele(b)) continue;
            if (i == end) continue;
            int dir = (b > start)? 1 : -1;
            start += dir;
            while (start != b) { edgeflow[start] += dir; start += dir; }
        }
    }
    boolean rec_solve(int start, int nm) {
        boolean f;
        int j;
        int b = field[start];
        moves[nm++] = b;
        if (nm == N) return true;
        //System.out.println("Processing: " + start + "->" + field[start]);        
        field[start] = HOLE;
        field[b] = PEG;
        int dir = (b > start)? 1 : -1;
        int i = start + dir;
        while (i != b) { edgeflow[i] -= dir; i += dir; } // clear edge                
        int flow = edgeflow[b];
        if (Math.abs(flow) > 2) return false;
        if (end > b) {
            switch (flow) {
            case 1 :                    
                j = find(b,-1,nm);
                if (j <= 0) return false;
                return rec_solve(j,nm);
            case -1 :
                return false;
            case 0 :          
                j = find(b,1,nm);
                if (j <= 0) return false;
                return rec_solve(j,nm);
            }        
        } else {
            switch (flow) {
            case -1 :                    
                j = find(b,1,nm);
                if (j <= 0) return false;
                return rec_solve(j,nm);
            case 1 :
                return false;
            case 0 :          
                j = find(b,-1,nm);
                if (j <= 0) return false;
                return rec_solve(j,nm);
            }            
        }
        return false;
    }
    boolean solve(int demo[][]) {
        N = demo.length;
        for (int i = 0; i < N; i++)
            M = Math.max(M, Math.max(demo[i][0], demo[i][1]));
        moves = new int[N];
        edgeflow = new int[M+1];
        field = new int[M+1];
        problem = demo;        
        for (int i = 0; i < problem.length; i++) {
            int a = problem[i][0];
            int b = problem[i][1];
            if ( a < 1 || b < 1 || a > M || b > M || ! is_hole(field[a]) || ! is_hole(field[b])) {
                System.out.println("Bad input pair (" + a + "," + b + ")");
                return false;
            }
            field[a] = b;
        }
        for (int i = 1; i <= M; i++) {
            end = i;
            build_edges();
            if (!is_ele(field[i])) continue;
            for (int j = 1; j <= M; j++) {
                if (!is_ele(field[j])) continue;
                if (i==j) continue;
                int tmp_edgeflow[] = cp(edgeflow);
                int tmp_field[] = cp(field);
                choices = 0;
                //System.out.println("START: " + j + " " + " END: " + i);
                if (rec_solve(j, 0)) {
                    return true;
                }
                edgeflow = tmp_edgeflow;
                field = tmp_field;
            }
        }
        return false;
    }
    void init(int demo[][]) {

    }
    public static void main(String args[]) {
        /**** THE INPUT ********/        

        int demo[][] =  {{4,2},{5,7},{6,3},{10,12},{11,1},{13,8},{14,9}};

        /***********************/        
        String r = "";
        StrangeSort sorter = new StrangeSort();       
        if (sorter.solve(demo)) {
            for (int i = 0; i < N; i++) { // print it in clear text
                int b =  moves[i];
                for (int j = 0; j < demo.length; j++)
                    if (demo[j][1] == b)
                        r += ((i>0)? " -> " : "") + "(" + demo[j][0] + "," + demo[j][1] + ")";
            }             
            r = "SOLUTION: "+r;
        }
        else
            r = "NO SOLUTIONS";
        System.out.println(r);
    }    
}

(a,b)bO(logn)

@ এমজেকিএক্সএক্সএক্সএক্সএক্স ... জাভা অ্যালগরিদমের সাথে মেলে পুরো উত্তরটি আমি আবারও লিখেছিলাম ...
মারজিও ডি বায়াসি

@ এমজেকিএক্সএক্সএক্সএক্সএক্স ... ঠিক আছে, শেষ পর্যন্ত আমি পেয়েছি ... :-)
মারজিও ডি বিয়াসি

2
(a,b)bb(an,bn)ban। প্রতিটি প্রান্তের পরে চলার জন্য কেবলমাত্র একটি সম্ভাব্য দিক রয়েছে, যেহেতু একটি বিজোড় (এমনকি) সংখ্যক জাম্প আপনাকে প্রথমে যে বিপরীতে (একই) দিকে গিয়েছিল আপনাকে ছেড়ে দেবে। সুতরাং প্রান্তগুলি শুরু এবং শেষের প্রতিটি পছন্দ পরীক্ষা করে বহুপক্ষীয় সময়ে করা যেতে পারে।
এমজেকিউএক্সএক্সএক্সএক্সএক্সএক্স

1
এটি একটি সুন্দর অ্যালগরিদম। সর্বশেষ পদক্ষেপটি ঠিক করার আগে কখনও আমার কাছে আসেনি। গৌণ পয়েন্ট: (1) এমজেকিউএক্সএক্সএক্সএক্সএক্সএক্স যেমন লিখেছেন, শেষটি অবশ্যই a_k হতে হবে। অন্যথায় "শেষ> বি_জ" শর্তটি ভুল। (২) হয় "প্রবাহ" এর সংজ্ঞাটিকে এড়িয়ে যাওয়া করতে হবে, বা বি এবং সি ক্ষেত্রে পরিবর্তন করতে হবে।
Tsuyoshi Ito

10

এটি কোনও সমাধান নয়, তবে এমন একটি সংস্কার যা অদলবদল এবং বাছাইয়ের ক্রিয়াকলাপের সুস্পষ্ট উল্লেখ এড়ানো যায়। ফাইলের নাম এবং তাদের অদল-বদল করা সংস্করণগুলির সম্পূর্ণ সংযুক্ত তালিকাটি বাছাই করে শুরু করুন এবং সেই তালিকাতে প্রতিটি ফাইলের নামটি সূচী দিয়ে সনাক্ত করুন। তারপরে দুটি ফাইলই প্রতিবেশী হয় যদি তাদের মধ্যে থাকা সমস্ত পুরানো ফাইলের নাম ইতিমধ্যে ধ্বংস হয়ে যায়, এবং যদি তাদের মধ্যে নতুন ফাইলের নামগুলি এখনও তৈরি না হয়। সংশোধিত সমস্যাটি নিম্নরূপ:

n(a,b)a,b{1,2,,2n}(a1,b1),(a2,b2),...,(an,bn)

  • ajbiai+1ji
  • bjbiai+1ji+1

2
+1 টি। সমতুল্য সমস্যাটি বর্ণনা করার এটি একটি খুব সহজ উপায়। কেবল একটি স্পষ্টতা: প্রান্তগুলি (ক, খ) নির্দেশিত (এই অর্থে যে প্রান্ত (ক, খ) এবং প্রান্ত (খ, ক) এর আলাদা অর্থ রয়েছে)।
সোসোশি ইটো

@ শুয়োশি: ধন্যবাদ; আমি 'নির্দেশিত' বলতে সম্পাদনা করেছি।
mjqxxxx

bacabc

@Oleksandr: এখানে মানে হলো "। <একটি পারেন একটি <b <C অথবা C, <b" "খ 'ও' সি মধ্যে হল"
Tsuyoshi ইটো
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.