বিভাজন প্যারাডক্স


10

প্রদত্ত:

  • একটি প্রাকৃতিক সংখ্যা এস
  • এন যুক্তিযুক্ত ওজনের W এর তালিকা যা সমষ্টি 1।

ফিরুন একটি তালিকা এল এন অ নেতিবাচক পূর্ণসংখ্যার, এই ধরনের যে:

(1) sum(L) = S
(2) sum((S⋅W_i - L_i)^2) is minimal

অন্য কথায়, S⋅W_iযতটা সম্ভব নিকটতম পূর্ণসংখ্যার সাথে গুলি।

উদাহরণ:

1 [0.4 0.3 0.3] = [1 0 0]
3 [0 1 0] = [0 3 0]
4 [0.3 0.4 0.3] = [1 2 1]
5 [0.3 0.4 0.3] = [2 2 1] or [1 2 2] but not [1 3 1]
21 [0.3 0.2 0.5] = [6 4 11]
5 [0.1 0.2 0.3 0.4] = [1 1 1 2] or [0 1 2 2]
4 [0.11 0.3 0.59] = [1 1 2]
10 [0.47 0.47 0.06] = [5 5 0]
10 [0.43 0.43 0.14] = [4 4 2]
11 [0.43 0.43 0.14] = [5 5 1]

নিয়মাবলী:

  • আপনি যে কোনও ইনপুট ফর্ম্যাটটি একেবারে ব্যবহার করতে পারেন, বা কেবল এমন একটি ফাংশন সরবরাহ করতে পারেন যা ইনপুটটিকে আর্গুমেন্ট হিসাবে গ্রহণ করে।

পটভূমি:

এই সমস্যা যখন প্রদর্শন আসে আপ এস বিভিন্ন অনুপাতে আইটেম বিভিন্ন ধরনের ডব্লিউ আমি ধরনের ব্যাপারে।

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

একজন পরিসংখ্যানবিদ হিসাবে, আমি একটি স্তরিত নমুনা পরিচালনা করার সময় নমুনা আকার সনাক্তকরণে যে সমস্যার মুখোমুখি হয়েছিল তার সমতুল্য হিসাবে এই সমস্যাটি স্বীকৃতি দিয়েছি। সেই পরিস্থিতিতে আমরা নমুনায় প্রতিটি স্তরের অনুপাতকে জনসংখ্যার প্রতিটি স্তরের অনুপাতের সমান করতে চাই। - @ টমি


আপনি কি কথায় কথায় বলতে পারেন কাজটি কি? স্বজ্ঞাগত কিছুতে ভাবগুলি সংক্ষেপিত করতে আমার সমস্যা হচ্ছে।
xnor

উভয়ই ≤, স্থির হওয়া উচিত। কাজটি হল ওজনের উপর ভিত্তি করে পূর্ণসংখ্যার যোগফল হিসাবে একটি পূর্ণসংখ্যা উপস্থাপন করা। অবশিষ্টটি সর্বোচ্চ ওজনের পক্ষে বিতরণ করা উচিত, যদিও আমি নিশ্চিত নই যে এই প্রয়োজনীয়তাটি সঠিকভাবে এনকোড করা আছে? এটি আকর্ষণীয় কারণ round(A + B) != round(A) + round(B), একটি সংক্ষিপ্ত সমাধানের জন্য এখানে কী চলছে সে সম্পর্কে অন্তর্দৃষ্টি প্রয়োজন।
glebm

1
হয়তো দূরত্বের যোগফল কমানোর জন্য নিয়ম পরিবর্তন L[i] - S*W[i]নিয়ম 2 এবং নিয়ম 3. এই আনুমানিক হবে পরিবর্তে ছক S*W[i]
জাকুবে

1
এর [0 1 2 2] জন্য আরও একটি সম্ভাব্য সমাধান5 [0.1 0.2 0.3 0.4]
জাকুব

1
হতে পারে আপনার 1 এর জন্য একটি উদাহরণ যুক্ত করা উচিত [0.4 0.3 0.3]
অ্যাডিটসু প্রস্থান করুন কারণ এসই ইভিল

উত্তর:


6

