Kitap yığını sırala


21

Kitapları istiflerken genellikle en büyükleri, en küçükleri de en üste koymak istersiniz. Bununla birlikte, gizli OKB'm, biri kısa olan fakat diğerinden daha geniş olan iki kitabım varsa, beni çok rahatsız ediyor. Onları hangi sıraya koyarsam ver, üst kitap bir tarafta alt kitabın ötesine uzanacak.

Örnek olarak, bir kitabın boyutları var (10,15), diğeri boyutlar (11,14). Hangi tarafa koyarsam sürsünlerim, çıkıntı alırım. Ama boyutlara sahip kitaplar varsa (4,3)ve (5,6)ben eski aşağıda ikincisi yerleştirerek bir sarkan önleyebilirsiniz.

Bu zorluğun amaçları doğrultusunda, sadece derhal aşağıdaki kitapla ilgili çıkıntıları dikkate alacağız . Örneğin ben bir yığın varsa (5,5), (3,3), (4,4)(aklı başında herkes bunu yapabilir değil), bir çıkıntı gibi üst kitap sayar, bu alt kitabın ötesine geçmez rağmen. Benzer şekilde, yığın (3,3), (3,3), (4,4)ayrıca alt birinin ötesine uzanan üst kitabında rağmen sadece bir çıkıntıya sahiptir.

Meydan okuma

Kitap boyutları için bir tamsayı çifti listesi verildiğinde, bu çiftleri / kitapları, çıkma sayısının minimum olacağı şekilde sıralayın. Kitapları döndürmemelisiniz - tüm dikenlerin aynı yöne bakmasını istiyorum. Aynı sarkma sayısına sahip birden fazla çözüm varsa, böyle bir sipariş seçebilirsiniz. Sıralama algoritmanızın kararlı olması gerekmez. Uygulamanız, kitap boyutlarının her birinin 2 16'dan küçük olduğunu varsayabilir .

Zaman karmaşıklığı: Bunu biraz daha ilginç hale getirmek için, algoritmanızın asimptotik en kötü durum karmaşıklığı yığının boyutunda polinom olmalıdır. Yani sadece her olası permütasyonu test edemezsin Lütfen algoritmanızın optimizasyonunun ve karmaşıklığının kısa bir kanıtını ve isteğe bağlı olarak büyük rasgele girdiler için ölçeklendirmeyi gösteren bir çizim ekleyin. Tabii ki, girişin maksimum boyutunu, kodunuzun O (1) 'de çalıştığını belirtmek için kullanamazsınız.

Herhangi bir uygun (önceden işlenmemiş) liste biçiminde bir program veya işlev yazabilir, STDIN, ARGV veya function argümanından giriş alabilir ve sonucu yazdırabilir veya geri döndürebilirsiniz.

Bu kod golf, yani en kısa cevap (bayt cinsinden) kazanır.

Polinom çözümünün var olduğuna inanıyorum, ancak beni yanlış ispat ederseniz, golf gönderimi yerine böyle bir kanıt sunabilirsiniz. Bu durumda, P ≠ NP olabilir . İlk doğru kanıtı kabul edeceğim ve ona bir ödül vereceğim.

Örnekler

In:  [[1, 1], [10, 10], [4, 5], [7, 5], [7, 7], [10, 10], [9, 8], [7, 5], [7, 5], [3, 1]]
Out: [[10, 10], [10, 10], [9, 8], [7, 7], [7, 5], [7, 5], [7, 5], [4, 5], [3, 1], [1, 1]]

In:  [[4, 5], [5, 4], [5, 4], [5, 4], [5, 4], [4, 5], [4, 5], [4, 5], [5, 4], [4, 5]]
Out: [[4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [5, 4], [5, 4], [5, 4], [5, 4], [5, 4]]
  or [[5, 4], [5, 4], [5, 4], [5, 4], [5, 4], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5]]

In:  [[2, 3], [1, 1], [5, 5], [7, 1]]
Out: [[5, 5], [2, 3], [7, 1], [1, 1]]
 or  [[5, 5], [2, 3], [1, 1], [7, 1]]
 or  [[7, 1], [5, 5], [2, 3], [1, 1]]
 or  [[7, 1], [1, 1], [5, 5], [2, 3]]

Bunları el ile yaptım, bu yüzden herhangi bir hata görürseniz haberim olsun.


3
Polinom zamanında asgari sayıda çıkıntı içeren bir çözüm bulmanın çözülebileceğinden emin misiniz?
COTO

@COTO Kendime oldukça güveniyorum, evet.
Martin Ender

Hmm. Normalde açgözlü bir algoritma ile ele alırdım, ancak bulabildiğim herhangi bir "açgözlü" kriter için düşük çıktılara yol açan girdileri kolaylıkla temin edebilirim (örneğin alan, bir boyutu maksimuma çıkarmak, en küçük boyutu maksimuma çıkarmak vb.). Tek düşünebildiğim diğer yaklaşımlar kitapların kliklere bölünmesini de içeriyor ve hepsinde üstel en kötü durum karmaşıklığı var. Hangi cevapların geldiğini görmek isterim. Ayrıca, spesifikasyonun bir parçası olarak, sıralamadaki iyimserliğin kısa bir kanıtını da isteyebilirsiniz.
COTO

@COTO Aslında yanlış olduğum için bununla ilgili bir paragraf ekledim, ama buna güvenme. ;)
Martin Ender

Bu durumda, hiçbir polinom-zaman algoritması bulunmadığına dair potansiyel kanıtların, P'nin NP'ye eşit olmadığını varsaymasına izin verilmeli.
xnor

Yanıtlar:


2

Pyth , 30

