Mesafe ile ilgili olmayan bir maliyeti en aza indirirken bir sayı çizgisinde ziyaret noktaları


18

Bu ACM ICPC sorununda yardıma ihtiyacım var. Şu anki fikrim, bunu sorun ifadesi altında açıklanan en kısa yol problemi olarak modellemek.

Sorun

Var N = 1000bir 1-D numarası hattı boyunca yer alan nükleer atık kaplar farklı pozisyonlarında -500,000 to 500,000hariç x=0. Bir kişi tüm çöp kutularını toplamakla görevlendirilir. Atık kabının toplanmadığı her saniye 1 birim radyasyon yayar. Kişi başlar x = 0ve 1birimi her saniye hareket ettirebilir ve atıkların toplanması ihmal edilebilir bir zaman alır. Tüm kapları toplarken açığa çıkan minimum radyasyon miktarını bulmak istiyoruz.

Örnek Giriş:

4Kapsayıcılar [-12, -2, 3, 7].

Bu kapları toplamak için en iyi emir [-2, 3, 7, -12], en az 50birim yaymaktır . Açıklama: Kişi -22 saniye içinde gider ve bu süre zarfında 2 unitsradyasyon yayılır. Daha sonra 3(mesafe :) 'a gider, 5böylece namlu 2 + 5 = 7radyasyon birimleri yayınlar. O namlunun birimler yaydığı yere 4ulaşmak için daha fazla zaman alıyor . O namlunun birimler yaydığı yere ulaşmak için saniyeler alır . , cevap budur.x = 72 + 5 + 4 = 1119x = -122 + 5 + 4 + 19 = 302 + 7 + 11 + 30 = 50

notlar

Açık bir O(N!)çözüm var. Ancak, en yakın olana geçmek veya en yakın kümeye gitmek gibi açgözlü yöntemleri araştırdım ama bunlar işe yaramadı.

Bu problemi bir süredir düşündüm ve bir grafik arama problemi olarak modelledim:

  1. Bu insert 0bir temel pozisyonda olarak (bu ilk durum olacaktır)
  2. Sonra pozisyonları en azdan en büyüğe doğru sıralarız.
  3. Sonra bir BFS / PFS, do stateoluşur
    • İki tamsayı lve rsıralanmış konum dizisinde daha önce ziyaret ettiğimiz bitişik bir aralığı temsil ediyor
    • locAralığın sol veya sağ uç noktasında olup olmadığımızı bize bildiren bir tam sayı
    • timeGeçen süreyi gösteren bir tam sayı
    • Bize şu ana kadar toplam maliyeti bildiren bir tam sayı 'maliyeti' (ziyaret ettiğimiz düğümlere dayanarak)
  4. Her durumdan, diğer 3 tamsayıyı buna göre ayarlayarak [l - 1, r] ve [l, r + 1] 'e geçebiliriz
  5. Son durum [0, N] olup her iki bitiş konumunu da kontrol eder.

Ancak, [L, R, loc]bir devleti benzersiz bir şekilde tanımlamıyor gibi görünüyor ve bunların her birini L, R, loc, and timeen aza indirirken depolamamız gerekiyor cost. Bu, herhangi bir mal için hala çok yavaş olan üstel bir algoritmaya yol açar.

Biri fikrimi genişletmeme veya doğru yönde itmeme yardımcı olabilir mi?

Düzenleme: Belki bu dinamik bir programlama optimizasyonu sorunu olarak modellenebilir? Bunu düşünmek, grafik arama çözümü ile aynı sorunlara sahiptir - akımın costdüşük olması, bu alt problem için en uygun cevap olduğu anlamına gelmez, çünkü timeyanıtı da büyük ölçüde etkiler.

Açgözlü çalışmıyor: Belirli bir yere taşınmanın maliyetini tahmin eden açgözlü bir seçim algoritmam var (örneğin sağa hareket edersek, mesafeleri sol varillere ve ikiye katlıyoruz).

Bir sezgisel tarama ile önce Öncelikli bir arama yapabilir misiniz? Buluşsal yöntem, mevcut seyahatin maliyetini geçen zamanla birleştirebilir.


En Kısa Yol Algoritmaları'na ne dersiniz? Dijkstra'nın algoritması gibi mi?
suraj_fale

Bunu denedim, ama bence gerçekten yanlış bir şey yapıyorum. Altta bulunan algoritmamı (öncelikli ilk arama veya BFS idi) numaralı listeyle açıkladım.
Barron

