আনুমানিক পারস্পরিক সম্পর্কের সন্ধান করা


14

Sদৈর্ঘ্যের একটি বাইনারি স্ট্রিং বিবেচনা করুন n। থেকে ইন্ডেক্স 1, আমরা গনা করতে Hamming দূরত্বের মধ্যে S[1..i+1]এবং S[n-i..n]সব জন্য iথেকে অনুক্রমে 0করতে n-1। সমান দৈর্ঘ্যের দুটি স্ট্রিংয়ের মধ্যে হামিং দূরত্বটি এমন অবস্থানগুলির সংখ্যা যা সম্পর্কিত চিহ্নগুলি পৃথক। উদাহরণ স্বরূপ,

S = 01010

দেয়

[0, 2, 0, 4, 0].

এর কারণ 0ম্যাচ 0, 01করতে Hamming দূরত্ব দুই 10, 010ম্যাচ 010, 0101করতে Hamming দূরত্ব চার রয়েছে 1010 এবং পরিশেষে 01010নিজেই সাথে মেলে।

তবে কেবলমাত্র আউটপুটগুলিতে আমরা আগ্রহী যেখানে হামিংয়ের দূরত্ব সর্বাধিক 1। সুতরাং এই কার্যক্রমে আমরা একটি প্রতিবেদন করব Yযদি হামিং দূরত্ব সর্বাধিক এক এবং Nঅন্যথায় হয়। সুতরাং উপরে আমাদের উদাহরণে আমরা পেতে হবে

[Y, N, Y, N, Y]

দৈর্ঘ্যের বিভিন্ন সম্ভাব্য বিট স্ট্রিংগুলিতে পুনরাবৃত্তি করার সময় s এবং s f(n)এর পৃথক অ্যারেগুলির সংখ্যা হতে সংজ্ঞায়িত করুন ।YN2^nSn

কার্য

nশুরু থেকে বাড়ানোর জন্য 1, আপনার কোডটি আউটপুট করা উচিত f(n)

উদাহরণ উত্তর

কারণ n = 1..24, সঠিক উত্তরগুলি হ'ল:

1, 1, 2, 4, 6, 8, 14, 18, 27, 36, 52, 65, 93, 113, 150, 188, 241, 279, 377, 427, 540, 632, 768, 870

স্কোরিং

আপনার কোডটি n = 1প্রতিটি পরিবর্তে উত্তর দেওয়া থেকে পুনরুক্ত হওয়া উচিত n। আমি পুরো রান সময়টি করব, দুই মিনিট পরে এটি হত্যা করব।

আপনার স্কোর nসেই সময়ে আপনি সবচেয়ে বেশি পাবেন।

টাইয়ের ক্ষেত্রে প্রথম উত্তরটি জয়ী হয়।

আমার কোডটি কোথায় পরীক্ষা করা হবে?

আমি আপনার কোডটি সাইগউইনের অধীনে আমার (কিছুটা পুরানো) উইন্ডোজ 7 ল্যাপটপে চালাব। ফলস্বরূপ, দয়া করে এটিকে সহজ করে তুলতে সহায়তা করতে পারেন কোনও সহায়তা দিন।

আমার ল্যাপটপে 8 গিগাবাইট র‌্যাম এবং 2 টি কোর এবং 4 টি থ্রেড সহ একটি ইন্টেল i7 5600U@2.6 গিগাহার্টজ (ব্রডওয়েল) সিপিইউ রয়েছে। নির্দেশিকা সেটটিতে এসএসই 4.2, এভিএক্স, এভিএক্স 2, এফএমএ 3 এবং টিএসএক্স অন্তর্ভুক্ত রয়েছে।

প্রতি ভাষা প্রতি নেতৃস্থানীয় এন্ট্রি

  • এন = 40 মধ্যে মরচে CryptoMiniSat, অ্যান্ডার্স Kaseorg দ্বারা ব্যবহার করে। (ভিবক্সের অধীনে লুবুন্টু অতিথি ভিএম-এ)
  • খ্রিস্টান সেভিয়ার্স দ্বারা বুডিডি লাইব্রেরি ব্যবহার করে সি ++এন = 35 । (ভিবক্সের অধীনে লুবুন্টু অতিথি ভিএম-এ)
  • এন = 34 মধ্যে Clingo অ্যান্ডার্স Kaseorg দ্বারা। (ভিবক্সের অধীনে লুবুন্টু অতিথি ভিএম-এ)
  • এন = 31 মধ্যে মরচে অ্যান্ডার্স Kaseorg দ্বারা।
  • এন = 29 মধ্যে Clojure NikoNyrh দ্বারা।
  • এন = 29 মধ্যে সি bartavelle দ্বারা।
  • এন = 27 মধ্যে Haskell, bartavelle দ্বারা
  • এন = 24 মধ্যে পরীর / জিপি alephalpha দ্বারা।
  • এন = 22 মধ্যে পাইথন 2+ pypy আমার দ্বারা।
  • এন = 21 মধ্যে ম্যাথামেটিকাল alephalpha দ্বারা। (স্ব-প্রতিবেদিত)

ভবিষ্যত উদ্যান

আমি এখন আমার মেশিনে দুই মিনিটের মধ্যে এন = 80 পর্যন্ত উঠে যে কোনও উত্তরের জন্য 200 পয়েন্টের অনুদান দেব will