FN_SQFbYIgeeYeb~b]NB)E~Y]]N;sY

Bu, grc'ın harika algoritmasının doğrudan golfüdür. İşte derlenmiş python kodunda, yukarıdaki pyth programının tam eşdeğeri.

Q = eval(input())
Y = []
for N in sorted(Q)[::-1]:
     for b in Y:
         if Y[-1][-1] >= b[-1]:
             b += [N]
             break
     else:
         Y += [[N]]
print(Psum(Y))

Bu bağlamda, Psum(Y)işlev python ile eşdeğerdir sum(Y,[]).

Gerçek derlenmiş ve kodunu çalıştırın (from pyth -d):

Y=[]
Q=copy(eval(input()))
for N in neg(Psorted(Q)):
 for b in Y:
  if gte(end(end(Y)),end(b)):
   b+=[N]
   break
 else:
  Y+=[[N]]
Pprint("\n",Psum(Y))

1
Python çevirisinin "Y = []" olması gerekiyor, Python 2'deyseniz değerlendirmeyi kaldırın ve toplamın ikinci bir argümana ihtiyacı var sum(Y,[]). Bunların hepsi Pyth'te çalışmalı, sadece çeviri otomatik olarak içermiyor.
xnor

@xnor son satırı gerçekten okur: Pprint("\n",Psum(Y)). Sanırım kolaylık sağlamak için sadeleştirmiş olabilir, sanki -1s vb. PsumAslında daha çok çalışacaktı reduce(lambda x,y:x+y, Y[1:], Y[0]).
FryAmTheEggman

20

Python, 113

P=[]
for n in sorted(input())[::-1]:
 for p in P:
  if p[-1][1]>=n[1]:p+=[n];break
 else:P+=[[n]]
print sum(P,[])

Kitapların listesini azalan düzende sıraladıktan sonra (önce genişlik ve sonra yükseklik), bu kitapların üst üste gelmeden yığınlara bölünmesine neden olur. Her kitabın nereye yerleştirileceğini belirlemek için, yüksekliği her bir yığındaki en üst kitabın yüksekliği ile karşılaştırılır. Mümkün olan ilk yığına yerleştirilir ya da yeni bir yığın oluşturulur.

Zaman karmaşıklığı konusunda pek iyi değilim, ancak en kötü durumda O ( N 2 ) olacağına inanıyorum . Her biri en fazla N yinelemeye sahip iki döngü vardır . Ayrıca Python'un O ( n log n ) olan yerleşik türünü kullanıyorum .


Bu algoritmanın optimal çözümler ürettiğine dair ilk kanıtım yanlış olduğu ortaya çıktı. Büyük bir teşekkür, @xnor ve @ Sp3000'e gider ve sohbette bu konuyla ilgili ( burada başlayarak okuyabileceğiniz ) harika bir tartışma sunar . Doğru bir kanıt yaptıktan sonra @ xnor, bir kısmının zaten yapıldığını buldu ( Dilworth teoremi ).

İşte yine de ispatın bir özeti (@xnor ve @ Sp3000’e verilen kredi).

İlk önce, bir antipile veya antichain kavramını tanımladık ( alıntı @xnor ):

Bir antipile yüksekliği azalan fakat genişlik artan bir kitap dizisidir
So her başarılı kitap kesinlikle uzun boylu ama kesinlikle daha az genişliğinde
Not dair bir antipile başka kitabın üzerine bir antipile çıkıntılar herhangi bir kitap
, bir antipile kutu içinde Yani, iki kitap Aynı
yığında olması Sonuç olarak, eğer bir x kitap antipilini bulabilirseniz, o zaman bu kitaplar farklı yığınlarda olmalıdır.
Yani, en büyük antipilin büyüklüğü kazık sayısına bağlı

Daha sonra kitapları azalan sırayla genişliklerine (ilk) ve yüksekliklerine (ikinci) * göre sıralarız.

Her kitap B için aşağıdakileri yaparız:

  1. Eğer B ilk yığına sığabilirse, oraya yerleştirip devam ederiz.
  2. Aksi takdirde, en erken * kazık bulmak x B üstüne yerleştirilebilir. Gerekirse bu yeni bir yığın olabilir.
  3. Sonra, bağlantı B için P , P önceki yığınının üzerine üst kitaptır 1 - x .
  4. Şimdi bunu biliyoruz:
    • B kesinlikle * P'den daha küçüktür , çünkü kitaplar genişliğe göre azalan sırada
    • B , P'den kesinlikle yüksektir , yoksa B'yi P'nin üstüne yerleştirirdik .

Şimdi, her kitaptan (ilk yığında olanlar hariç), önceki yığında daha geniş ve daha düşük yükseklikte bir kitap olan bir bağlantı kurduk.

@ Sp3000'ın mükemmel şeması bu durumu göstermektedir:

Son yığından (sağda), ilk yığına (solda) giden herhangi bir yolu izleyerek bir antipile alırız. Önemli olarak, bu antipilin uzunluğu kazık sayısına eşittir. Bu nedenle, kullanılan yığınların sayısı minimumdur.

Son olarak, kitapları üst üste binmeden en az sayıda yığın halinde düzenlediğimiz için, üst üste binen en az sayıda üst üste binen bir yığın elde etmek için üst üste yığabiliriz.

* Bu faydalı yorum birkaç şeyi açıklıyor


3
Açıklayıcı kanıt için +1 ve tartışmaya bağlantı. Xnor ve ark.
COTO

Dilworth Teoreminin tüm kanıtı kapsamadığını, sadece en az kazık sayısının en büyük boyuttaki antipere eşit olduğu gerçeğini açıklığa kavuşturmalıyım.
xnor
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.