এপিএল, 21

{{⍵+1=⍋⍋⍵-⍺}⍣⍺/⍺0×⊂⍵}

এটি আদিতসুর 37 বাইট সিজেএম উত্তর থেকে একটি অনুবাদ ।

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

ব্যাখ্যা

 {      ⍵-⍺}            ⍝ Right argument - left argument.
 {  1=⍋⍋⍵-⍺}            ⍝ Make one of the smallest number 1, others 0.
 {⍵+1=⍋⍋⍵-⍺}            ⍝ Add the result and the right argument together.
 {⍵+1=⍋⍋⍵-⍺}⍣⍺          ⍝ Repeat that S times. The result of each iteration is the new right argument.
                  ⊂⍵    ⍝ Return enclosed W, which is taken as one unit in APL.
               ⍺0×⊂⍵    ⍝ Return S*W and 0*W.
{{⍵+1=⍋⍋⍵-⍺}⍣⍺/⍺0×⊂⍵}   ⍝ Make S*W the left argument, 0*W the right argument in the first iteration.

7

পাইথন 2, 95 83 132 125 143

আমার প্রথম (এবং দ্বিতীয়) (এবং তৃতীয়) অ্যালগরিদমের সমস্যা ছিল সুতরাং একটি (অন্য!) পুনর্লিখন এবং আরও পরীক্ষার পরে, এখানে (আমি সত্যিই আশা করি) একটি সঠিক এবং দ্রুত সমাধান:

def a(b,h):
 g=h;c=[];d=[]
 for w in b:f=int(w*h);d+=[f];c+=[h*w-f];g-=f
 if g:
  for e in sorted(c)[-g:]:i=c.index(e);c[i]=2;d[i]+=1
 return d

মিনিফায়ারের আগে উত্সটি এখন দেখে মনে হচ্ছে:

# minified 143 bytes
def golfalloc(weights, num):
    # Tiny seq alloc for golfing
    gap = num;
    errors = [];
    counts = []
    for w in weights :
        count = int(w*num);
        counts += [count];
        errors += [num*w - count];
        gap -= count
    if gap:
        for e in sorted(errors)[-gap:] :
            i = errors.index(e);
            errors[i] = 2;
            counts[i] += 1
    return counts

পরীক্ষাগুলি ফিরে:

Pass                    Shape    N               Result Error                        AbsErrSum
ok            [0.4, 0.3, 0.3]    1            [1, 0, 0] -0.60,+0.30,+0.30                 1.20
ok                  [0, 1, 0]    3            [0, 3, 0] +0.00,+0.00,+0.00                 0.00
ok            [0.3, 0.4, 0.3]    4            [1, 2, 1] +0.20,-0.40,+0.20                 0.80
ok            [0.3, 0.4, 0.3]    5            [2, 2, 1] -0.50,+0.00,+0.50                 1.00
ok            [0.3, 0.2, 0.5]   21           [6, 4, 11] +0.30,+0.20,-0.50                 1.00
ok       [0.1, 0.2, 0.3, 0.4]    5         [1, 1, 1, 2] -0.50,+0.00,+0.50,+0.00           1.00
ok          [0.11, 0.3, 0.59]    4            [1, 1, 2] -0.56,+0.20,+0.36                 1.12
ok         [0.47, 0.47, 0.06]   10            [5, 5, 0] -0.30,-0.30,+0.60                 1.20
ok         [0.43, 0.43, 0.14]   10            [4, 4, 2] +0.30,+0.30,-0.60                 1.20
ok         [0.43, 0.43, 0.14]   11            [5, 5, 1] -0.27,-0.27,+0.54                 1.08

এই অ্যালগরিদম এখানে অন্যান্য উত্তর অনুরূপ। এটি সংখ্যার জন্য ও (1) তাই এটি 10 ​​এবং 1000000 এর পূর্ণসংখ্যার জন্য একই রান সময়। যদি এটি অন্য সমস্ত জটিল ইনপুট কেসগুলিকে প্রতিরোধ করে তবে এটি আমার প্রোগ্রামিং সরঞ্জামবক্সে নীচের অ্যালগরিদমটি প্রতিস্থাপন করবে।

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