আপনি কি এমন এমন কৌশল সম্পর্কে জানেন যা কোনও ব্যক্তিকে একটি নিষ্পাপ ব্রুটে বলের চেয়ে দ্রুত অ্যালগরিদম খুঁজে পেতে দেয়? যদি এই চ্যালেঞ্জটি না হয় তবে "দয়া করে এটি x86 এ প্রয়োগ করুন" (বা সম্ভবত আমরা যদি আপনার জিপিইউ জানি ...)।
জোনাথন অ্যালান

@ জোনাথান অ্যালান নিশ্চয়ই খুব নিখুঁত পদ্ধতির গতি বাড়ানো সম্ভব। ঠিক কতটা দ্রুত আপনি পেতে পারেন আমি নিশ্চিত নই। মজার বিষয় হল, আমরা যদি প্রশ্নটি পরিবর্তন করেছিলাম যাতে হামিংয়ের দূরত্ব সর্বাধিক 0 এবং কোনও এন হয় তবে আপনি একটি ওয়াই পান, তবে সেখানে একটি বদ্ধ ফর্মুলা রয়েছে।

@ ল্যাম্বিক আমরা সিপিইউ সময় বা বাস্তব সময় পরিমাপ করি?
flawr

@ ফ্লোয়ার আমি বাস্তব সময়টি পরিমাপ করছি তবে এটি কয়েকবার চালিয়ে যাচ্ছি এবং বিজোড়তা দূর করতে সর্বনিম্ন সময় নিচ্ছি।

উত্তর:


9

মরিচা + ক্রিপ্টোমিনিস্যাট , এন ≈ 41

src/main.rs

extern crate cryptominisat;
extern crate itertools;

use std::iter::once;
use cryptominisat::{Lbool, Lit, Solver};
use itertools::Itertools;

fn make_solver(n: usize) -> (Solver, Vec<Lit>) {
    let mut solver = Solver::new();
    let s: Vec<Lit> = (1..n).map(|_| solver.new_var()).collect();
    let d: Vec<Vec<Lit>> = (1..n - 1)
        .map(|k| {
                 (0..n - k)
                     .map(|i| (if i == 0 { s[k - 1] } else { solver.new_var() }))
                     .collect()
             })
        .collect();
    let a: Vec<Lit> = (1..n - 1).map(|_| solver.new_var()).collect();
    for k in 1..n - 1 {
        for i in 1..n - k {
            solver.add_xor_literal_clause(&[s[i - 1], s[k + i - 1], d[k - 1][i]], true);
        }
        for t in (0..n - k).combinations(2) {
            solver.add_clause(&t.iter()
                                   .map(|&i| d[k - 1][i])
                                   .chain(once(!a[k - 1]))
                                   .collect::<Vec<_>>()
                                   [..]);
        }
        for t in (0..n - k).combinations(n - k - 1) {
            solver.add_clause(&t.iter()
                                   .map(|&i| !d[k - 1][i])
                                   .chain(once(a[k - 1]))
                                   .collect::<Vec<_>>()
                                   [..]);
        }
    }
    (solver, a)
}

fn search(n: usize,
          solver: &mut Solver,
          a: &Vec<Lit>,
          assumptions: &mut Vec<Lit>,
          k: usize)
          -> usize {
    match solver.solve_with_assumptions(assumptions) {
        Lbool::True => search_sat(n, solver, a, assumptions, k),
        Lbool::False => 0,
        Lbool::Undef => panic!(),
    }
}

fn search_sat(n: usize,
              solver: &mut Solver,
              a: &Vec<Lit>,
              assumptions: &mut Vec<Lit>,
              k: usize)
              -> usize {
    if k >= n - 1 {
        1
    } else {
        let s = solver.is_true(a[k - 1]);
        assumptions.push(if s { a[k - 1] } else { !a[k - 1] });
        let c = search_sat(n, solver, a, assumptions, k + 1);
        assumptions.pop();
        assumptions.push(if s { !a[k - 1] } else { a[k - 1] });
        let c1 = search(n, solver, a, assumptions, k + 1);
        assumptions.pop();
        c + c1
    }
}

fn f(n: usize) -> usize {
    let (mut solver, proj) = make_solver(n);
    search(n, &mut solver, &proj, &mut vec![], 1)
}

fn main() {
    for n in 1.. {
        println!("{}: {}", n, f(n));
    }
}

Cargo.toml

[package]
name = "correlations-cms"
version = "0.1.0"
authors = ["Anders Kaseorg <andersk@mit.edu>"]

[dependencies]
cryptominisat = "5.0.1"
itertools = "0.6.0"

কিভাবে এটা কাজ করে

ওয়াই / এন অ্যারের উপসর্গগুলিতে সমস্ত আংশিক কার্যভারের গাছের মাধ্যমে এটি পুনরাবৃত্ত অনুসন্ধান করবে, বর্তমান আংশিক কার্যনির্বাহী ধারাবাহিক কিনা তা অনুসন্ধানের জন্য প্রতিটি পদক্ষেপে স্যাট সলভার ব্যবহার করে এবং অনুসন্ধানটি ছাঁটাই করে না। ক্রিপ্টোমিনিস্যাট এই এক্সওর ক্লজের জন্য বিশেষ অনুকূলকরণের কারণে এই কাজের জন্য সঠিক স্যাট সলভার।

বাধা তিন পরিবার

এস আইএস কে + আইডি কি , 1 ≤ কেএন - 2, 0 ≤ আই ≤ এন - কে এর জন্য ;
ডি কি 1ডি কি 2 ∨ ¬ কে , 1 ≤ কেn - 2, 0 ≤ i 1 < i 2n - কে জন্য ;
¬ ডি কি 1 ∨ ⋯ ∨ ¬ ডি কি এন - কে - 1কে , 1 ≤ কেn - 2, 0 ≤ i 1 <⋯ < i n - কে - 1n - কে জন্য ;