Bu size yardımcı olabilir ... stackoverflow.com/q/14639346/585398
suraj_fale

Maalesef, bu iki sorunun nasıl ilişkili olduğunu anlamıyorum. Açıklayabilir misin?
Barron

2
Bu bir ACM ICPC uygulama problemidir, gerçek yaşam problemi değildir. Başka bir notta, devleti azaltmaya çalıştım ama boşuna. Bir DP çözümü yazmaya çalıştım ama bu da işe yaramadı. Devlet L, R, POS idi.
Barron W.Mar

Yanıtlar:


4

Sorunu pozisyon çiftlerinin yönlendirilmiş bir grafiği olarak inceleyerek bunu geliştirebileceğinizi düşünüyorum.

Bu örnek için -9, -6, -1, 3 ve 5 değerlerini içeren satırı kullanacağım.

Sadece metin içeren bir grafik çizmek çok zor olduğundan, çiftleri tablo olarak göstereceğim. Hücreleri, bu iki konum arasındaki tüm kapların toplandığı durumu temsil ettiğini düşünebiliriz. Her bir hücrenin iki değeri vardır, biri sola gitme maliyetini, diğeri sağa gitme maliyetini temsil eder (bir sonraki kaba).

Değerler, iki nokta arasındaki mesafe , bu iki nokta + 1 dışındaki varil sayısıyla çarpılarak hesaplanabilir . Her iki sayının da aynı işarete sahip olduğu hücreler, karşıt işaretin tüm varillerinin toplandığı durumları temsil eder. Bunlar sadece sıfırdan uzağa doğru varil sayısı kullanılarak hesaplanır.

Tablodaki X değerleri, o yönde gidemeyeceğiniz anlamına gelir (bu yöndeki tüm variller alınmıştır). Satırlar toplayıcının geçerli konumunu ve sütunlar bir sonraki karşıt varilin konumunu temsil eder.

    +------+------+------+------+------+
    |  -9  |  -6  |  -1  |   3  |   5  |
+---+------+------+------+------+------+
|-9 |      |      |      | X, 24| X, 14|
+---+------+------+------+------+------+
|-6 | 3, X |      |      | 9, 27| 6, 22|
+---+------+------+------+------+------+
|-1 |      |10, X |      |20, 8 |15, 18|
+---+------+------+------+------+------+
| 3 |24, 4 |27, 6 |16, 8 |      | X, 2 |
+---+------+------+------+------+------+
| 5 |14, X |22, X |18, X |      |      |
+---+------+------+------+------+------+

Kareler arasında hareket etme kuralları biraz kafa karıştırıcı olabilir.

Negatif numaralı sütunlar için kurallar aşağıdaki gibidir:

  • Sağa gitmek bir hücreyi aşağı taşır.
  • Sola gitmek bir hücre aşağı doğru hareket eder ve sonra köşegen boyunca aynalar.
  • Doğru değer X ise, sola gitmek çapraz (sütun ve satırın eşit olduğu) diyagonal yukarı ve sola doğru hareket eder.

Pozitif numaralı sütunlar için kurallar aşağıdaki gibidir:

  • Sola gitmek bir hücre yukarı gider.
  • Sağa gitmek bir hücre yukarı hareket eder ve sonra köşegen boyunca aynalar.
  • Sol değer X ise, sağa gitmek diyagonal ve sağa birer birer hareket eder.

Şimdi grafiği hareket ettirmek için bu hareket kurallarını kullanarak en iyi yolu hesaplamak için Dijkstra'nın algoritmasını çalıştırabiliriz. Başlangıç ​​pozisyonlarımız sırasıyla başlangıç ​​maliyeti 5 ve 15 olan (-1, 3) ve (3, -1) 'dir. İki son konum için değerleri hesapladıktan sonra (solun (-9, -9) ve sağının (5, 5)) ikisinden daha küçük olan cevabımızdır.

Her adım için çalışma süresi:

  • Başlangıçta satır boyunca giriş değerlerini sıralamak için O (N log N)
  • Tablo / grafiği hesaplamak için O (N ^ 2)
  • Dijkstra'ları grafik üzerinde çalıştırmak için O (N ^ 2 log N) (Not: herhangi bir tepe noktası için en fazla iki kenar vardır).

İlk iki adım sonuncuya hükmeder, bu nedenle genel çalışma zamanınız, meydan okuma için yeterince iyi bir çalışma zamanı olması gereken O (N ^ 2 log N) olur.


1

En Kısa Mesafe