def seqalloc(anyweights, num):
    # Distribute integer num depending on weights.
    # weights may be non-negative integers, longs, or floats.
    totalbias = float(sum(anyweights))
    weights = [bias/totalbias for bias in anyweights]
    counts = [int(w*num) for w in weights]
    gap = num - sum(counts)
    if gap:
        errors = [num*w - q for w,q in zip(weights, counts)]
        ordered = sorted(range(len(errors)), key=errors.__getitem__)
        for i in ordered[-gap:]:
            counts[i] += 1
    return counts

সংখ্যাটির মান গতিতে উল্লেখযোগ্যভাবে প্রভাব ফেলবে না। আমি 1 থেকে 10 ^ 19 পর্যন্ত মান সহ এটি পরীক্ষা করেছি। কার্যকর করার সময়টি ওজনের সংখ্যার সাথে সামঞ্জস্যভাবে পরিবর্তিত হয়। আমার কম্পিউটারে এটি 10 ​​^ 5 ওজন সহ 0.15 সেকেন্ড এবং 10 ^ 7 ওজনের সাথে 15 সেকেন্ড সময় নেয়। মনে রাখবেন যে ওজনগুলি একটির যোগফলের মধ্যে সীমাবদ্ধ নয়। এখানে ব্যবহৃত বাছাইয়ের কৌশলটি গতানুগতিক sorted((v,i) for i,v in enumerate...)শৈলীর চেয়ে দ্বিগুণ দ্রুত ।

আসল অ্যালগরিদম

এটি আমার সরঞ্জামবাক্সের একটি কাজ ছিল, গল্ফের জন্য কিছুটা পরিবর্তন করা হয়েছিল। এটি মূলত একটি এসও উত্তর থেকে হয়েছিল । এবং এটা ভুল।

def seqalloc(seq, num):
    outseq = []
    totalw = float(sum(seq))
    for weight in seq:
        share = int(round(num * weight / totalw)) if weight else 0
        outseq.append(share)
        totalw -= weight
        num -= share
    return outseq

এটি একটি আনুমানিক দেয়, তবে সর্বদা সঠিক হয় না, যদিও যোগফল (আউটসেক) == সংখ্যা বজায় থাকে। দ্রুত তবে প্রস্তাবিত নয়।

@Alephalpha এবং @ ব্যবহারকারী23013 কে ত্রুটিগুলি চিহ্নিত করার জন্য ধন্যবাদ।

সম্পাদনা: ওপেনের যোগফল সর্বদা ১ টি হবে বলে নির্দিষ্ট হিসাবে মোট (ডি) 1 হবে সেট করুন এখন 83 বাইট।

সম্পাদনা 2: [0.4, 0.3, 0.3], 1 এর জন্য স্থির ত্রুটি পাওয়া গেছে।

সম্পাদনা 3: ত্রুটিযুক্ত অ্যালগরিদম পরিত্যক্ত। আরও ভাল একটি যোগ করা হয়েছে।

সম্পাদনা 4: এটি হাস্যকর হয়ে উঠছে। সঠিক দ্বারা প্রতিস্থাপন (আমি সত্যিই আশা করি) অ্যালগরিদম।

EDIT5: এই অ্যালগরিদমটি ব্যবহার করতে পছন্দ করতে পারে এমন অন্যের জন্য নন-গোল্ফী কোড যুক্ত হয়েছে।


4
a([0.4, 0.3, 0.3], 1)প্রত্যাবর্তন [0, 1, 0], যখন সঠিক উত্তর [1, 0, 0]
আলেফাল্ফ

1
এখনও ভুল। a([0.11,0.3,0.59],4)ফিরে এসেছি [0, 1, 3]। হওয়া উচিত [1, 1, 2]
jimmy23013

1
f([0.47,0.47,0.06],10)ফিরে এসেছি [5, 4, 1]। হওয়া উচিত [5, 5, 0]
jimmy23013

2
আমি মনে করি এটি এখন সঠিক।
jimmy23013