এটি ব্যতীত, অপ্টিমাইজেশন হিসাবে, এস 0 টি মিথ্যা হতে বাধ্য করা হয়, যাতে ডি কে 0 কেবল এস কে এর সমান হয় ।


2
ওহুহুও! :)

আমি এখনও এটি উইন্ডোজে (সাইগউইন + জিসিসি ব্যবহার করে) সংকলনের চেষ্টা করছি। আমি ক্রিপ্টোমিনিস্যাট ক্লোন করে এটি সংকলন করেছি। তবে আমি এখনও জং কোডটি সংকলন করতে জানি না। যখন আমি কি cargo buildআমি পেতে--- stderr CMake Error: Could not create named generator Visual Studio 14 2015 Win64

2
@ রাহনেমা 1 ধন্যবাদ, তবে এটি মনে হচ্ছে সমস্যাটি ক্রিপ্টোমিনিসেট ক্র্যাটে এম্বেড করা সি ++ লাইব্রেরির সিএমকে বিল্ড সিস্টেমের সাথে, রাস্ট নিজেই নয়।
অ্যান্ডারস ক্যাসরগ

1
@ লেম্বিক আমি সেই পেস্ট থেকে একটি 404 পাচ্ছি।
মেগো

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

9

মরিচা, n ≈ 30 বা 31 বা 32

আমার ল্যাপটপ (দুই কোর, i5-6200U) -এ, মধ্যে দিয়ে যেতে এন = 1, ..., 31 53 সেকেন্ড, ব্যবহার মেমরি 2.5 GiB সম্পর্কে, বা এর মাধ্যমে এন = 1, ..., 32 105 সেকেন্ড, 5 GiB সম্পর্কে ব্যবহার স্মৃতি। সংকলন cargo build --releaseএবং চালান target/release/correlations

src/main.rs

extern crate rayon;

type S = u32;
const S_BITS: u32 = 32;

fn cat(mut a: Vec<S>, mut b: Vec<S>) -> Vec<S> {
    if a.capacity() >= b.capacity() {
        a.append(&mut b);
        a
    } else {
        b.append(&mut a);
        b
    }
}

fn search(n: u32, i: u32, ss: Vec<S>) -> u32 {
    if ss.is_empty() {
        0
    } else if 2 * i + 1 > n {
        search_end(n, i, ss)
    } else if 2 * i + 1 == n {
        search2(n, i, ss.into_iter().flat_map(|s| vec![s, s | 1 << i]))
    } else {
        search2(n,
                i,
                ss.into_iter()
                    .flat_map(|s| {
                                  vec![s,
                                       s | 1 << i,
                                       s | 1 << n - i - 1,
                                       s | 1 << i | 1 << n - i - 1]
                              }))
    }
}

fn search2<SS: Iterator<Item = S>>(n: u32, i: u32, ss: SS) -> u32 {
    let (shift, mask) = (n - i - 1, !(!(0 as S) << i + 1));
    let close = |s: S| {
        let x = (s ^ s >> shift) & mask;
        x & x.wrapping_sub(1) == 0
    };
    let (ssy, ssn) = ss.partition(|&s| close(s));
    let (cy, cn) = rayon::join(|| search(n, i + 1, ssy), || search(n, i + 1, ssn));
    cy + cn
}

fn search_end(n: u32, i: u32, ss: Vec<S>) -> u32 {
    if i >= n - 1 { 1 } else { search_end2(n, i, ss) }
}

fn search_end2(n: u32, i: u32, mut ss: Vec<S>) -> u32 {
    let (shift, mask) = (n - i - 1, !(!(0 as S) << i + 1));
    let close = |s: S| {
        let x = (s ^ s >> shift) & mask;
        x & x.wrapping_sub(1) == 0
    };
    match ss.iter().position(|&s| close(s)) {
        Some(0) => {
            match ss.iter().position(|&s| !close(s)) {
                Some(p) => {
                    let (ssy, ssn) = ss.drain(p..).partition(|&s| close(s));
                    let (cy, cn) = rayon::join(|| search_end(n, i + 1, cat(ss, ssy)),
                                               || search_end(n, i + 1, ssn));
                    cy + cn
                }
                None => search_end(n, i + 1, ss),
            }
        }
        Some(p) => {
            let (ssy, ssn) = ss.drain(p..).partition(|&s| close(s));
            let (cy, cn) = rayon::join(|| search_end(n, i + 1, ssy),
                                       || search_end(n, i + 1, cat(ss, ssn)));
            cy + cn
        }
        None => search_end(n, i + 1, ss),
    }
}

fn main() {
    for n in 1..S_BITS + 1 {
        println!("{}: {}", n, search(n, 1, vec![0, 1]));
    }
}

Cargo.toml

[package]
name = "correlations"
version = "0.1.0"
authors = ["Anders Kaseorg <andersk@mit.edu>"]

[dependencies]
rayon = "0.7.0"

এটি অনলাইন চেষ্টা করুন!

আমার খুব কম স্মৃতি ব্যবহার করে কিছুটা ধীর গতির বৈকল্পিকও রয়েছে


আপনি কোন আশাবাদী ব্যবহার করেছেন?