Dün sorunu çözmek için bir Java uygulaması yazdım. SRJ'nin yorumunda söylediği gibi, sorun temelde en kısa mesafe problemidir. Radyasyon sadece en kısa mesafeyle birlikte bir değer biriktirebileceğinizi gösterir.

Temel olarak, işte yaptığım şey.

  • Kapsayıcı numaralarını bir Listeye yerleştirin <Integer>
  • Liste öğeler içerirken;
    • En yakın öğeleri bulun
    • Bir eleman varsa, oraya yürüyün ve elemanı çıkarın.
    • İki öğe varsa, yolu kopyalayın ve her iki öğeye doğru yürüyün
  • En küçük radyasyon değerine sahip yolu bulun.

İşte uygulamadan bazı çıktılar

10 containers are located at [-90, -75, -47, -9, 9, 26, 48, 50, 64, 79].

You walk to position -9 and pick up the container.  The total radiation emitted is 90 units.
You walk to position 9 and pick up the container.  The total radiation emitted is 252 units.
You walk to position 26 and pick up the container.  The total radiation emitted is 388 units.
You walk to position 48 and pick up the container.  The total radiation emitted is 542 units.
You walk to position 50 and pick up the container.  The total radiation emitted is 554 units.
You walk to position 64 and pick up the container.  The total radiation emitted is 624 units.
You walk to position 79 and pick up the container.  The total radiation emitted is 684 units.
You walk to position -47 and pick up the container.  The total radiation emitted is 1,062 units.
You walk to position -75 and pick up the container.  The total radiation emitted is 1,118 units.
You walk to position -90 and pick up the container.  The total radiation emitted is 1,133 units.

Algoritmayı hiçbir şekilde optimize etmedim. Sayıların giriş listesinin sıralandığını bile fark etmedim. (Ben bir doofusum.)

Kodumu maksimum değerlerle, 1.000 kapsayıcıyla ve -500.000 ile 500.000 arasında bir aralıkta çalıştırdığımda kodumun yürütülmesi 3 saniye sürdü. O zamanların çoğu konsola 1.000 baskı hattı yazıyordu.

Ben büyük bir O insan değilim, ama bence en kısa yol algoritmasını yürüdüğüm kaba kuvvetim O (N kare) değil O (N kare).

Giriş numaralarının sıralandığı gerçeğinden yararlandım, böylece şu anda bulunduğum yerin her iki tarafındaki iki sayıyı kontrol etmek zorunda kaldım, uygulamayı O (N) 'ye yakın alabilirim. Sadece 2 numarayı kontrol etmeliyim çünkü onlara ulaştığımda öğeleri Listeden kaldırıyorum.

Yaklaşık bir çözüm bulmak için açgözlü algoritma gibi farklı algoritmalar kullandınız.

Programımın çalışması 3 saniye yerine 3 saat sürmüş olsaydı, seçim yapma şansınız olurdu.

Yeterince iyi çözüm yeterince iyi mi?

Başka bir deyişle, işlem hızını yeterince iyi bir cevap için takas etmeye hazır mıyım?

Yeterince iyi bir cevap yeterince iyiyse, yaklaşık algoritmalar kullanırsınız.

Mükemmel bir cevap istiyorsanız, en kısa yollardan yürümelisiniz. Kısayol yok.

Birisi kodumu göndermemi isterse, söylerim. Eminim hala hatalar var, en kısa yürüme algoritmasını uygulayıp uygulayamayacağımı görmek istedim.


1

Bu sorunu 2^Nzamanında çözecek bir çözümüm var , ki bu da zayıf, ama bence bu sorunu çerçevelemenin yararlı bir yolu, bu yüzden göndereceğimi düşündüm.

Sorunu bir grafik olarak modellemek yerine, bunun ikili bir karar ağacı olduğunu söyleyebilirim (diyelim T). Her seviyede sağa sola gitmek arasında seçim yapmak zorundasınız. Her kenarın 'maliyetini' hesaplamak oldukça kolaydır. Izin vermek h(K)geçerli düğümün yüksekliği K, sonra gidecek kenar maliyeti left_child(K) = h(K) x dist(K, left_child(K)). Benzer bir hesaplama, kenarın sağ çocuğa maliyeti için yeterlidir. Bu ağacı inşa edersiniz ve kenarların kümülatif maliyetini sonuna kadar takip edersiniz ve yaprak düğümüne giden yolu en düşük toplam maliyetle bildirirsiniz.