2
@ কার্পেট পাইথন আমি এই অ্যালগরিদমের সাথে একই রকম প্রক্রিয়া চালিয়েছি এবং এইভাবেই আমি এই সমস্যাটি নিয়ে এসেছি। যদি তারা আপনার লাইসেন্সটি কেড়ে নেয় তবে তাদেরও আমার নেওয়া উচিত :)
glebm

4

গণিত, 67 50 46 45 অক্ষর

f=(b=⌊1##⌋;b[[#~Ordering~-Tr@#&[b-##]]]++;b)&

Ungolfed:

f[s_, w_] := Module[{a = s*w, b, c, d},
  b = Floor[a];
  c = b - a;
  d = Ordering[c, -Total[c]];
  b[[d]] += 1;
  b]

উদাহরণ:

f[5,{0.1,0.2,0.3,0.4}]

{1, 1, 1, 2}


আমার ধার্মিকতা, এটি ম্যাথমেটিকাকে বিবেচনা করে সংক্ষেপে!
ডেভিডসি

3

সিজোম - 37

q~:W,0a*\:S{[_SWf*]z::-_:e<#_2$=)t}*p

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

ব্যাখ্যা:

q~             read and evaluate the input
               (pushing the number and the array on the stack)
:W,            save the array in variable W and calculate its length (N)
0a*            make an array of N zeros (the initial "L")
\:S            swap it with the number and save the number in S
{…}*           execute the block S times
    [_SWf*]    make a matrix with 2 rows: "L" and S*W
    z          transpose the matrix, obtaining rows of [L_i S*W_i]
    ::-_       convert to array of L_i-S*W_i and duplicate
    :e<        get the smallest element
    #          find its index in the unsorted array,
               i.e. the "i" with the largest S*W_i-L_i
    _2$=)t     increment L_i
p              print the result nicely

মন্তব্য:

  • জটিলতা ও (এস * এন) সম্পর্কে, সুতরাং এটি বড় এস এর জন্য সত্যিই ধীর হয়ে যায়
  • সিজেএমের 2 টি অ্যারেগুলির জন্য খুব গা ar়ভাবে গাণিতিক অপারেটরগুলির ঘাটতি রয়েছে, যা আমি পরে বাস্তবায়নের পরিকল্পনা করছি

বিভিন্ন ধারণা - 46

q~:Sf*_:m[_:+S\-@[1f%_,,]z{0=W*}$<{1=_2$=)t}/p

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

এটি অনেক বেশি সোজা এবং দক্ষ, কিন্তু হায়, বেশ খানিকটা দীর্ঘ। এখানে ধারণাটি হল L_i = তল (এস * ডাব্লু_আই) দিয়ে শুরু করা, এস এবং তাদের যোগফলের মধ্যে পার্থক্য নির্ধারণ করুন (ডি বলুন) নির্ধারণ করুন, এস * ডাব্লু_আই এর বৃহত্তম ভগ্নাংশের সাথে ডি সূচকগুলি সন্ধান করুন (শীর্ষ ডি বাছাই করে) এবং সূচকগুলির জন্য বৃদ্ধি এল_আই। জটিলতা হে (এন * লগ (এন))।


এখন ও (এন) আছে :e<
jimmy23013

@ ইউজার ২৩০১৩ ওহ হ্যাঁ, প্রথম প্রোগ্রামের জন্য ধন্যবাদ
অদিতসু ছেড়ে গেছে কারণ এসই ইভিল

সেটা দ্রুত ছিল! অভিনন্দন 🌟
glebm

যারা ভাবছেন তাদের ক্ষেত্রে, বাছাইয়ের সময়টি লিনিয়ার সময় নির্বাচনের অ্যালগরিদম দিয়ে সৃজন করার ফলে প্রকৃত ও (এনলন) এর পরিবর্তে ও (এন) পাওয়া যাবে: ডি-থ্রি বৃহত্তম উপাদান, পি, ও (এন) এর মধ্যে অনুসন্ধান করুন, তারপরে বৃদ্ধি উপাদানগুলি যা <PD বার (O (N) থেকে ডি <= এন)।
glebm

@glebm এটি বেশ দুর্দান্ত, তবে আমি মনে করি একাধিক উপাদানগুলির একই মান (পি) থাকলে সমস্যা আছে। তখন আপনি এটি 2 টি পাসে সমাধান করতে পারেন: প্রথমে বৃদ্ধি এবং উপাদানগুলি> পি গণনা করুন, তারপরে আপনি জানেন কতগুলি উপাদান = পি প্রয়োজন। অথবা আপনি যদি নির্বাচন অ্যালগরিদম থেকে আরও ভাল তথ্য পেতে পারেন।
অ্যাডিটসু ছেড়ে গেছে কারণ এসই এভিল

3

জাভাস্ক্রিপ্ট (ES6) 126 130 104 115 156 162 194

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

ওজন ডাব্লু এর প্রতিটি আউটপুট উপাদানগুলির জন্য সম্পাদনা করুন , 'সমস্ত' সম্ভাব্য মানগুলি কেবল 2: ট্রাঙ্ক (ডাব্লু * গুলি) এবং ট্রাঙ্ক (ডাব্লু * গুলি) +1, সুতরাং চেষ্টা করার জন্য কেবল (2 ** এলেমেনস্ট) সম্ভাব্য সমাধান রয়েছে।

Q=(s,w)=>
  (n=>{
    for(i=0;
        r=q=s,(y=i++)<1<<w.length;
        q|r>n||(n=r,o=t))
      t=w.map(w=>(f=w*s,q-=d=0|f+(y&1),y/=2,f-=d,r+=f*f,d));
  })()||o

টেস্ট সালে ফায়ারফক্স / ফায়ারবাগ কনসোলটি

;[[ 1,  [0.4, 0.3, 0.3]      ]
, [ 3,  [0, 1, 0]            ]
, [ 4,  [0.3, 0.4, 0.3]      ]
, [ 5,  [0.3, 0.4, 0.3]      ]
, [ 21, [0.3, 0.2, 0.5]      ]
, [ 5,  [0.1, 0.2, 0.3, 0.4] ]
, [ 4,  [0.11, 0.3, 0.59]    ]
, [ 10, [0.47, 0.47, 0.06]   ]
, [ 10, [0.43, 0.43, 0.14]   ]
, [ 11, [0.43, 0.43, 0.14]   ]]
.forEach(v=>console.log(v[0],v[1],Q(v[0],v[1])))

আউটপুট

1 [0.4, 0.3, 0.3] [1, 0, 0]
3 [0, 1, 0] [0, 3, 0]
4 [0.3, 0.4, 0.3] [1, 2, 1]
5 [0.3, 0.4, 0.3] [1, 2, 2]
21 [0.3, 0.2, 0.5] [6, 4, 11]
5 [0.1, 0.2, 0.3, 0.4] [0, 1, 2, 2]
4 [0.11, 0.3, 0.59] [1, 1, 2]
10 [0.47, 0.47, 0.06] [5, 5, 0]
10 [0.43, 0.43, 0.14] [4, 4, 2]
11 [0.43, 0.43, 0.14] [5, 5, 1]

এটি একটি স্মার্ট সমাধান। ওয়েলথ অ্যারেতে একক পাস।
প্রতিটি পাসের জন্য আমি ডাব্লুতে বর্তমান সর্বাধিক মান খুঁজে পাই। আমি এই মানটি ওজনিত পূর্ণসংখ্যার মান (গোলকৃত) সহ জায়গায় পরিবর্তন করেছি, সুতরাং যদি s == 21 এবং ডাব্লু = 0.4 হয় তবে আমরা 0.5 * 21 -> 10.5 -> ১১ পেয়েছি this পরের লুপে সর্বাধিক হিসাবে পাওয়া যাবে। তারপরে আমি সেই অনুযায়ী মোট যোগফল হ্রাস করব (s = s-11) এবং ভেরিয়েবল এফের ওজনের মোট সংখ্যাও হ্রাস করব।
লুপটি যখন সর্বাধিক 0 থেকে উপরে না পাওয়া যায় তখন শেষ হয় (সমস্ত মান! = 0 পরিচালিত হয়েছে)।
অবশেষে আমি মানগুলি আবার ইতিবাচক হিসাবে ফিরিয়ে দিয়েছি। এই কোডটি সতর্ক করে দেওয়া জায়গায় ওজনের অ্যারেটিকে সংশোধন করে, সুতরাং এটি অবশ্যই মূল অ্যারের অনুলিপি সহ কল ​​করা উচিত

F=(s,w)=>
 (f=>{
  for(;j=w.indexOf(z=Math.max(...w)),z>0;f-=z)
    s+=w[j]=-Math.ceil(z*s/f);
 })(1)||w.map(x=>0-x)

আমার প্রথম চেষ্টা

এত স্মার্ট সমাধান নয়। প্রতিটি সম্ভাব্য ফলাফলের জন্য, এটি পার্থক্যটি মূল্যায়ন করে এবং সর্বনিম্ন রাখে।

F=(s,w,t=w.map(_=>0),n=NaN)=>
  (p=>{
    for(;p<w.length;)
      ++t[p]>s?t[p++]=0
      :t.map(b=>r+=b,r=p=0)&&r-s||
        t.map((b,i)=>r+=(z=s*w[i]-b)*z)&&r>n||(n=r,o=[...t])
  })(0)||o

Ungolfed এবং ব্যাখ্যা

F=(s, w) =>
{
  var t=w.map(_ => 0), // 0 filled array, same size as w
      n=NaN, // initial minumum NaN, as "NaN > value"  is false for any value
      p, r
  // For loop enumerating from [1,0,0,...0] to [s,s,s...s]
  for(p=0; p<w.length;)
  {
    ++t[p]; // increment current cell
    if (t[p] > s)
    {
      // overflow, restart at 0 and point to next cell
      t[p] = 0;
      ++p;
    }
    else
    {
      // increment ok, current cell is the firts one
      p = 0;
      r = 0;
      t.map(b => r += b) // evaluate the cells sum (must be s)
      if (r==s)
      {
        // if sum of cells is s
        // evaluate the total squared distance (always offset by s, that does not matter)
        t.map((b,i) => r += (z=s*w[i]-b)*z) 
        if (!(r > n))
        {
          // if less than current mininum, keep this result
          n=r
          o=[...t] // copy of t goes in o
        }
      }
    }
  }
  return o
}

2

সিজেম, 48 বাইট

সমস্যার সরাসরি সমাধান।

q~:Sf*:L,S),a*{m*{(+}%}*{1bS=},{L]z::-Yf#:+}$0=p

ইনপুট মত যায়

[0.3 0.4 0.3] 4

ব্যাখ্যা:

q~:S                                 "Read and parse the input, store sum in S";
    f*:L                             "Do S.W, store the dot product in L";
         S),                         "Get array of 0 to S";
        ,   a*                       "Create an array with N copies of the above array";
              {m*{(+}%}*             "Get all possible N length combinations of 0 to S ints";
                        {1bS=},      "Filter to get only those which sum up to S";
{L]z::-Yf#:+}$                       "Sort them based on (S.W_i - L_i)^2 value";
 L                                   "Put the dot product after the sum combination";
  ]z                                 "Wrap in an array and transpose";
    ::-                              "For each row, get difference, i.e. S.W_i - L_i";
       Yf#                           "Square every element";
          :+                         "Take sum";
              0=p                    "After sorting on sum((S.W_i - L_i)^2), take the";
                                     "first element, i.e. smallest sum and print it";

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


