কিছু বিট এবং গণনা মুছুন


26

2^nদৈর্ঘ্য nএবং অনুমানের সমস্ত বাইনারি স্ট্রিং বিবেচনা করুন n > 2b < n/2দৈর্ঘ্যের স্ট্রিং বাকি রেখে, আপনাকে বাইনারি স্ট্রিংগুলির প্রতিটি থেকে হুবহু বিট মুছার অনুমতি দেওয়া হয় n-b। আলাদা আলাদা স্ট্রিংয়ের সংখ্যা নির্ভর করে আপনি কোন বিট মুছবেন তার উপর। আপনার লক্ষ্য ধরে নেওয়া সম্ভব যতগুলি সম্ভব অবশিষ্ট কয়েকটি ভিন্ন স্ট্রিং ছেড়ে যাওয়া, এই চ্যালেঞ্জটি হল আপনি কতগুলি ফাংশন হিসাবে ছেড়ে যেতে পারবেন তা গণনা করার জন্য কোড লেখা n

উদাহরণ, n=3এবং b = 1। আপনি কেবল দুটি স্ট্রিং রেখে যেতে পারেন 11এবং 00

জন্য n=9এবং b = 1,2,3,4আমাদের আছে70,18,6,2

জন্য n=8এবং b = 1,2,3আমাদের আছে40,10,4

জন্য n=7এবং b = 1,2,3আমাদের আছে20,6,2

জন্য n=6এবং b = 1,2আমাদের আছে12,4

জন্য n=5এবং b = 1,2আমাদের আছে6,2

এই প্রশ্নটি মূলত 2014 সালে এমও- তে ভিন্ন রূপে আমার দ্বারা উত্থাপিত হয়েছিল ।

ইনপুট এবং আউটপুট

আপনার কোডটি শুরুতে এবং বাড়ার nপ্রতিটি মানের জন্য একটি পূর্ণসংখ্যার এবং একক পূর্ণসংখ্যার আউটপুট নেওয়া উচিত ।bb = 0

স্কোর

আপনার স্কোর সবচেয়ে বড় nযার জন্য আপনার কোডটি b < n/2আমার লিনাক্স ভিত্তিক পিসিতে এক মিনিটের মধ্যে সমস্তের জন্য পূর্ণ করে। টাই বিরতির ক্ষেত্রে, bআপনার কোডটি সবচেয়ে বেশি সম্মিলিত বৃহত্তম nজয়ের জন্য পায় । যে নির্ণায়ক খুব, বৃহত্তম মানের জন্য দ্রুততম কোডের উপর টাই বিরতি ক্ষেত্রে nএবং bসিদ্ধান্ত নেয়। যদি সময়গুলি একে অপরের দু'এক সেকেন্ডের মধ্যে হয় তবে প্রথম পোস্ট করা উত্তরটি জয়ী হয়।

ভাষা ও গ্রন্থাগার

আপনার পছন্দ মতো লাইব্রেরির যে কোনও ভাষা ব্যবহার করতে পারেন। যেহেতু আমাকে আপনার কোডটি চালাতে হবে, এটি বিনামূল্যে (বিয়ারের মতো) এবং লিনাক্সে কাজ করাতে সহায়তা করবে।


আমি b > 0অতিরিক্ত ইনপুট-প্রয়োজন হিসাবে ধরে নিচ্ছি ? অথবা would n=3এবং b=0কেবল আউটপুট 2^nফলে?
কেভিন ক্রুইজসেন

@ কেভিন ক্রুজসেন এটি 2^nপ্রকৃতপক্ষে আউটপুট করা উচিত ।
আনুশ

এছাড়াও, আপনি বলেন ইনপুটটি একক nএবং একক b, তবে স্কোরটি সবচেয়ে বড় nযার জন্য কোডটি b < n/2এক মিনিটের মধ্যে সমস্ত সম্পূর্ণ করে । সেক্ষেত্রে একটি একক ইনপুট রাখলে কী ভাল হয় না nএবং এর জন্য সমস্ত ফলাফল আউটপুট দেয় 0 <= b < n/2? অথবা আমাদের দুটি প্রোগ্রাম / ফাংশন সরবরাহ করা উচিত: একটি দুটি ইনপুট গ্রহণ nএবং bএবং একটি কেবল ইনপুট গ্রহণ করে nএবং পরিসীমাতে সমস্ত ফলাফল আউটপুট করে 0 <= b < n/2?
কেভিন ক্রুইজসেন