Maliyet hesaplamasının işe yaradığına dikkat edin, çünkü her kenarın uzunluğu bir dist(K, left_child(K))sonraki siteye gitme süresini temsil ederken, alt ağacın yüksekliği kalan site sayısıdır (örneğin, hala radyasyon yayan).

Şimdi bu çerçevedeki püf noktası, aramayı bir dal boyunca genişletmeyi göz ardı edebileceğinizi 'kanıtlamak' için kullanabileceğiniz bazı buluşsal yöntemler olup olmadığını belirlemektir. Benim sezgim böyle bir sezgisel için onu yenecek bir site düzenlemesi var, ama belki birileri bir şey bulabilir.

Bir dizi grafikler için en kısa yol çözümlerini uygulamayı önerdi, böyle bir çözümün işe yarayıp yaramayacağı konusunda bazı şüphelerim var. Sorundaki 'grafik' içindeki komşularınız takip ettiğiniz yola bağlı olarak değişecektir. İle orijinal sonrası Örneğin [-12, -2, 3, 7]sen gidersen -2sonra -12ve 3'komşular' olmak ve eğer gidip 3sonra -2ve 7komşularımız. Pozitif ve negatif değerlerin olası her bir 'çifti', nihai grafikte potansiyel olarak komşu olabilir. Dinamik bir grafikte doğru bir şekilde doğru olan en kısa yol algoritmalarını bilmiyorum.


0

Sanırım her aşamayı en yakın namluya gitmekle en yakın namluya gitmek arasında ikili bir seçenek olarak düşünmek en mantıklı. Herhangi bir hareket yaparak toplamda ortaya çıkacak radyasyon ünitesi sayısını detaylandıran ve en düşük maliyetli olanı seçen bir maliyet fonksiyonuna sahip olmanız yeterlidir.

Sadece en yakın namluyu düşünmeyin, bunun yerine bir namludan uzaklaşarak etkili bir şekilde radyasyonun iki katını eklediğinizi varsayın, çünkü uzaklaşarak daha sonra bu yönde geri gitme maliyetine katlandınız.

[-12, -2,3,7] örneğinizde, sola hareket etmek solda toplam 14 (2 + 2 + 10) ve sağda 18 (2 + 2 + 5 + 9), Sağa hareket etmek sağda 10 (3 + 3 + 4) ve sağda 26 (3 + 3 + 5 + 15) olacaktır. Açıkça sol ilk başta doğru çözümdür. Birbirini izleyen her hareket için benzer bir hesaplama yapılabilir.

Bundan sonra sorun temel olarak bir aramaya indirgenir, bu nedenle karmaşıklık O (nlog (n)) olmalıdır, ki bu O (n!) 'Den çok daha iyidir. Temelde O (nlog (n)) 'den daha iyi yapmanın mümkün olmadığı bir karşılaştırma tabanlı arama algoritması olduğu için, bu sorun için mutlaka en düşük karmaşıklık olduğuna inanıyorum.

Görünüşe göre bu açıklama ile yeterince net değildim, bu yüzden biraz daha programlı hale getirmeye karar verdim: 1. Sola giderek oluşan maliyeti ve mevcut pozisyona göre sağa giderek oluşan maliyeti hesaplayın. en ucuz yön 3. Bir yöne hareket etmenin maliyetini hesaplarken ulaşılan varili dikkate alın

Maliyet hesaplama: 1. Verilen yönde en yakın namluyu tanımlayın. Diyelim ki $ dist, mevcut konumdan belirli bir yöne en yakın namluya olan mesafedir. 2. Maliyet, N'nin hala aktif varil olduğunu düşündüğü N * $ dist olarak başlatılır. 3. Buna, $ dist ile gösterilen yeni konumun kalan her varilden uzaklığı ekleyin.


1
Bu her zaman işe yaramaz. Belki de koordinatları sıralayabilir ve daha sonra devletin bir aralığı [i..j] (hangi aralığı ziyaret ettiğinizi gösterir) ve maliyeti ve geçerli saati içerdiği bir arama yapabilirsiniz.
Barron W.Mar

Bu ne zaman işe yaramıyor?
Slater Victoroff

Bunun başarısız olduğu basit bir test durumu vardı. Bulmaya çalışacağım, ancak N = 4 veya
5'le oldu

[43, -18, -98, -82, 63]
Barron W.Mar

Ayrıca vakalar gibi [-10,-11, 10,20,30,40,50,60,70]. Doğru ve tek çözüm tüm negatif olanları toplamak ve sonra pozitif olanları toplamaktır. 455'in cevabı için.
Barron

0

Kısmi çözüm - Daha sonra geri döneceğim.