1
@ লেলেবিক সংকলিত ভাষায় বিটওয়াসার গাণিতিক দিয়ে সবকিছু করার পাশাপাশি বৃহত্তম অপ্টিমাইজেশন হ'ল ওয়াই / এন অ্যারের একটি উপসর্গ খালি করার জন্য কেবল যতটা ননডেটরিনিজম প্রয়োজন তা ব্যবহার করা। আমি ওয়াই / এন অ্যারের সম্ভাব্য উপসাগরগুলিতে পুনরাবৃত্ত অনুসন্ধান করব, সম্ভাব্য স্ট্রিংয়ের একটি ভেক্টরকে সাথে নিয়ে সেই উপসর্গটি অর্জন করেছি, তবে কেবল সেই স্ট্রিং যার অব্যক্ত মাঝারিটি শূন্যে পূর্ণ। এটি বলেছিল, এটি এখনও একটি ক্ষতিকারক অনুসন্ধান এবং এই অপ্টিমাইজেশানগুলি কেবল বহুবিধ উপাদান দ্বারা এটির গতি বাড়ায়।
অ্যান্ডারস ক্যাসরগ

এটি একটি দুর্দান্ত উত্তর। ধন্যবাদ. আমি আশা করছি যে একটি গুরুত্বপূর্ণ গতি বাড়ানোর জন্য কেউ সংযুক্তিগুলির খনন করবে।

@ ল্যাম্বিক আমি একটি স্মৃতি নষ্টকারী বাগটি স্থির করেছি, আরও মাইক্রো-অপ্টিমাইজেশন করেছি এবং সমান্তরালতা যুক্ত করেছি। সুযোগ পেলে দয়া করে পুনরায় পরীক্ষা করুন — আমি আমার স্কোরটি 1 বা 2 দ্বারা বাড়িয়ে নেওয়ার প্রত্যাশা করছি কি আরও বড় স্পিডআপের জন্য আপনার মনে সম্মিলিত ধারণা রয়েছে? আমি কিছু নিয়ে আসিনি।
অ্যান্ডারস ক্যাসরগ

1
@ ল্যাম্বিক ওইআইএস প্রবেশে কোনও সূত্র দেওয়া হয়নি। (সেখানে গণিতের কোডটিও নিষ্ঠুর-শক্তি ব্যবহার করে বলে মনে হচ্ছে)) আপনি যদি কোনওটির সাথে পরিচিত হন তবে আপনি এটি সম্পর্কে তাদের বলতে চান।
খ্রিস্টান সিভর্স

6

সি ++ বুডিডি লাইব্রেরি ব্যবহার করে

একটি ভিন্ন পদ্ধতির: একটি বাইনারি সূত্র ( বাইনারি সিদ্ধান্ত ডায়াগ্রাম হিসাবে ) রয়েছে যা বিটগুলি Sইনপুট হিসাবে গ্রহণ করে এবং সত্য iff যা নির্দিষ্ট Yবা Nনির্দিষ্ট কিছু পজিশনের নির্দিষ্ট কিছু মান দেয় । যে সূত্র ধ্রুবক মিথ্যা না হয়, একটি বিনামূল্যে অবস্থান নির্বাচন এবং recurse, চেষ্টা উভয় Yএবং N। যদি কোনও মুক্ত অবস্থান না থাকে তবে আমরা একটি সম্ভাব্য আউটপুট মান খুঁজে পেয়েছি found সূত্রটি যদি অবিচ্ছিন্ন থাকে তবে ব্যাকট্র্যাক করুন।

এটি তুলনামূলক যুক্তিসঙ্গত কাজ করে কারণ খুব কম সম্ভাব্য মান রয়েছে যাতে আমরা প্রায়শই প্রথম দিকে ব্যাকট্র্যাক করতে পারি। আমি স্যাট সলভারের সাথে অনুরূপ ধারণার চেষ্টা করেছি, তবে এটি কম সফল ছিল।

#include<vector>
#include<iostream>
#include<bdd.h>

// does vars[0..i-1] differ from vars[n-i..n-1] in at least two positions?
bdd cond(int i, int n, const std::vector<bdd>& vars){
  bdd x1 { bddfalse };
  bdd xs { bddfalse };
  for(int k=0; k<i; ++k){
    bdd d { vars[k] ^ vars[n-i+k] };
    xs |= d & x1;
    x1 |= d;
  }
  return xs;
}

void expand(int i, int n, int &c, const std::vector<bdd>& conds, bdd x){
  if (x==bddfalse)
    return;
  if (i==n-2){
    ++c;
    return;
  }

  expand(i+1,n,c,conds, x & conds[2*i]);
  x &= conds[2*i+1];
  expand(i+1,n,c,conds, x);
}

int count(int n){
  if (n==1)   // handle trivial case
    return 1;
  bdd_setvarnum(n-1);
  std::vector<bdd> vars {};
  vars.push_back(bddtrue); // assume first bit is 1
  for(int i=0; i<n-1; ++i)
    if (i%2==0)            // vars in mixed order
      vars.push_back(bdd_ithvar(i/2));
    else
      vars.push_back(bdd_ithvar(n-2-i/2));
  std::vector<bdd> conds {};
  for(int i=n-1; i>1; --i){ // handle long blocks first
    bdd cnd { cond(i,n,vars) };
    conds.push_back( cnd );
    conds.push_back( !cnd );
  }
  int c=0;
  expand(0,n,c,conds,bddtrue);
  return c;
}

int main(void){
  bdd_init(20000000,1000000);
  bdd_gbc_hook(nullptr); // comment out to see GC messages
  for(int n=1; ; ++n){
    std::cout << n << " " << count(n) << "\n" ;
  }
}