2
ঠিক আছে, আমি ইতিমধ্যে আপনার চ্যালেঞ্জটিকে উড়িয়ে দিয়েছি, সুতরাং এটি আর করতে পারব না। :) যদিও এই দক্ষতার সাথে কীভাবে গণনা করা যায় তা সম্পর্কে আমার কোনও ধারণা নেই (দক্ষ ও অ্যালগরিদমগুলি এমন কিছু ছিল যা আমি সবসময় খারাপ ছিলাম .. এবং আইটি কলেজের কয়েকটি বিষয়গুলির মধ্যে একটিতে আমাকে কয়েকবার পুনরায় করতে হয়েছিল) তবে এটি মনে হয় না একটি খুব আকর্ষণীয় চ্যালেঞ্জ। লোকেরা কী উত্তর নিয়ে আসে তা দেখার জন্য আমি আগ্রহী।
কেভিন ক্রুইজসেন

2
কোন কাজের উদাহরণ আছে? উভয়ই নির্ভুলতার দিক থেকে শুরু করার জন্য এটি ভাল জায়গা হবে তবে গতির তুলনা করার জন্যও।
সর্বোচ্চ

উত্তর:


6

পাইথন ২.7 / গুড়োবি এন = ৯

এই সমাধানটি বুলিয়ান মিশ্রিত-পূর্ণসংখ্যার সমস্যাগুলির (এমআইপি) জন্য গুরুবির আইএলপি সলভারটির খুব সোজা ব্যবহার।

একমাত্র কৌশলটি হ'ল সমস্যার আকারকে অর্ধেক করার জন্য 1 এর পরিপূরক প্রতিসাম্য গ্রহণ করা।

গুরোবি এলএলসির সীমিত সময় "ফ্রি" লাইসেন্স ব্যবহার করে আমরা 2000 টি সীমাবদ্ধ সীমাবদ্ধ, তবে 10 ডেল 1 সমাধান করা আমার ল্যাপটপে যাই হোক 60 সেকেন্ড টাইম-লিমিটের বাইরে।

from gurobipy import *
from itertools import combinations

def mincover(n,d):
    bs = pow(2,n-1-d)
    m = Model()
    m.Params.outputFlag = 0
    b = {}
    for i in range(bs):
      b[i] = m.addVar(vtype=GRB.BINARY, name="b%d" % i)
    m.update()
    for row in range(pow(2,n-1)):
      x = {}
      for i in combinations(range(n), n-d):
        v = 0
        for j in range(n-d):
          if row & pow(2,i[j]):
            v += pow(2,j)
        if v >= bs:
          v = 2*bs-1-v
        x[v] = 1
      m.addConstr(quicksum(b[i] for i in x.keys()) >= 1)
    m.setObjective(quicksum(b[i] for i in range(bs) ), GRB.MINIMIZE)
    m.optimize()
    return int(round(2*m.objVal,0))

