En hızlı algoritma optimizasyonu zorluğu


9

Bu onların asimptotik bir karmaşıklık mücadelesi ile ilk denemem olmasına rağmen, zaman karmaşıklıklarının bir açıklaması ile birlikte geldikleri sürece tamamen koddaki cevaplardan memnunum.

Aşağıdaki sorunum var.

T_1, ... T_n ve M_1, ..., M_m işlemlerini düşünün. Her görevin prokse bağlı olarak gerçekleştirilmesi belirli bir zaman alır.

Her görevin, prokse bağlı olarak gerçekleştirilmesi için belirli bir miktar maliyeti vardır.

Görevler katı bir şekilde yapılmalıdır (paralel olarak yapılamazlar) ve proc'u değiştirmek zaman alır. Bir görev başlatıldıktan sonra bir işlemden diğerine taşınamaz.

Son olarak, her bir görev belirli bir süre için tamamlanmalıdır.

görev

Amaç, yukarıdaki formun beş tablosunu veren, tüm görevlerin tamamlanması için toplam maliyeti en aza indirirken, tüm görevlerin son tarihlerine kadar tamamlandığından emin olan bir algoritma (veya bazı kodlar) vermektir. Bu mümkün değilse, sadece yapılamayacağını bildiririz.

Puan

Çözümünüzün büyük Oh karmaşıklığını n, m ve d değişkenleri olarak vermelisiniz, burada d son son tarihtir. Büyük Oh karmaşıklığınızda gereksiz sabitler olmamalıdır. Yani O (n / 1000), örneğin O (n) olarak yazılmalıdır.

Skorunuz, belirtilen karmaşıklığa n = 100, m = 100 ve d = 1000 ayarlanarak hesaplanır. Mümkün olan en küçük puanı istiyorsunuz.

kravat kırıcı

Beraberlik durumunda, ilk cevap kazanır.


eklenen notlar

log zaman içinde bir cevabın karmaşıklığı esas alınacaktır 2.

skor tahtası

  • 10 ^ 202 kimden KSFT ( Python ) İlk gönderilen böylece ödül alır.
  • Dominik Müller'den ( Scala ) 10 ^ 202

"satır makineden sütun makinesine geçiş zamanı" M_1'den M_2'ye geçmenin zaman maliyetini mi kastediyorsunuz? Ayrıca "anahtarlama maliyeti" ile "anahtarlama süresi" arasındaki fark nedir? Programlama algoritmalarını tanımlamak için genellikle aynı anlama gelirler.
Aydınlık

@Luminous Süreyi saniye cinsinden ve maliyeti dolar cinsinden düşünün. Bu sorudaki farklı şeyler bunlar. Tablolar, bir sonraki görevi gerçekleştirmek için makinenin değiştirilme süresini (sırasıyla maliyeti) göstermektedir. Bu M_1'den M_2'ye veya M_2'den M_1'e olabilir.

Tamam, bu açıklığa kavuştu.
Aydınlık

Kısa cevap, karmaşıklığın olacağıdır O(m ^ n). Hiçbir algoritma bundan daha hızlı olmayacaktır. Gereken maksimum süreye veya maliyete dayalı budama, algoritmanın karmaşıklığını değiştirmez veya hem dolar maliyeti hem de zaman maliyetine dsahip değildir , bu nedenle karmaşıklığın bir unsuru değildir.
Bob Dalgleish

1
@BobDalgleish 100'ün gücüne 100 puan verir. Çok daha iyisini yapabileceğinize inanıyorum.

Yanıtlar:


2

Puan: 10 ^ 202

Keşke şimdi LaTeX desteğimiz olsaydı ...

Kimse cevap vermediğinden, çok verimli olmasa da deneyeceğim diye düşündüm. Yine de onun büyük O'nun ne olduğundan emin değilim.

Bence işe yarıyor. En azından, yayınlanan tek test senaryosu için geçerlidir.

Makine veya görev numarası etiketleri hariç ve satır sonları yerine noktalı virgül hariç, söz konusu girdiyi alır.