ডিবিয়ান 8 (জেসি) দিয়ে সংকলন করতে, ইনস্টল করুন libbdd-devএবং করুন g++ -std=c++11 -O3 -o hb hb.cpp -lbdd। প্রথম যুক্তিটিকে bdd_initআরও বেশি করে বাড়ানো কার্যকর হতে পারে ।


এটি আকর্ষণীয় দেখায়। আপনি এই কি পেতে?

@ লেম্বিক আমি খুব পুরানো হার্ডওয়্যারে 100 এর মধ্যে 31 পেয়েছি যা আমাকে দ্রুত উত্তর দিতে দেবে না
খ্রিস্টান সিভারস

কীভাবে আপনি উইন্ডোজে এটি সংকলন করতে পারেন তার কোনও সহায়তা (উদাহরণস্বরূপ সাইগউইন ব্যবহার করে) কৃতজ্ঞভাবে প্রাপ্ত।

@ ল্যাম্বিক আমি উইন্ডোজ সম্পর্কে জানি না তবে github.com/fd00/yacp/tree/master/buddy সহায়ক রাই্ট সাইগউইন
খ্রিস্টান

1
বাহ, ঠিক আছে, আপনি আমাকে নিশ্চিত করেছেন যে আমার এই সরঞ্জামটি আমার সরঞ্জামদণ্ডে যুক্ত করা দরকার। সাবাশ!
অ্যান্ডারস ক্যাসরগ

4

ক্লিঙ্গো, n ≈ 30 বা 31 34

ক্লিঙ্গো কোডের পাঁচটি লাইন আমার ব্রুট-ফোর্স মরিচ সমাধানটি পেরিয়ে দেখে খালি খ্রিস্টানের বুডিডি সমাধানের কাছাকাছি এসেছিল দেখে আমি কিছুটা অবাক হয়েছিলাম - দেখে মনে হচ্ছে এটি উচ্চতর সময়সীমার সাথে এটিও পরাজিত হবে।

corr.lp

{s(2..n)}.
d(K,I) :- K=1..n-2, I=1..n-K, s(I), not s(K+I).
d(K,I) :- K=1..n-2, I=1..n-K, not s(I), s(K+I).
a(K) :- K=1..n-2, {d(K,1..n-K)} 1.
#show a/1.

corr.sh

#!/bin/bash
for ((n=1;;n++)); do
    echo "$n $(clingo corr.lp --project -q -n 0 -c n=$n | sed -n 's/Models *: //p')"
done

পটভূমি


এটা অসাধারণ! আপনার গ্রাফ থেকে মনে হচ্ছে বুডিডি সমাধান হঠাৎ খারাপ হয়ে যায়। কোন ধারণা কেন?

@ ল্যাম্বিক আমি নিশ্চিত হয়ে ওঠার জন্য বুডিডি কে তদন্ত করে দেখিনি, তবে সম্ভবত এই মুহুর্তে এটি ক্যাশে থেকে যায়?
অ্যান্ডারস ক্যাসরগ

কি দারুন! আমি মনে করি যে উচ্চতর প্রথম মানটি bdd_initসাহায্য করতে পারে, বা bdd_setmaxincrease50000 এর ডিফল্টের চেয়ে অনেক বেশি মূল্য দিয়ে কল করে নোড টেবিলকে আরও বাড়িয়ে দিতে পারে - আপনি কি আমার প্রোগ্রামের পরিবর্তিত সংস্করণটি ব্যবহার করছেন?
খ্রিস্টান সিভর্স

2
আমি তোমার গ্রাফ পছন্দ করি

1
আপনি বিকল্পটি ব্যবহার করে --configuration=crafty( jumpyএবং trendyঅনুরূপ ফলাফল দিন) একটি চমকপ্রদ পারফরম্যান্স উত্সাহ পাবেন ।
খ্রিস্টান সিভর্স

2

পরীর / জিপি , 23

ডিফল্টরূপে, পারী / জিপি তার স্ট্যাকের আকারটি 8 এমবি সীমাবদ্ধ করে। কোডের প্রথম লাইনটি default(parisize, "4g")4 গিগাবাইটে এই সীমাটি সেট করে। এটি এখনও যদি স্ট্যাকওভারফ্লো দেয় তবে আপনি এটি 8 জিবিতে সেট করতে পারেন।

default(parisize, "4g")
f(n) = #vecsort([[2 > hammingweight(bitxor(s >> (n-i) , s % 2^i)) | i <- [2..n-1]] | s <- [0..2^(n-1)]], , 8)
for(n = 1, 100, print(n " -> " f(n)))

22 এ পৌঁছে তারপর স্ট্যাকওভারফ্লো দেয়।

এখন 24 এ পাওয়া যায়।

2

ক্লোজার, 75 এ 29 38 সেকেন্ডে , 80-এ 30 এবং 165-এ 31

ইন্টেল i7 6700K থেকে রানটাইম , মেমরির ব্যবহার 200 এমবি এর চেয়ে কম।

প্রোজেক্ট.সিএলজে ( মাল্টিথ্রেডিংয়ের জন্য কমপ্লেমেট / ক্লেপুল ব্যবহার করে):

(defproject tests "0.0.1-SNAPSHOT"
  :description "FIXME: write description"
  :dependencies [[org.clojure/clojure "1.8.0"]
                 [com.climate/claypoole "1.1.4"]]
  :javac-options ["-target" "1.6" "-source" "1.6" "-Xlint:-options"]
  :aot [tests.core]
  :main tests.core)

সোর্স কোড:

(ns tests.core
  (:require [com.climate.claypoole :as cp]
            [clojure.set])
  (:gen-class))

(defn f [N]
  (let [n-threads   (.. Runtime getRuntime availableProcessors)
        mask-offset (- 31 N)
        half-N      (quot N 2)
        mid-idx     (bit-shift-left 1 half-N)
        end-idx     (bit-shift-left 1 (dec N))
        lower-half  (bit-shift-right 0x7FFFFFFF mask-offset)
        step        (bit-shift-left 1 12)
        bitcount
          (fn [n]
            (loop [i 0 result 0]
              (if (= i N)
                result
                (recur
                  (inc i)
                  (-> n
                      (bit-xor (bit-shift-right n i))
                      (bit-and (bit-shift-right 0x7FFFFFFF (+ mask-offset i)))
                      Integer/bitCount
                      (< 2)
                      (if (+ result (bit-shift-left 1 i))
                          result))))))]
    (->>
      (cp/upfor n-threads [start (range 0 end-idx step)]
        (->> (for [i      (range start (min (+ start step) end-idx))
                   :when  (<= (Integer/bitCount (bit-shift-right i mid-idx))
                              (Integer/bitCount (bit-and         i lower-half)))]
               (bitcount i))
             (into #{})))
      (reduce clojure.set/union)
      count)))

(defn -main [n]
  (let [n-iters 5]
    (println "Calculating f(n) from 1 to" n "(inclusive)" n-iters "times")
    (doseq [i (range n-iters)]
      (->> n read-string inc (range 1) (map f) doall println time)))
  (shutdown-agents)
  (System/exit 0))

একটি ব্রুট-ফোর্স সমাধান, প্রতিটি থ্রেড পরিসরের একটি উপসেট (2 ^ 12 আইটেম) এর উপরে চলে যায় এবং সনাক্তকৃত নিদর্শনগুলি নির্দেশ করে যা পূর্ণসংখ্যার মানগুলির সেট তৈরি করে। এরপরে এগুলি একত্রে "একত্রিত" হয় এবং এইভাবে পৃথক গণনা গণনা করা হয়। আমি আশা করি কোডটি ইভেন্টটি অনুসরণ করতে খুব জটিল নয়, এটি ম্যাক্রোগুলিকে প্রচুর থ্রেডিং ব্যবহার করে । আমারmain জেভিএম উষ্ণ হওয়ার জন্য কয়েকবার পরীক্ষা চালায়।

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

প্রাক-নির্মিত উবারজার ( ভি 1 ) (3.7 এমবি):

$ wget https://s3-eu-west-1.amazonaws.com/nikonyrh-public/misc/so-124424-v2.jar
$ java -jar so-124424-v2.jar 29
Calculating f(n) from 1 to 29 (inclusive) 5 times
(1 1 2 4 6 8 14 18 27 36 52 65 93 113 150 188 241 279 377 427 540 632 768 870 1082 1210 1455 1656 1974)
"Elapsed time: 41341.863703 msecs"
(1 1 2 4 6 8 14 18 27 36 52 65 93 113 150 188 241 279 377 427 540 632 768 870 1082 1210 1455 1656 1974)
"Elapsed time: 37752.118265 msecs"
(1 1 2 4 6 8 14 18 27 36 52 65 93 113 150 188 241 279 377 427 540 632 768 870 1082 1210 1455 1656 1974)
"Elapsed time: 38568.406528 msecs"
[ctrl+c]

বিভিন্ন হার্ডওয়ারের ফলাফল, প্রত্যাশিত রানটাইমটি কি O(n * 2^n)?

i7-6700K  desktop: 1 to 29 in  38 seconds
i7-6820HQ laptop:  1 to 29 in  43 seconds
i5-3570K  desktop: 1 to 29 in 114 seconds

আপনি সহজেই এই একক থ্রেডেড করতে পারেন এবং এর জন্য স্ট্যান্ডার্ড ব্যবহার করে that য় পক্ষের নির্ভরতা এড়াতে পারেন:

(for [start (range 0 end-idx step)]
  ... )

আচ্ছা বিল্ট-ইন পিএমএপ এছাড়াও বিদ্যমান তবে ক্রেটপুলের আরও বৈশিষ্ট্য এবং সুরক্ষার ব্যবস্থা রয়েছে।


হ্যাঁ, এটি বিতরণকে তুচ্ছ করে তোলে। আমার সমাধানটি পুনরায় মূল্যায়নের জন্য আপনার কি সময় আছে, আমি নিশ্চিত আপনি এটি এখন 30-এ পেয়ে যাবেন। আমার সামনে আরও অনুকূলিতকরণ নেই ations
নিকোনিহার

দুঃখজনকভাবে এটি 30 নম্বরের জন্য সময় অতিবাহিত সময়: 217150.87386 এমসেকস

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

1

গণিত, এন = 19

Alt + টিপুন। বাতিল এবং ফলাফল মুদ্রণ করা হবে

k = 0;
For[n = 1, n < 1000, n++,
Z = Table[HammingDistance[#[[;; i]], #[[-i ;;]]], {i, Length@#}] & /@
Tuples[{0, 1}, n];
Table[If[Z[[i, j]] < 2, Z[[i, j]] = 0, Z[[i, j]] = 1], {i, 
Length@Z}, {j, n}];
k = Length@Union@Z]
Print["f(", n, ")=", k]

আমি এটি চালাতে পারছি না তাই আপনি কীভাবে তা ব্যাখ্যা করতে পারবেন এটি তাত্পর্যপূর্ণ সময় নেওয়া এড়ায়? 2 ^ 241 খুব বড় একটি সংখ্যা!

আপনি কোডের আউটপুট দেখাতে পারেন?

1
আমার অর্থ f (n) ... স্থির ছিল
J42161217

1

গণিত, 21

f [n_]: = দৈর্ঘ্য @
     DeleteDuplicates @
      TRANSPOSE @
       সারণী [2> টিআর @ ইন্টিজার ডিজিটস [#, 2] এবং / @ 
         বিট এক্সর 
         n - 1}] & @ ব্যাপ্তি [0, 2 ^ (n - 1)];
[মুদ্রণ করুন [এন -> চ @ এন], {n, অনন্ত}]

তুলনার জন্য, জেনি_ম্যাথির উত্তরn = 19 আমার কম্পিউটারে দেয় ।

সবচেয়ে ধীর অংশ Tr@IntegerDigits[#, 2] &। এটা লজ্জাজনক যে ম্যাথমেটিকার হ্যামিং ওজনের জন্য অন্তর্নির্মিতা নেই।


আপনি যদি আমার কোডটি পরীক্ষা করতে চান তবে আপনি গণিতের একটি বিনামূল্যে পরীক্ষা ডাউনলোড করতে পারেন ।


1

এসি সংস্করণ, অন্তর্নির্মিত পপকাউন্ট ব্যবহার করে

এর সাথে আরও ভাল clang -O3কাজ করে তবে আপনার যদি কেবল থাকে তবে তা কাজ করে gcc

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

unsigned long pairs(unsigned int n, unsigned long s) { 
  unsigned long result = 0;

  for(int d=1;d<=n;d++) { 
    unsigned long mx = 1 << d;
    unsigned long mask = mx - 1;

    unsigned long diff = (s >> (n - d)) ^ (s & mask);
    if (__builtin_popcountl(diff) <= 1)
      result |= mx;
  } 
  return result;

}

unsigned long f(unsigned long  n) { 
  unsigned long max = 1 << (n - 1);
#define BLEN (max / 2)
  unsigned char * buf = malloc(BLEN);
  memset(buf, 0, BLEN);
  unsigned long long * bufll = (void *) buf;

  for(unsigned long i=0;i<=max;i++) { 
    unsigned int r = pairs(n, i);
    buf[r / 8] |= 1 << (r % 8);
  } 

  unsigned long result = 0;

  for(unsigned long i=0;i<= max / 2 / sizeof(unsigned long long); i++) { 
    result += __builtin_popcountll(bufll[i]);
  } 

  free(buf);

  return result;
}

int main(int argc, char ** argv) { 
  unsigned int n = 1;

  while(1) { 
    printf("%d %ld\n", n, f(n));
    n++;
  } 
  return 0;
}

এটি খুব দ্রুত 24 এ যায় এবং তারপরে শেষ হয়। আপনার সীমা বাড়াতে হবে।

ওহ ,শ্বর, আমি মাপদণ্ডের কোডটি সরিয়ে দিতে ভুলে গেছি! আমি দুটি আপত্তিকর লাইন সরিয়ে
ফেলব

@ লেম্বিক এখনই ঠিক করা উচিত
বার্তাভেল

1

হাস্কেল, (আনুষ্ঠানিক এন = 20)

এটি কেবল নির্বোধ পন্থা - এখন পর্যন্ত কোনও অপ্টিমাইজেশন ছাড়াই। আমি ভাবলাম যে এটি অন্যান্য ভাষার বিরুদ্ধে কতটা ভাল করে দেবে।

এটি কীভাবে ব্যবহার করবেন (ধরে নিবেন আপনি হ্যাশেল প্ল্যাটফর্ম ইনস্টল করেছেন):

  • একটি ফাইলে কোডটি আটকান approx_corr.hs(বা অন্য কোনও নাম অনুসারে নিম্নলিখিত পদক্ষেপগুলি সংশোধন করুন)
  • ফাইলটিতে নেভিগেট করুন এবং কার্যকর করুন ghc approx_corr.hs
  • চালান approx_corr.exe
  • সর্বাধিক প্রবেশ করান n
  • প্রতিটি গণনার ফলাফল প্রদর্শিত হয়, পাশাপাশি সেই বিন্দু অবধি সংশ্লেষিত রিয়েল টাইম (এমএসে)।

কোড:

import Data.List
import Data.Time
import Data.Time.Clock.POSIX

num2bin :: Int -> Int -> [Int]
num2bin 0 _ = []
num2bin n k| k >= 2^(n-1) = 1 : num2bin (n-1)( k-2^(n-1))
           | otherwise  = 0: num2bin (n-1) k

genBinNum :: Int -> [[Int]]
genBinNum n = map (num2bin n) [0..2^n-1]

pairs :: [a] -> [([a],[a])]
pairs xs = zip (prefixes xs) (suffixes xs)
   where prefixes = tail . init . inits 
         suffixes = map reverse . prefixes . reverse 

hammingDist :: (Num b, Eq a) => ([a],[a]) -> b     
hammingDist (a,b) = sum $ zipWith (\u v -> if u /= v then 1 else 0) a b

f :: Int -> Int
f n = length $ nub $ map (map ((<=1).hammingDist) . pairs) $ genBinNum n
--f n = sum [1..n]

--time in milliseconds
getTime = getCurrentTime >>= pure . (1000*) . utcTimeToPOSIXSeconds >>= pure . round


main :: IO()
main = do 
    maxns <- getLine 
    let maxn = (read maxns)::Int
    t0 <- getTime 
    loop 1 maxn t0
     where loop n maxn t0|n==maxn = return ()
           loop n maxn t0
             = do 
                 putStrLn $ "fun eval: " ++ (show n) ++ ", " ++ (show $ (f n)) 
                 t <- getTime
                 putStrLn $ "time: " ++ show (t-t0); 
                 loop (n+1) maxn t0

কোডটি চলতে চলতে আউটপুট দেবে না বলে মনে হচ্ছে। এটি পরীক্ষা করা একটু কঠিন করে তোলে।

আজব, এটি ত্রুটি ছাড়াই সংকলন করে? আপনি যদি প্রোগ্রামটি সংকলন করার চেষ্টা করেন তবে কী হবে main = putStrLn "Hello World!"?
flawr

Data.Bitsমডিউল সহায়ক হতে পারে। আপনার প্রধান লুপের জন্য, আপনি main = do maxn <- getmax; t0 <- gettime; loop 1কোথায় loop n|n==maxn = return ()এবং যেখানে কিছু ব্যবহার করতে পারেন loop n = do printresult n (f n); t <- gettime; printtime (t-t0); loop (n+1)getmaxউদাহরণস্বরূপ getArgsপ্রোগ্রাম আর্গুমেন্ট ব্যবহার করতে পারেন।
খ্রিস্টান সিভর্স

@ ক্রিশ্চিয়ানসিভার্স অনেক ধন্যবাদ !!! আমি এই প্রশ্নটি স্ট্যাকওভারফ্লোতে জিজ্ঞাসা করেছি , আমার মনে হয় আপনি যদি সেখানেও যুক্ত করতে পারতেন তবে দুর্দান্ত হত!
flawr

আমি কীভাবে উত্তর দেবো তা দেখছি না। ইতিমধ্যে আপনার এখানে একই লুপ রয়েছে এবং সময় পাওয়ার বিষয়ে আমি কিছুই বলিনি: আপনি ইতিমধ্যে এখানে এসেছিলেন।
খ্রিস্টান সিভর্স

1

পপকাউন্ট এবং ম্যানুয়ালি পরিচালিত সমান্তরালতা ব্যবহার করে একটি হাস্কেল সমাধান

কম্পাইল: ghc -rtsopts -threaded -O2 -fllvm -Wall foo.hs

(ঝরা -llvm যদি এটি কাজ না তবে )

চালান: ./foo +RTS -N

module Main (main) where

import Data.Bits
import Data.Word
import Data.List
import qualified Data.IntSet as S 
import System.IO
import Control.Monad
import Control.Concurrent
import Control.Exception.Base (evaluate)

pairs' :: Int -> Word64 -> Int
pairs' n s = fromIntegral $ foldl' (.|.) 0 $ map mk [1..n]
  where mk d = let mask = 1 `shiftL` d - 1 
                   pc = popCount $! xor (s `shiftR` (n - d)) (s .&. mask)
               in  if pc <= 1 
                     then mask + 1 
                     else 0 

mkSet :: Int -> Word64 -> Word64 -> S.IntSet
mkSet n a b = S.fromList $ map (pairs' n) [a .. b]

f :: Int -> IO Int
f n 
   | n < 4 = return $ S.size $ mkSet n 0 mxbound
   | otherwise = do
        mvs <- replicateM 4 newEmptyMVar
        forM_ (zip mvs cpairs) $ \(mv,(mi,ma)) -> forkIO $ do
          evaluate (mkSet n mi ma) >>= putMVar mv
        set <- foldl' S.union S.empty <$> mapM readMVar mvs
        return $! S.size set
   where
     mxbound = 1 `shiftL` (n - 1)
     bounds = [0,1 `shiftL` (n - 3) .. mxbound]
     cpairs = zip bounds (drop 1 bounds)

main :: IO()
main = do
    hSetBuffering stdout LineBuffering
    mapM_ (f >=> print) [1..]

একটি বাফারিংয়ের সমস্যা রয়েছে বলে মনে হয় যে আমি সাইগুইম কমান্ড লাইন থেকে চালালে আমি কোনও আউটপুট পাই না get

আমি আমার সমাধানটি সবেমাত্র আপডেট করেছি, তবে জানি না এটি কতটা উপকারী হবে।
বারটাভলে

@ ল্যাম্বিক অনিশ্চিত যদি তা সুস্পষ্ট হয় তবে এটি সংকলিত হওয়া উচিত -O3এবং এর সাথে আরও দ্রুত হতে পারে -O3 -fllvm...
বার্তাভেল

(এবং সোর্স কোড পরিবর্তন না হলে
পুনর্নির্মাণের

@ ল্যাম্বিক: আমি সমান্তরালতার পরিচয় দিয়েছি। এটি কিছুটা দ্রুত হওয়া উচিত।
বার্তাভেল

0

পাইথন 2 + পিপি, এন = 22

বেসলাইন বেঞ্চমার্কের এক ধরণের হিসাবে এটি একটি খুব সাধারণ পাইথন সমাধান।

import itertools
def hamming(A, B):
    n = len(A)
    assert(len(B) == n)
    return n-sum([A[i] == B[i] for i in xrange(n)])

def prefsufflist(P):
    n = len(P)
    return [hamming(P[:i], P[n-i:n]) for i in xrange(1,n+1)]

bound = 1
for n in xrange(1,25):
    booleans = set()
    for P in itertools.product([0,1], repeat = n):
        booleans.add(tuple(int(HD <= bound) for HD in prefsufflist(P)))
    print "n = ", n, len(booleans)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.