for n in range(4,10):
    for d in range((n//2)+1):
        print n, d, mincover(n,d)

আপডেট + সিআরআর: 10,2 এর সর্বোত্তম সমাধান আকার 31 রয়েছে (উদাহরণস্বরূপ) গুরুবি 30 মাপের কোনও প্রতিসাম্যিক সমাধান দেখায় না (সমস্যাটি অক্ষম হয়) .. [9.5 ঘন্টা রানটাইমের পরে অসমমিতিক সম্ভাব্যতা দেখানোর আমার প্রচেষ্টা অসম্পূর্ণ রয়ে গেছে] যেমন বিট পূর্ণসংখ্যার নিদর্শন 0 7 13 14 25 28 35 36 49 56 63 64 95 106 118 128 147 159 170 182 195 196 200 207 225 231 240 243 249 252 255বা0 7 13 14 19 25 28 35 36 49 56 63 64 95 106 118 128 159 170 182 195 196 200 207 225 231 240 243 249 252 255


আপনি "দ্রুততম দাবিযুক্ত অনন্ত অনুগ্রহ" রেকর্ডটি ভঙ্গ করেছেন?
ব্যবহারকারী 202729

আমি এখানে কোন অনুগ্রহ দেখছি না, আপনার মানে কি?
জয়প্রিচ

@ ব্যবহারকারী 202729 হ্যাঁ .. আমি এটি খুব কম সেট করেছি। আমার এটি এন = 10 :) এ সেট করা উচিত ছিল
আনুশ

আসলে এটি n = 9 এ সমাধান করা খুব সহজ জিনিস নয়। এ কারণেই ওপি একটি বিদ্যমান লাইব্রেরি ব্যবহার করে (যা খনি হিসাবে লেখা একটি সমাধানের চেয়ে ভাল বলে মনে হয়)।
ব্যবহারকারী 202729

1
ধন্যবাদ @ খ্রিস্টিয়ানসিভারস আমি এমওএর দাবি দেখতে পাচ্ছি যে 10,2 এর মধ্যে কেবলমাত্র অসম্পূর্ণ অপটিমা রয়েছে যা আমি খণ্ডন করতে পারি না বা যাচাই করতে পারি না। যদি আমি প্রতিসম অনুমান শর্টকাটটি সরিয়ে ফেলি যা এন = 9 পর্যন্ত কাজ করে তবে এটি প্রমাণিত হয় যে গুরুবি এখনও প্রয়োজনীয় সময়ে এন = 9 পর্যন্ত সমাধান করতে পারে।
জয়প্রিচ

3

সি ++, এন = 6

কিছু ছোট অপ্টিমাইজেশান সহ ব্রুট ফোর্স।

#include<cassert>
#include<iostream>
#include<vector>

// ===========
/** Helper struct to print binary representation.
`std::cout<<bin(str,len)` prints (str:len) == the bitstring 
represented by last (len) bits of (str).
*/
struct bin{
    int str,len;
    bin(int str,int len):str(str),len(len){}
};
std::ostream& operator<<(std::ostream& str,bin a){
    if(a.len)
        return str<<bin(a.str>>1,a.len-1)<<char('0'+(a.str&1));
    else if(a.str)
        return str<<"...";
    else
        return str;
}
// ===========

/// A patten of (len) bits of ones.
int constexpr pat1(int len){
    return (1<<len)-1;
}

// TODO benchmark: make (res) global variable?

/**Append all distinct (subseqs+(sfx:sfxlen)) of (str:len) 
with length (sublen) to (res).
*/
void subseqs_(
    int str,int len,int sublen,
    int sfx,int sfxlen,
    std::vector<int>& res
){
    // std::cout<<"subseqs_ : str = "<<bin(str,len)<<", "
    // "sublen = "<<sublen<<", sfx = "<<bin(sfx,sfxlen)<<'\n';

    assert(len>=0);

    if(sublen==0){ // todo remove some branches can improve perf?
        res.push_back(sfx);
        return;
    }else if(sublen==len){
        res.push_back(str<<sfxlen|sfx);
        return;
    }else if(sublen>len){
        return;
    }

    if(str==0){
        res.push_back(sfx);
        return;
    }

    int nTrail0=0;
    for(int ncut;str&&nTrail0<sublen;

        ++nTrail0,
        ncut=__builtin_ctz(~str)+1, // cut away a bit'0' of str
        // plus some '1' bits
        str>>=ncut,
        len-=ncut
    ){
        ncut=__builtin_ctz(str)+1; // cut away a bit'1' of str
        subseqs_(str>>ncut,len-ncut,sublen-nTrail0-1,
            sfx|1<<(sfxlen+nTrail0),sfxlen+nTrail0+1,
            res
        ); // (sublen+sfxlen) is const. TODO global var?
    }

    if(nTrail0+len>=sublen) // this cannot happen if len<0
        res.push_back(sfx);
}

std::vector<int> subseqs(int str,int len,int sublen){
    assert(sublen<=len);
    std::vector<int> res;
    if(__builtin_popcount(str)*2>len){ // too many '1's, flip [todo benchmark]
        subseqs_(pat1(len)^str,len,sublen,0,0,res);
        int const p1sublen=pat1(sublen);
        for(int& r:res)r^=p1sublen;
    }else{
        subseqs_(str,len,sublen,0,0,res);
    }
    return res;
}

// ==========

/** Append all distinct (supersequences+(sfx:sfxlen)) of (str:len)
with length (suplen) to (res).
Define (a) to be a "supersequence" of (b) iff (b) is a subsequence of (a).
*/
void supseqs_(
    int str,int len,int suplen,
    int sfx,int sfxlen,
    std::vector<int>& res
){
    assert(suplen>=len);

    if(suplen==0){
        res.push_back(sfx);
        return;
    }else if(suplen==len){
        res.push_back(str<<sfxlen|sfx);
        return;
    }

    int nTrail0; // of (str)
    if(str==0){
        res.push_back(sfx);
        // it's possible that the supersequence is '0000..00'
        nTrail0=len;
    }else{
        // str != 0 -> str contains a '1' bit ->
        // supersequence cannot be '0000..00'
        nTrail0=__builtin_ctz(str);
    }
    // todo try `nTrail0=__builtin_ctz(str|1<<len)`, eliminates a branch
    // and conditional statement

    for(int nsupTrail0=0;nsupTrail0<nTrail0;++nsupTrail0){
        // (nsupTrail0+1) last bits of supersequence matches with 
        // nsupTrail0 last bits of str.
        supseqs_(str>>nsupTrail0,len-nsupTrail0,suplen-1-nsupTrail0,
            sfx|1<<(nsupTrail0+sfxlen),sfxlen+nsupTrail0+1,
            res);
    }

    int const strMatch=str?nTrail0+1:len; 
    // either '1000..00' or (in case str is '0000..00') the whole (str)

    for(int nsupTrail0=suplen+strMatch-len;nsupTrail0-->nTrail0;){
        // because (len-strMatch)<=(suplen-1-nsupTrail0),
        // (nsupTrail0<suplen+strMatch-len).

        // (nsupTrail0+1) last bits of supersequence matches with
        // (strMatch) last bits of str.
        supseqs_(str>>strMatch,len-strMatch,suplen-1-nsupTrail0,
            sfx|1<<(nsupTrail0+sfxlen),sfxlen+nsupTrail0+1,
            res);
    }

    // todo try pulling constants out of loops
}

// ==========

int n,b;
std::vector<char> done;
unsigned min_undone=0;

int result;
void backtrack(int nchoice){
    assert(!done[min_undone]);
    ++nchoice;
    std::vector<int> supers_s;
    for(int s:subseqs(min_undone,n,n-b)){
        // obviously (s) is not chosen. Try choosing (s)
        supers_s.clear();
        supseqs_(s,n-b,n,0,0,supers_s);
        for(unsigned i=0;i<supers_s.size();){
            int& x=supers_s[i];
            if(!done[x]){
                done[x]=true;
                ++i;
            }else{
                x=supers_s.back();
                supers_s.pop_back();
            }
        }

        unsigned old_min_undone=min_undone;
        while(true){
            if(min_undone==done.size()){
                // found !!!!
                result=std::min(result,nchoice);
                goto label1;
            }
            if(not done[min_undone])
                break;
            ++min_undone;
        }
        if(nchoice==result){
            // backtrack more will only give worse result
            goto label1;
        }

        // note that nchoice is already incremented
        backtrack(nchoice);

        label1: // undoes the effect of (above)
        for(int x:supers_s)
            done[x]=false;
        min_undone=old_min_undone;
    }
}

int main(){
    std::cin>>n>>b;

    done.resize(1<<n,0);
    result=1<<(n-b); // the actual result must be less than that

    backtrack(0);
    std::cout<<result<<'\n';
}

স্থানীয়ভাবে চালান:

[user202729@archlinux golf]$ g++ -std=c++17 -O2 delbits.cpp -o delbits
[user202729@archlinux golf]$ time for i in $(seq 1 3); do ./delbits <<< "6 $i"; done
12
4
2

real    0m0.567s
user    0m0.562s
sys     0m0.003s
[user202729@archlinux golf]$ time ./delbits <<< '7 1'
^C

real    4m7.928s
user    4m7.388s
sys     0m0.173s
[user202729@archlinux golf]$ time for i in $(seq 2 3); do ./delbits <<< "7 $i"; done
6
2

real    0m0.040s
user    0m0.031s
sys     0m0.009s

1
বেশিরভাগই অন্যদের কোডটি আমার থেকে দ্রুততর পোস্ট করতে উত্সাহিত করার জন্য।
ব্যবহারকারী 202729

দয়া করে? ... (দ্রষ্টব্য: এটি একটি সেট কভার সমস্যার একটি উদাহরণ।)
ব্যবহারকারী 202729

1
আমি এটার উপর কাজ করছি. আমি এটি করার কোনও স্মার্ট উপায় নিয়ে আসতে পারি না। অন্য কেউ যদি কোনও উত্তর পোস্ট না করে, আমি আমার আপ রাখব যা এখন পর্যন্ত কেবল এন = 4 এর বেশি যেতে পারে।
মাইপিটলিয়ন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.