import itertools
time = [[int(j) for j in i.split()] for i in raw_input().split(";")]
cost = [[int(j) for j in i.split()] for i in raw_input().split(";")]
nmachines=len(time)
ntasks=len(time[0])
switchtime = [[int(j) for j in i.split()] for i in raw_input().split(";")]
switchcost = [[int(j) for j in i.split()] for i in raw_input().split(";")]
deadline = [int(i) for i in raw_input().split()]
d={}
m=itertools.product(range(nmachines),repeat=ntasks)
for i in m:
    t=-switchtime[i[-1]][i[0]]
    c=-switchcost[i[-1]][i[0]]
    e=0
    meetsdeadline=True
    for j in range(ntasks):
        t+=switchtime[i[e-1]][i[e]]+time[i[e]][j]
        c+=switchcost[i[e-1]][i[e]]+cost[i[e]][j]
        e+=1
        if t>deadline[j]:
            meetsdeadline=False
    if meetsdeadline:
        d[(c,t)]=i
print min(d.keys()),d[min(d.keys())]

Biraz açıklama yapabilir ve puanınızın ne olması gerektiğini hisseder misiniz? Ayrıca, sorudaki örnek için ne verdiğini gösterebilir misiniz?

Cevabımda belirttiğim gibi denedim ve örnek üzerinde çalışıyor. Büyük O'nun (cevabımda bahsetmek istediğim) ne olduğundan emin değilim.
KSFT

Temel olarak, kabaca kaç işlemin tamamlanması gerekir. Kabul etmek zorunda olduğum doğruluk konusunda şüpheli hale getiren kabaca ntasks * m zaman alır (döngülerdeki tüm ödevlerin sabit zaman aldığını varsayalım). Neden işe yaradığını düşündüğünüz hakkında bir şeyler söyleyebilir misiniz?

1
Ah! Onu özledim. Yani m aslında nmachines boyutu ^ ntasks. Tamam şimdi işe yaradığına inanıyorum. Bence puanınız (100 ^ 100) * 100.

4
@Lembik Şu ana kadar en iyi puanı aldı!
KSFT

1

Tümünü Kontrol Et - Scala

Tahmini puan: 2m ^ n

Her makineden başlıyorum ve son teslim tarihlerini karşılayan farklı makinelerle görevler aracılığıyla tüm permütasyonları oluşturmak için tüm görevleri tekrar ediyorum. Eğer her şey zamanında olursa, 2 makine ve 3 görev ile 9 olası yol elde edeceğim. (m ^ n) Daha sonra, en düşük maliyetle yola çıkıyorum.

Girdi şu şekilde yapılandırılmıştır (-> parçaları açıklar ve dolayısıyla girilmemelidir):

M_1:5 3 5 4;M_2:4 2 7 5                 --> time
M_1:5 4 2 6;M_2:3 7 3 3                 --> cost
M_1:M_1}0 M_2}1;M_2:M_1}2 M_2}0         --> switch itme
M_1:M_1}0 M_2}2;M_2:M_1}1 M_2}0         --> switch cost
5 10 15 20                              --> deadlines

Ve işte kod:

package Scheduling

import scala.io.StdIn.readLine

case class Cost(task: Map[String, List[Int]])
case class Switch(machine: Map[String, Map[String, Int]])
case class Path(time: Int, cost: Int, machine: List[String])

object Main {

    def main(args: Array[String]) {
        val (machines, cost_time, cost_money, switch_time, switch_money, deadlines) = getInput

        val s = new Scheduler(machines, cost_time, cost_money, switch_time, switch_money, deadlines)
        s.schedule
    }

    def getInput(): (List[String], Cost, Cost, Switch, Switch, List[Int]) = {
        val cost_time = Cost(readLine("time to complete task").split(";").map{s => 
                val parts = s.split(":")
                (parts(0) -> parts(1).split(" ").map(_.toInt).toList)
            }.toMap)

        val cost_money = Cost(readLine("cost to complete task").split(";").map{s => 
                val parts = s.split(":")
                (parts(0) -> parts(1).split(" ").map(_.toInt).toList)
            }.toMap)

        val switch_time = Switch(readLine("time to switch").split(";").map{s => 
                val parts = s.split(":")
                (parts(0) -> parts(1).split(" ").map{t =>
                        val entries = t.split("}")
                        (entries(0) -> entries(1).toInt)
                    }.toMap)
            }.toMap)

        val switch_money = Switch(readLine("time to switch").split(";").map{s => 
                val parts = s.split(":")
                (parts(0) -> parts(1).split(" ").map{t =>
                        val entries = t.split("}")
                        (entries(0) -> entries(1).toInt)
                    }.toMap)
            }.toMap)

        val deadlines = readLine("deadlines").split(" ").map(_.toInt).toList

        val machines = cost_time.task.keys.toList

        (machines, cost_time, cost_money, switch_time, switch_money, deadlines)
    }
}

