নির্ধারিত যোগফল সহ এলোমেলো সংখ্যা


32

আপনার টাস্ক একটি লিখতে হয় প্রোগ্রাম বা একটি ফাংশন যে আউটপুট n সংশোধন সমষ্টি সঙ্গে র্যান্ডম সংখ্যা ব্যবধান [0,1] থেকে s

ইনপুট

n, n≥1, উত্পন্ন করার জন্য এলোমেলো সংখ্যার সংখ্যা

s, s>=0, s<=n, সংখ্যার যোগফল তৈরি করতে হবে

আউটপুট

অন্তরাল [0,1] থেকেn সমস্ত উপাদানের সাথে ভাসমান পয়েন্ট সংখ্যার একটি এলোমেলো-শীর্ষ এবং যে কোনও সুবিধাজনক দ্ব্যর্থহীন উপায়ে আউটপুট সমান সমস্ত উপাদানগুলির সমষ্টি । সমস্ত বৈধ- টিপলগুলিকে ভাসমান পয়েন্ট সংখ্যাগুলির সীমাবদ্ধতার মধ্যে সমান সম্ভাবনা থাকতে হবে।sn

এটি- nমাত্রিক ইউনিট ঘনক্ষেত্রের মধ্যে পয়েন্টের ছেদ থেকে সমান নমুনার সমান এবং n-1দ্বি - মাত্রিক হাইপারপ্লেন যা (s/n, s/n, …, s/n)ভেক্টরের মধ্য দিয়ে যায় এবং লম্ব হয় (1, 1, …, 1)(তিনটি উদাহরণের জন্য চিত্র 1 এ লাল অঞ্চল দেখুন)।

উদাহরণস্বরূপ n = 3 এবং অঙ্কগুলি 0.75, 1.75 এবং 2.75

চিত্র 1: বৈধ আউটপুটগুলির সমতুল্য এন = 3 এবং যোগফল 0.75, 1.75 এবং 2.75

উদাহরণ

n=1, s=0.8 → [0.8]
n=3, s=3.0 → [1.0, 1.0, 1.0]
n=2, s=0.0 → [0.0, 0.0]
n=4, s=2.0 → [0.2509075946818119, 0.14887693388076845, 0.9449661625992032, 0.6552493088382167]
n=10, s=9.999999999999 → [0.9999999999999,0.9999999999999,0.9999999999999,0.9999999999999,0.9999999999999,0.9999999999999,0.9999999999999,0.9999999999999,0.9999999999999,0.9999999999999]

বিধি

  • আপনার প্রোগ্রামটি কমপক্ষে n≤10এবং কোনও বৈধ গুলি সহ আপনার মেশিনে এক সেকেন্ডের মধ্যে শেষ করা উচিত ।
  • আপনি যদি চান তবে আপনার প্রোগ্রামটি উপরের প্রান্তে, s<nএবং অর্ধ-খোলা ব্যবধান [0,1) থেকে আউটপুট সংখ্যাগুলিতে একচেটিয়া হতে পারে (দ্বিতীয় উদাহরণটি ভঙ্গ করে)
  • যদি আপনার ভাষা ভাসমান পয়েন্ট সংখ্যা সমর্থন করে না, আপনি দশমিক পয়েন্টের পরে কমপক্ষে দশ দশমিক অঙ্কের সাথে আউটপুটটিকে জাল করতে পারেন।
  • স্ট্যান্ডার্ড লুফোলগুলি অনুমোদিত নয় এবং স্ট্যান্ডার্ড ইনপুট / আউটপুট পদ্ধতিগুলি অনুমোদিত।
  • এটি , তাই সংক্ষিপ্ত এন্ট্রি, বাইটে পরিমাপ করা হয়, জিততে পারে।


আপনি যখন বলবেন This is equal to uniformly sampling from the intersection- আমি সেই ছেদটির ঠিক কোণ থেকে এলোমেলোভাবে বেছে নেওয়া একটি প্রোগ্রাম দেখতে পাচ্ছি। এটা কি বৈধ হবে?
জেসি

2
@ কেভিন ক্রুজসেন না, এটি কেবল সত্য s==0 or s==3। অন্যান্য সমস্ত মানগুলির জন্য s, বিমানটির ননজারো অঞ্চল রয়েছে এবং আপনাকে সমতুল্য-এলোমেলোভাবে সেই বিমানের একটি বিন্দু বেছে নিতে হবে।
ব্যবহারকারী 202729