"Varsayılan" stratejinin hangisi daha ucuzsa, sola veya sağa tam olarak yürütüldüğünü varsayın. Şimdi sor, bir varil almak için başka bir yol küçük bir yan gezi değer mi. Cevabı hesaplamak oldukça kolaydır.

Örnek girdi için, sağa doğru koşmak soldan daha ucuzdur. Bir yan geziye -2 değerinde olacak mı? Bu, tam olarak çalıştırma maliyetini azaltır ve ardından 14'e kadar 0'a geri döner (çünkü varsayılan strateji üzerinde 0'dan 3'e hareket başına 4 radyasyon birimi "ödüyordunuz", şimdi 3'e düştü, 3'ten 3'e ödüyordunuz 7'ye, şimdi 2, vb.) artı, hareket başına maliyetinizi 0'dan -2'ye düşürür, böylece toplam 16 için 2 tasarruf sağlar.

Bununla birlikte, net bir kazanç (16-14) = 2 için -2'ye, sonra 14'ün 0'ına geri gitme maliyeti (hareket başına 4 birim -2'ye, hareket başına 3) geri gider. Bunu hesaplamak için, her bir karar için tüm problemi çözmenin tam maliyetini değerlendirmeniz gerekmediğini unutmayın - sadece sonuna kadar koşmanın tamamen doğru koşmaktan daha ucuz olup olmadığını ve nasıl birçok atık kabınız her iki tarafınızda ve en yakın 2'ye olan uzaklığınız. Yani bu O (N ^ 2).

Önemli bir sorun dışında - sonuna kadar koşacağınızı varsaydım ve geri dönebileceğinizi biliyoruz. Bunu temizlemek için hesaplamamı güncellememiz gerekiyor. Numune girişi için, 0'dan 7'ye ve geriye doğru çalışırken saniyede birim daha az toplam radyasyon yayarak 14 tasarruf edeceğinizi varsaydım. Ancak, 7'ye koşmadan önce iki katına çıkarsanız, tasarruflar azalır.

Bu oldukça kötü, çünkü bizi O'ya (2 ^ N) geri koyan tüm olasılıkları denemeden bir sonraki çifte hesaplamayı nasıl yapacağımı bilmiyorum.

Dışında - budama ile 2 ^ N. Ben "yan gezisi" -2 maliyeti 14, ancak en doğru sayıya yapmadan önce daha fazla yan gezileri yoktu 16, kazandı. En doğru sayı 5 olsaydı, hemen yan gezinin -2'yi ödeyemediğini hemen bilirdim. (Maliyet hala 14, maksimum fayda 12). Ayrıca -2'ye gitmeyi ve sonra 6'ya ulaşmadan önce bir yan seyahat yapmayı düşünmem gerekir, çünkü bu her zaman doğrudan o noktaya gitmekten daha aşağıdır.


0

Ben yolun karmaşık olduğu sürece dizeleri fazla 2 * N ^ 2 tuples (boolean, int, int, int, dize) en fazla korumak, bir genişlik ilk arama kullanarak çözebilirsiniz düşünüyorum.

Tupler (min veya maks. Boolean, minimum hareket mesafesi, hareket edilen maksimum pozisyon, yayılan toplam radyasyon, yol geçmişi).

Algoritmanın şöyle gittiğini görüyorum:

  1. Tuples havuzunu tek bir girişe başlatın (min, 0, 0, 0, "")
  2. Havuzda en az radyasyon yayılan bir eleman bulun. Min ve maks, tüm varillerin min ve maks'lerine karşılık geliyorsa, yol geçmişi en uygun çözümdür. Aksi takdirde havuzdan silin.
  3. Her biri bir sonraki işlenmemiş varili sola veya sağa yürümeye karşılık gelen bu demetin 2 torununu hesaplayın.
  4. Torunları havuza yerleştirin. Havuzda zaten yeni bir alçalma ile aynı boole, min ve max değerine sahip bir öğe varsa, öğeyi daha yüksek radyasyon sayısı ile atın.
  5. Git 2.

Hakim tuplleri bulmak ve kaldırmak performansı önemli ölçüde artıracaktır. Her bir tuple için bir 'yetiştirdi "bayrağı eklemek ve yetiştirilen tuples'ları havuzda bırakmak faydalı olabilir.

Ayrıca, tuple'lerin nasıl saklanacağına karar vermek ve onları üremek için hakimiyet ve yeni unsurlar aramak için alınması gereken bazı önemli kararlar da var.

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.