2

পাইথ: 40 বাইট

Mhosm^-*Ghded2C,HNfqsTGmms+*G@Hb}bklHyUH

এটি g2 পরামিতি সহ একটি ফাংশন সংজ্ঞায়িত করে । আপনি এটি পছন্দ করতে পারেন Mhosm^-*Ghded2C,HNfqsTGmms+*G@Hb}bklHyUHg5 [0.1 0.2 0.3 0.4

এটি অনলাইনে ব্যবহার করে দেখুন: পাইথ কমপাইলার / এক্সিকিউটার

ব্যাখ্যা:

mms+*G@Hb}bklHyUH     (G is S, H is the list of weights)
m             yUH    map each subset k of [0, 1, ..., len(H)-1] to:
 m          lH          map each element b of [0, 1, ..., len(H)-1] to: 
    *G@Hb                  G*H[b]
   +     }bk               + b in k
  s                       floor(_)

এই সব সম্ভাব্য সমাধান সৃষ্টি L, যেখানে L[i] = floor(S*W[i])বা L[i] = floor(S*W[i]+1)। উদাহরণস্বরূপ, ইনপুট 4 [0.3 0.4 0.3তৈরি করে [[1, 1, 1], [2, 1, 1], [1, 2, 1], [1, 1, 2], [2, 2, 1], [2, 1, 2], [1, 2, 2], [2, 2, 2]]

fqsTG...  
f    ... only use the solutions, where
 qsTG       sum(solution) == G

শুধু [[2, 1, 1], [1, 2, 1], [1, 1, 2]]থাকবে।

Mhosm^-*Ghded2C,HN
  o                  order the solutions by
   s                   the sum of 
    m         C,HN       map each element d of zip(H, solution) to
     ^-*Ghded2           (G*d[0] - d[1])^2
 h                   use the first element (minimum)
M                    define a function g(G,H): return _

2

গণিত 108

s_~f~w_:=Sort[{Tr[(s*w-#)^2],#}&/@ 
Flatten[Permutations/@IntegerPartitions[s,{Length@w},0~Range~s],1]][[1,2]]

f[3, {0, 1, 0}]
f[4, {0.3, 0.4, 0.3}]
f[5, {0.3, 0.4, 0.3}]
f[21, {0.3, 0.2, 0.5}]
f[5, {0.1, 0.2, 0.3, 0.4}]

{0, 3, 0}
{1, 2, 1}
{1, 2, 2}
{6, 4, 11}
{0, 1, 2, 2


ব্যাখ্যা

Ungolfed

f[s_,w_]:=
Module[{partitions},
partitions=Flatten[Permutations/@IntegerPartitions[s,{Length[w]},Range[0,s]],1];
Sort[{Tr[(s *w-#)^2],#}&/@partitions][[1,2]]]

IntegerPartitions[s,{Length@w},0~Range~s]sসেট থেকে নেওয়া উপাদানগুলি ব্যবহার করে প্রতিরোধের সমস্ত পূর্ণসংখ্যা পার্টিশন প্রদান করে {0, 1, 2, ...s}যে আউটপুটটিতে ওজনের সেটগুলির মতো একই সংখ্যক উপাদান থাকা উচিত w

Permutations প্রতিটি পূর্ণসংখ্যা বিভাজনের সমস্ত আদেশকৃত ব্যবস্থা দেয়।

{Tr[(s *w-#)^2],#}{error, permutation} প্রতিটি অনুক্রমের জন্য আদেশযুক্ত জোড়গুলির একটি তালিকা প্রদান করে ।

Sort[...] তালিকা অনুসারে বাছাই করে {{error1, permutation1},{error2, permutation2}...according to the size of the error.

[[1,2]]]বা Part[<list>,{1,2}]সাজানো তালিকায় প্রথম উপাদানটির দ্বিতীয় আইটেমটি প্রদান করে {{error, permutation}...}। অন্য কথায়, এটি ক্ষুদ্রতম ত্রুটির সাথে অনুমতিটি প্রদান করে।


2

আর, 85 80 76

হরে কোটা পদ্ধতি ব্যবহার করে।

ডাব্লু 1 এর যোগফল হবে এমন অনুমান দেখে কিছুটা সরানো হয়েছে

function(a,b){s=floor(d<-b*a);s[o]=s[o<-rev(order(d%%1))[0:(a-sum(s))]]+1;s}

টেস্ট রান

> (function(a,b){s=floor(d<-b/(sum(b)/a));s[o]=s[o<-rev(order(d%%1))[0:(a-sum(s))]]+1;s})(3,c(0,1,0))
[1] 0 3 0
> (function(a,b){s=floor(d<-b/(sum(b)/a));s[o]=s[o<-rev(order(d%%1))[0:(a-sum(s))]]+1;s})(1,c(0.4,0.3,0.3))
[1] 1 0 0
> (function(a,b){s=floor(d<-b/(sum(b)/a));s[o]=s[o<-rev(order(d%%1))[0:(a-sum(s))]]+1;s})(4,c(0.3, 0.4, 0.3))
[1] 1 2 1
> (function(a,b){s=floor(d<-b/(sum(b)/a));s[o]=s[o<-rev(order(d%%1))[0:(a-sum(s))]]+1;s})(5,c(0.3, 0.4, 0.3))
[1] 1 2 2
> (function(a,b){s=floor(d<-b/(sum(b)/a));s[o]=s[o<-rev(order(d%%1))[0:(a-sum(s))]]+1;s})(21,c(0.3, 0.2, 0.5))
[1]  6  4 11
> (function(a,b){s=floor(d<-b/(sum(b)/a));s[o]=s[o<-rev(order(d%%1))[0:(a-sum(s))]]+1;s})(5,c(0.1,0.2,0.3,0.4))
[1] 1 1 1 2
>

2

পাইথন, 139 128 117 বাইট

def f(S,W):
 L=(S+1,0,[]),
 for n in W:L=[(x-i,y+(S*n-i)**2,z+[i])for x,y,z in L for i in range(x)]
 return min(L)[2]

পূর্ববর্তী এরটুলস সমাধান, 139 বাইট

from itertools import*
f=lambda S,W:min((sum(x)!=S,sum((S*a-b)**2for a,b in zip(W,x)),list(x))for x in product(*tee(range(S+1),len(W))))[2]

আমি ভাবছিলাম যে এটির কোনও সমাধান সমাধান সম্ভব কিনা। দুর্দান্ত কাজ +1। আমি কি এই ভাবতে ঠিক আছি যে এটিতে (n 4) সময়ের জটিলতা রয়েছে?
লজিক নাইট

Itertools সমাধান O(S^len(W))আসলে ছিল : পি। নতুন সমাধানটি অনেক দ্রুত, তবে এখনও ধীর
স্প 3000

2

অক্টাভা, 87 76

Golfed:

function r=w(s,w)r=0*w;for(i=1:s)[m,x]=max(s*w-r);r(x)+=1;endfor endfunction

Ungolfed:

function r=w(s,w)
  r=0*w;   # will be the output
  for(i=1:s)
    [m,x]=max(s*w-r);
    r(x)+=1;
  endfor
endfunction

(ব্লাস্টড "এন্ডফোর" এবং "এন্ড ফাংশন"! আমি কখনই জিততে পারি না তবে আমি "বাস্তব" ভাষা নিয়ে গল্ফ উপভোগ করি))


চমৎকার অ্যালগরিদম। আপনি প্রতিস্থাপন করতে পারেন zeros(size(w))সঙ্গে 0*w
আলেফাল্ফ

নিস! কেন আমি তা ভেবে দেখিনি?
ডিসিএসএইচএল

1

টি-এসকিউএল, 167 265

কারণ আমিও এই প্রশ্নগুলিতে একটি চ্যালেঞ্জ চেষ্টা করতে এবং করতে চাই।

স্পেকটি আরও ভালভাবে ফিট করার জন্য এটিকে একটি ইনলাইন ফাংশনে পরিণত করেছে এবং টেবিলের ডেটার জন্য একটি প্রকার তৈরি করেছে। এটি একটি সামান্য ব্যয়, কিন্তু এটি কখনও প্রতিযোগী হতে যাচ্ছিল না। প্রতিটি বিবৃতি পৃথকভাবে চালানো প্রয়োজন।

CREATE TYPE T AS TABLE(A INT IDENTITY, W NUMERIC(9,8))
CREATE FUNCTION W(@ int,@T T READONLY)RETURNS TABLE RETURN SELECT CASE WHEN i<=@-SUM(g)OVER(ORDER BY(SELECT\))THEN g+1 ELSE g END R,A FROM(SELECT A,ROW_NUMBER()OVER(ORDER BY (W*@)%1 DESC)i,FLOOR(W*@)g FROM @T)a

ব্যাবহৃত হচ্ছে

DECLARE @ INT = 21
DECLARE @T T
INSERT INTO @T(W)VALUES(0.3),(0.2),(0.5)
SELECT R FROM dbo.W(@,@T) ORDER BY A

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