3
বিরতিটি বন্ধ হওয়া বা অর্ধ-বন্ধ হওয়া (খোলার বিপরীতে) প্রয়োজন একটি তাত্ত্বিকভাবে অলক্ষণীয় প্রয়োজন। অনেক এলোমেলো সংখ্যা জেনারেটর (0,1) এ আউটপুট দেয়। আউটপুট অন্তর [0,1) এবং (0,1) নয় তা কীভাবে পরীক্ষা করবেন? 0 "কখনই" মানটি কোনওভাবেই ঘটে না
লুইস মেন্ডো

2
যদি আমাদের কোডটি প্রত্যাখ্যানের নমুনা ব্যবহার করে, এবং যেমন পরীক্ষার ক্ষেত্রে যেমন খুব বেশি সময় নেয় তবে এটি ঠিক কি s=2.99999999999, n=3? আমরা কি বহু গুণে এলোমেলো বাস্তব তৈরি করতে পারি, বলুন 1e-9?
xnor

উত্তর:


1

ওল্ফ্রাম ভাষা (গণিত) , 92 90 বাইট

If[2#2>#,1-#0[#,#-#2],While[Max[v=Differences@Sort@Join[{0,#2},RandomReal[#2,#-1]]]>1];v]&

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

আন-গল্ফ কোড:

R[n_, s_] := Module[{v},
  If[s <= n/2,             (* rejection sampling for s <= n/2:                        *)
    While[
      v = Differences[Sort[
            Join[{0},RandomReal[s,n-1],{s}]]];         (* trial randoms that sum to s *)
      Max[v] > 1           (* loop until good solution found                          *)
    ];
    v,                     (* return the good solution                                *)
    1 - R[n, n - s]]]      (* for s > n/2, invert the cube and rejection-sample       *)

এখানে একটি সমাধান যা 55 বাইটে কাজ করে তবে আপাতত (ম্যাথমেটিকা ​​সংস্করণ 12) সীমাবদ্ধ n=1,2,3কারণ RandomPointউচ্চতর মাত্রিক হাইপারপ্লেনগুলি থেকে পয়েন্ট আঁকতে রাজি হয়নি (টিআইওর সংস্করণ 11.3 এ এটিও ব্যর্থ হয় n=1)। এটি nভবিষ্যতে উচ্চতর জন্য কাজ করতে পারে যদিও:

RandomPoint[1&~Array~#~Hyperplane~#2,1,{0,1}&~Array~#]&

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

আন-গল্ফ কোড:

R[n_, s_] :=
  RandomPoint[                           (* draw a random point from *)
    Hyperplane[ConstantArray[1, n], s],  (* the hyperplane where the sum of coordinates is s *)
    1,                                   (* draw only one point *)
    ConstantArray[{0, 1}, n]]            (* restrict each coordinate to [0,1] *)


6

পাইথন 2 , 144 128 119 বাইট

from random import*
def f(n,s):
 r=min(s,1);x=uniform(max(0,r-(r-s/n)*2),r);return n<2and[s]or sample([x]+f(n-1,s-x),n)

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


  • -20 বাইট, কেভিন ক্রুইজসেনকে ধন্যবাদ

@ লুইস মেন্ডো এখনই ঠিক করা উচিত
টিফিল্ড

তারা এখনও অভিন্ন বলে মনে হচ্ছে না
l4m2

@ l4m2 আমি g(4, 2.0)4,000 পয়েন্ট পেতে 1,000 বার দৌড়েছি এবং ফলাফলগুলি দেখতে এর মতো দেখতে মোটামুটি ইউনিফর্ম appears
ইঞ্জিনিয়ার টোস্ট



4

জাভা 8, 194 188 196 237 236 বাইট

n->s->{double r[]=new double[n+1],d[]=new double[n],t;int f=0,i=n,x=2*s>n?1:0;for(r[n]=s=x>0?n-s:s;f<1;){for(f=1;i-->1;)r[i]=Math.random()*s;for(java.util.Arrays.sort(r);i<n;d[i++]=x>0?1-t:t)f=(t=Math.abs(r[i]-r[i+1]))>1?0:f;}return d;}

1 এর কাছাকাছি পরীক্ষার মামলার গতি ঠিক করার পাশাপাশি সাধারণভাবে অ্যালগরিদম ঠিক করতে +49 বাইট (188 → 196 এবং 196 → 237)

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

ব্যাখ্যা:

এই স্ট্যাকওভারফ্লো উত্তরের পদ্ধতির ব্যবহার করুন , লুপের ভিতরে যতক্ষণ না কোনও আইটেম 1 এর চেয়েও বড় হয় ততক্ষণ
, যদি 2*s>n, sএটি রূপান্তরিত হয় n-sএবং ফলাফলটি অ্যারের 1-diffপরিবর্তে আমাদের ব্যবহার করা উচিত তা চিহ্নিত করার জন্য একটি পতাকা সেট করা হয় diff(টিপস @ সোকটিনপ্ক এবং @ এল 4 এম 2 এর জন্য ধন্যবাদ )

n->s->{              // Method with integer & double parameters and Object return-type
  double r[]=new double[n+1]
                     //  Double-array of random values of size `n+1`
         d[]=new double[n],
                     //  Resulting double-array of size `n`
         t;          //  Temp double
  int f=0,           //  Integer-flag (every item below 1), starting at 0
      i=n,           //  Index-integer, starting at `n`
      x=             //  Integer-flag (average below 0.5), starting at:
        2*s>n?       //   If two times `s` is larger than `n`:
         1           //    Set this flag to 1
        :            //   Else:
         0;          //    Set this flag to 0
  for(r[n]=s=        //  Set both the last item of `r` and `s` to:
       x>0?          //   If the flag `x` is 1:
        n-s          //    Set both to `n-s`
       :             //   Else:
        s;           //    Set both to `s`
      f<1;){         //  Loop as long as flag `f` is still 0
    for(f=1;         //   Reset the flag `f` to 1
        i-->1;)      //   Inner loop `i` in range (n,1] (skipping the first item)
      r[i]=Math.random()*s;
                     //    Set the i'th item in `r` to a random value in the range [0,s)
    for(java.util.Arrays.sort(r);
                     //   Sort the array `r` from lowest to highest
        i<n;         //   Inner loop `i` in the range [1,n)
        ;d[i++]=     //     After every iteration: Set the i'th item in `d` to:
          x>0?       //      If the flag `x` is 1:
           1-t       //       Set it to `1-t`
          :          //      Else:
           t)        //       Set it to `t`
      f=(t=Math.abs( //    Set `t` to the absolute difference of:
            r[i]-r[i+1])) 
                     //     The i'th & (i+1)'th items in `r`
        >1?          //    And if `t` is larger than 1 (out of the [0,1] boundary)
         0           //     Set the flag `f` to 0
        :            //    Else:
         f;}         //     Leave the flag `f` unchanged
  return d;}         //  Return the array `d` as result

সময় শেষtest(10, 9.99);
l4m2

@ l4m2 হ্যাঁ, একই সাথে লক্ষ্য করেছেন 10, 9.0 আমি n=10, s=9.999999999999পরীক্ষার কেস ঠিক করার জন্য সম্পাদনা করার পরে ঠিক .. জাভাতে এখনও থাকার সময় কোনও ঠিক আছে কিনা তা নিশ্চিত নয় .. কিছুক্ষণের জন্য এ সম্পর্কে ভাবতে হবে। আপাতত আমি এটিকে সম্পাদন করব এটি সময়ের বাইরে জানাতে state
কেভিন ক্রুইজসেন 16

যদি n-s<1আপনি কল করতে পারেন f(n,n-s)এবং উপর যে সংখ্যা টুসকি 1/2(অর্থাত প্রতিস্থাপন xসঙ্গে 1-xl4m2 মত) করেনি। এটি sনিকটবর্তী সংখ্যার জন্য সমস্যাটি সমাধান করতে পারেn
soktinpk

টিউটোরিয়ালের জন্য ধন্যবাদ এটি আসলে s+s>nপরিবর্তেn-s<1 , কিন্তু যখন আমি অন্যান্য জাভাস্ক্রিপ্টের উত্তরগুলি দেখলাম তখন তা সত্যই উপলব্ধি হয়েছিল। এখনও উপস্থিত ছিল এমন অন্য বাগ সহ সমস্ত কিছু এখন ঠিক করা হয়েছে। বাইটস বেশ খানিকটা উপরে উঠেছিল তবে এখন প্রতিটি কাজ করে। এখান থেকে বাইট-কাউন্টে কাজ করবে। :)
কেভিন ক্রুইজসেন

আমি একটি সাধারণ প্রমাণ জানি না তবে আমি বিশ্বাস করি যে এই অ্যালগরিদম কাজ করে কারণ একটি এন-ডাইমেনশনাল হাইপারকিউব কে এন এন-ডাইমেনশনাল হাইপারপায়ারামিডে কাটা যেতে পারে।
নিল


3

সি ++ 11, 284 267 বাইট

-১৮ বাইটস জ্যাচারের জন্য ধন্যবাদ
সি ++ র্যান্ডম লাইব্রেরি, স্ট্যান্ডার্ড আউটপুটটিতে আউটপুট

#include<iostream>
#include<random>
typedef float z;template<int N>void g(z s){z a[N],d=s/N;int i=N;for(;i;)a[--i]=d;std::uniform_real_distribution<z>u(.0,d<.5?d:1-d);std::default_random_engine e;for(;i<N;){z c=u(e);a[i]+=c;a[++i]-=c;}for(;i;)std::cout<<a[--i]<<' ';}

কল করার জন্য, আপনাকে কেবল এটি করতে হবে:

g<2>(0.0);

যেখানে টেম্পলেট প্যারামিটার (এখানে, 2) এন, এবং প্রকৃত প্যারামিটার (এখানে, 0.0) এস


আমার মনে হয় আপনি মধ্যে স্থান অপসারণ করতে পারেন <z>এবংu
Zachary

আমি এটা নিচে আরও করেছেন: typedef float z;template<int N>void g(z s){z a[N],d=s/N;int i=N;for(;i;)a[--i]=d;std::uniform_real_distribution<z>u(.0,d<.5?d:1-d);std::default_random_engine e;for(;i<N;){z c=u(e);a[i]+=c;a[++i]-=c;}for(;i;)std::cout<<a[--i]<<' ';}। একটি নতুন লাইন আইটেমগুলির মধ্যে বিভাজক হতে হবে না
জাকারিয়া

1
পরিবর্তে দ্বিতীয় লুপটি পুনরায় কাজ করার পরামর্শ dদিয়ে পরিবর্তনের মাধ্যমে সম্পূর্ণরূপে পরিত্রাণ পাওয়ার পরামর্শ দিন ( প্রোগ্রামটি প্রথম নম্বরটি সঠিকভাবে গণনা করার জন্য d=s/Ns/=Nfor(z c;i<N;a[++i%N]-=c)a[i]+=c=u(e);for(;i<N;){z c=u(e);a[i]+=c;a[++i]-=c;}%N
সংযোজনটি নোট করুন

2

পরিষ্কার , 221 201 বাইট

পরিষ্কার, কোড-গল্ফ বা এলোমেলো সংখ্যা। দুটি বাছাই.

import StdEnv,Math.Random,System._Unsafe,System.Time
g l n s#k=toReal n
|s/k>0.5=[s/k-e\\e<-g l n(k-s)]
#r=take n l
#r=[e*s/sum r\\e<-r]
|all((>)1.0)r=r=g(tl l)n s

g(genRandReal(toInt(accUnsafe time)))

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

আংশিক ফাংশন আক্ষরিক :: (Int Real -> [Real])। প্রতি সেকেন্ডে একবারে নতুন ফলাফল আনবে।
কমপক্ষে 10 দশমিক স্থান পর্যন্ত সঠিক


2

আর , 99 বাইট ( gtoolsপ্যাকেজ সহ)

f=function(n,s){if(s>n/2)return(1-f(n,n-s))
while(any(T>=1)){T=gtools::rdirichlet(1,rep(1,n))*s}
T}

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

A~={w1,,wn:i,0<wi<1;wi=s}wisA={w1,,wn:i,0<wi<1s;wi=1}

s=1Dirichlet(1,1,,1) s1<1/ss

s>n/2


2

সি, 132 127 125 118 110 107 বাইট

-2 বাইটস @ সিলিংক্যাটকে ধন্যবাদ

i;f(s,n,o,d)float*o,s,d;{for(i=n;i;o[--i]=d=s/n);for(;i<n;o[++i%n]-=s)o[i]+=s=(d<.5?d:1-d)*rand()/(1<<31);}

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


দুর্ভাগ্যক্রমে, এই উত্তর চ্যালেঞ্জের নির্দিষ্টকরণের সাথে মেলে না। আউটপুট এলোমেলো সংখ্যার মধ্যে সীমাবদ্ধ নয় [0,1], এবং তাদের যৌথ বিতরণ অভিন্ন নয়।
নাইট্রডন

@ নাইট্রডন হে, আপনি কি দয়া করে এমন একটি ইনপুট সরবরাহ করতে পারেন যার জন্য আউটপুট [0,1] এ সীমাবদ্ধ নেই? আমি কয়েকটি ভিন্ন উদাহরণ চেষ্টা করেছিলাম এবং এগুলি সবই সঠিক বলে মনে হয়েছিল, যদি না আমি উদ্দেশ্যটি ভুল বুঝি।
ওভারলকডসানিক

টিআইওতে আরএনজি রাষ্ট্রের সাথে এবং আপনার n=4, মানগুলি s=3.23এবং s=0.89সীমার বাইরে আউটপুট দেয়। আরও X-s/nউল্লেখযোগ্য বিষয় হল s, বিতরণটির উপর নির্ভর করা উচিত , তবে তা হয় না।
নাইট্রডন

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

1

হাস্কেল , 122 217 208 বাইট

import System.Random
r p=randomR p
(n#s)g|n<1=[]|(x,q)<-r(max 0$s-n+1,min 1 s)g=x:((n-1)#(s-x)$q)
g![]=[]
g!a|(i,q)<-r(0,length a-1)g=a!!i:q![x|(j,x)<-zip[0..]a,i/=j]
n%s=uncurry(!).(n#s<$>).split<$>newStdGen

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

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

বুনিয়াদি ধারণাটি একটি সংখ্যা তৈরি করা হয় xতারপরে এটিকে বিয়োগ করে পুনরায় পুনরায় sপুনরুক্ত করা হয় যতক্ষণ না আমাদের nউপাদান থাকে তারপরে সেগুলি পরিবর্তন করে না uff আমি একটির xউপরের বাউন্ডের সাথে 1 বা s(যেটি ছোট) এবং একটি নিম্ন বাউন্ড s-n+1বা 0 (যেটি বৃহত্তর) এর সাথে জেনারেট করি । নীচের সীমাটি সেখানে রয়েছে যাতে পরবর্তী পুনরাবৃত্তিতে sএখনও কম বা তার সমান n(উপজাত: s-x<=n-1-> s<=n-1+x-> s-(n-1)<=x-> s-n+1<=x) থাকবে।

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

EDIT2: বাইট গণনা এবং নির্দিষ্ট ধরণের সীমাবদ্ধতা উন্নত


3
ইউনিফর্ম নমুনাগুলি শৃঙ্খলা কখনও অভিন্ন বিতরণে নেতৃত্ব দেয় না (শেষ স্থানাঙ্কটি আপনার উদাহরণের তুলনায় প্রায় সর্বদা 0.99 এর চেয়ে বড় হয়)
michi7x7

@ michi7x7 আমি আপনার বক্তব্যটি দেখতে পাচ্ছি। আমি যদি তালিকাটি তৈরির পরে এর ক্রমটি বদলে দেই? আমার আরও পরিসংখ্যান ক্লাস নেওয়া উচিত ছিল
ব্যবহারকারীর 1472751

সংখ্যাগুলি খুব অভিন্ন দেখায় না। এখানে , 8 টি ফলাফল> 0.99, 1 টি 0.96, এবং শেষটি 0.8। এই এটা কিসের মত দেখায়।
স্টিভি গ্রিফিন

@ user1472751 বেশ কিছু ভাল উত্তর এখানে আছেন: stackoverflow.com/q/8064629/6774250
michi7x7

1
অভিন্নতা এখনও কিছু সমস্যা আছে এখানে দেখুন - এখানে অনেকগুলি শূন্য উত্পন্ন হয়েছে (1000% 500 থেকে সাজানো মানের প্লট)
অ্যাঙ্গস

1

হাস্কেল , 188 বাইট

import System.Random
import Data.List
n!s|s>n/2=map(1-)<$>n!(n-s)|1>0=(zipWith(-)=<<tail).sort.map(*s).(++[0,1::Double])<$>mapM(\a->randomIO)[2..n]>>= \a->if all(<=1)a then pure a else n!s

Ungolfed:

n!s
 |s>n/2       = map (1-) <$> n!(n-s)       --If total more than half the # of numbers, mirror calculation 
 |otherwise   = (zipWith(-)=<<tail)        --Calculate interval lengths between consecutive numbers
              . sort                       --Sort
              . map(*s)                    --Scale
              . (++[0,1::Double])          --Add endpoints
              <$> mapM(\a->randomIO)[2..n] --Calculate n-1 random numbers
              >>= \a->if all(<=1)a then pure a else n!s   --Retry if a number was too large

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

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