class Scheduler(machines: List[String], cost_time: Cost, cost_money: Cost, switch_time: Switch, switch_money: Switch, deadlines: List[Int]) {

    def schedule() {
        var paths = List[Path]()
        var alternatives = List[(Int, Path)]()

        for (i <- machines) {
            if (cost_time.task(i)(0) <= deadlines(0)) {
                paths = paths ::: List(Path(cost_time.task(i)(0), cost_money.task(i)(0), List(i)))
            }
        }

        val allPaths = deadlines.zipWithIndex.tail.foldLeft(paths)((paths, b) => paths.flatMap(x => calculatePath(x, b._1, b._2)))

        if (allPaths.isEmpty) {
            println("It is not possible")
        } else {
            println(allPaths.minBy(p=>p.cost).machine)
        }
    }

    def calculatePath(prev: Path, deadline: Int, task: Int): List[Path] = {
        val paths = machines.map(m => calculatePath(prev, task, m))
        paths.filter(p => p.time <= deadline)
    }

    def calculatePath(prev: Path, task: Int, machine: String): Path = {
        val time = prev.time + switch_time.machine(prev.machine.last)(machine) + cost_time.task(machine)(task)
        val cost = prev.cost + switch_money.machine(prev.machine.last)(machine) + cost_money.task(machine)(task)

        Path(time, cost, prev.machine :+ machine)
    }
}

Ayrıca arkadan başlamak için bir fikrim vardı. Zaman daha küçükse, her zaman en düşük maliyetle bir makine seçebileceğinizden, önceki son tarihten yeni bir makineye olan fark. Ancak, daha iyi maliyete sahip görev son süreden daha uzun sürerse, maksimum çalışma süresini azaltmaz.

Güncelleme

======

İşte başka bir kurulum. süresi:

M_1 2 2 2 7
M_2 1 8 5 10

maliyet:

M_1 4 4 4 4
M_2 1 1 1 1

geçiş zamanı:

    M_1 M_2
M_1  0   2
M_2  6   0

anahtar maliyeti:

    M_1 M_2
M_1  0   2
M_2  2   0

tarihleri:

5 10 15 20

Programıma girdi olarak:

M_1:2 2 2 7;M_2:1 8 5 10
M_1:4 4 4 4;M_2:1 1 1 1
M_1:M_1}0 M_2}2;M_2:M_1}6 M_2}0
M_1:M_1}0 M_2}2;M_2:M_1}2 M_2}0
5 10 15 20

Bunun iki çözümü vardır: zaman: 18, maliyet: 15, yol: Liste (M_1, M_1, M_1, M_2) zaman: 18, maliyet: 15, yol: Liste (M_2, M_1, M_1, M_1)

Bu da bunun nasıl ele alınması gerektiği sorusunu gündeme getiriyor. Hepsi yazdırılmalı mı yoksa sadece bir tane mi yazdırılmalıdır? Ya zaman farklı olsaydı? En düşük maliyete ve kaçırılmış son teslim tarihine sahip biri yeterli mi yoksa en düşük süreye sahip olanı da olmalı mı?


Soru, amacın "toplam maliyeti [[en aza indirmek”) olduğunu söylüyor. Bu arada, algoritmanızın nasıl çalıştığını özetleyebilir misiniz? Scala'yı tanımıyorum ve bunun nasıl çalıştığını anlayamıyorum.
KSFT

Tüm yolları tekrar etmek O(m^n)zaman alır . Tüm görevler için her makineyi tekrarlamak O(n*m^n)zaman alır .
KSFT

Is not O(n*m^n)yollardan her biri için her görev yineleme? Ve her iş için her makinenin üzerinde yinelenen bir şey O(n*m).
Dominik Müller

Ah, yazım hatası. Ben "her makinenin üzerinde Yineleme Yapmak yazmak istedim yolların tümü için alır O(n*m^n)".
KSFT

Bekle, hayır, öyle O(m*m^n)=O(m^n+1). Yine de aynı puan.
KSFT
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.