सबसे तेज एल्गोरिथ्म अनुकूलन चुनौती


9

यह एक असममित जटिलता चुनौती के साथ मेरा पहला प्रयोग है, हालांकि मैं पूरी तरह से कोड में जवाब से खुश हूं जब तक वे अपने समय की जटिलता के स्पष्टीकरण के साथ आते हैं।

मुझे निम्न समस्या है।

कार्य T_1, ... T_n और M_1, ..., M_m पर विचार करें। प्रत्येक कार्य के लिए कुछ समय लगता है, जो कि प्रॉपर पर निर्भर करता है।

प्रत्येक कार्य में एक निश्चित राशि भी खर्च होती है जो प्रॉपर के आधार पर होती है।

कार्यों को कड़े क्रम में किया जाना चाहिए (वे समानांतर में नहीं किए जा सकते हैं) और खरीद को बदलने में समय लगता है। इसे शुरू करने के बाद एक कार्य को एक खरीद से दूसरे स्थान पर नहीं ले जाया जा सकता है।

अंत में, प्रत्येक कार्य को एक निश्चित समय तक पूरा किया जाना चाहिए।

काम

उद्देश्य एक एल्गोरिथ्म (या कुछ कोड) देना है जो ऊपर दिए गए फॉर्म के पांच टेबल दिए गए हैं, सभी कार्यों को पूरा करने की कुल लागत को कम करते हुए सुनिश्चित करते हैं कि सभी कार्य उनकी समय सीमा से पूरा होते हैं। यदि यह संभव नहीं है तो हम सिर्फ रिपोर्ट करते हैं कि यह नहीं किया जा सकता है।

स्कोर

आपको अपने समाधान की बड़ी ओह जटिलता को चर n, m और d के संदर्भ में देना चाहिए, जहां d अंतिम समय सीमा है। आपके बड़े ओह जटिलता में कोई अनावश्यक स्थिरांक नहीं होना चाहिए। इसलिए O (n / 1000) को O (n) के रूप में लिखा जाना चाहिए, उदाहरण के लिए।

आपके स्कोर की गणना आपके द्वारा बताई गई जटिलता में n = 100, m = 100 और d = 1000 निर्धारित करके की जाती है। आप सबसे छोटा स्कोर संभव चाहते हैं।

टाई ब्रेकर

एक टाई के मामले में, पहला उत्तर जीत जाता है।


जोड़े गए नोट

log किसी उत्तर की समय जटिलता में आधार 2 लिया जाएगा।

स्कोर बोर्ड

  • KSFT ( पायथन ) से 10 ^ 202 पहले जमा किया गया है ताकि इनाम मिल सके।
  • डोमिनिक मूलर ( स्काला ) से 10 ^ 202

"पंक्ति मशीन से कॉलम मशीन पर स्विच करने का समय" आपका मतलब है कि M_1 से M_2 तक स्विच करने का समय लागत है? इसके अलावा "स्विचिंग कॉस्ट" और "स्विचिंग टाइम" के बीच क्या अंतर है। वे आमतौर पर शेड्यूलिंग एल्गोरिदम का वर्णन करने के संबंध में एक ही बात करते हैं।
चमकदार

@ चमकदार सेकंड में समय और डॉलर में लागत के बारे में सोचो। वे इस सवाल में अलग-अलग चीजें हैं। टेबल अगले कार्य को करने के लिए बदलती मशीन का समय (क्रमशः लागत) दिखाते हैं। यह M_1 से M_2 या M_2 से M_1 तक हो सकता है।

ठीक है, यह स्पष्ट करता है कि।
चमकदार

संक्षिप्त उत्तर यह है कि जटिलता होगी O(m ^ n)। कोई भी एल्गोरिथम इससे अधिक "तेज" नहीं होगा। अधिकतम आवश्यक समय या लागत के आधार पर Pruning एल्गोरिथ्म की जटिलता को नहीं बदलता है, और न ही एक डॉलर की लागत और एक समय लागत दोनों है, इसलिए dजटिलता का एक तत्व नहीं है।
बॉब डेल्गीश

1
@ डबडलग्लिश जो 100 की शक्ति को 100 का स्कोर देता है। मेरा मानना ​​है कि आप बहुत बेहतर कर सकते हैं।

जवाबों:


2

स्कोर: 10 ^ 202

मुझे लगता है कि हम अब LaTeX समर्थन था काश ...

चूँकि किसी और ने उत्तर नहीं दिया है, मैंने सोचा कि मैं कोशिश करूँगा, हालांकि यह बहुत कुशल नहीं है। मुझे यकीन नहीं है कि इसके बारे में बड़ा ओ क्या है।

मुझे लगता है कि यह काम करता है। कम से कम, यह पोस्ट किए गए एकमात्र परीक्षण मामले के लिए करता है।

यह मशीन या टास्क नंबर लेबल के बिना और लाइन ब्रेक के बजाय अर्धविराम के साथ प्रश्न में इनपुट लेता है।

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())]

क्या आप कुछ स्पष्टीकरण दे सकते हैं और कह सकते हैं कि आपको लगता है कि आपका स्कोर क्या होना चाहिए? इसके अलावा, क्या आप दिखा सकते हैं कि यह प्रश्न में उदाहरण के लिए क्या देता है?

जैसा कि मैंने अपने जवाब में कहा था, मैंने इसकी कोशिश की है और यह उदाहरण पर काम करता है। मुझे यकीन नहीं है कि बड़ा ओ क्या है (जिसका मैं अपने उत्तर में उल्लेख करना चाहता था)।
केएसएफटी

असल में, लगभग कितने ऑपरेशनों को पूरा करने में लगेगा। ऐसा लगता है कि यह लगभग * m समय तक ntsc लेता है (मान लें कि छोरों में सभी असाइनमेंट लगातार समय लेते हैं) जो मुझे इसकी शुद्धता के बारे में संदेह करते हैं मुझे स्वीकार करना होगा। क्या आप इस बारे में कुछ कह सकते हैं कि आपको क्यों लगता है कि यह काम करता है?

1
ओह! मैंने यह खो दिया। तो एम आकार nmachines ^ ntasks के वास्तव में है। ठीक है अब मेरा मानना ​​है कि यह काम करता है। मुझे लगता है कि आपका स्कोर (100 ^ 100) * 100 है।

4
@Lembik यह अब तक का सर्वश्रेष्ठ स्कोर है!
केएसएफटी

1

सभी की जाँच करें - स्काला

अनुमानित स्कोर: 2 मी ^ एन

मैं प्रत्येक मशीन से शुरू करता हूं और डेडलाइन को पूरा करने वाली विभिन्न मशीनों के साथ कार्यों के माध्यम से सभी क्रमपरिवर्तन बनाने के लिए सभी कार्यों पर पुनरावृति करता हूं। मतलब अगर सब कुछ समय पर होता है तो मुझे 2 मशीनों और 3 कार्यों के साथ 9 संभावित रास्ते मिलेंगे। (m ^ n) बाद में, मैं सबसे कम लागत के साथ रास्ता लेता हूं।

इनपुट इस तरह संरचित है (-> भागों की व्याख्या करता है और इस तरह दर्ज नहीं किया जाना चाहिए):

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

और यहाँ कोड है:

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)
    }
}

मुझे भी पीछे से शुरू करने का विचार था। चूंकि आप हमेशा सबसे कम लागत वाली एक मशीन का चयन कर सकते हैं यदि समय छोटा है तो पिछली समय सीमा से लेकर नए में अंतर। लेकिन यह अधिकतम रनटाइम को कम नहीं करेगा यदि बेहतर लागत के साथ कार्य में अधिक समय लगता है तो अंतिम समय सीमा समाप्त हो जाती है।

अपडेट करें

======

यहाँ एक और सेट अप है। समय:

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_2
M_1  0   2
M_2  6   0

स्विच लागत:

    M_1 M_2
M_1  0   2
M_2  2   0

समय सीमा:

5 10 15 20

मेरे कार्यक्रम में इनपुट के रूप में:

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

इस एक के दो समाधान हैं: समय: 18, लागत: 15, पथ: सूची (M_1, M_1, M_1, M_2) समय: 18, लागत: 15, पथ: सूची (M_2, M_1, M_1, M_1)

जो सवाल उठाता है कि इसे कैसे संभाला जाना चाहिए। क्या सभी को मुद्रित या सिर्फ एक होना चाहिए? और क्या होगा अगर समय अलग होगा? क्या सबसे कम लागत वाली और कोई छूटी हुई समय सीमा पर्याप्त नहीं है या यह भी सबसे कम समय वाली होनी चाहिए?


सवाल कहता है कि लक्ष्य "कुल लागत को कम से कम" करना है। वैसे, क्या आप संक्षेप में बता सकते हैं कि आपका एल्गोरिदम कैसे काम करता है? मैं स्काला को नहीं जानता, और मैं यह पता नहीं लगा सकता कि यह कैसे काम करता है।
केएसएफटी

सभी रास्तों पर फेरबदल में O(m^n)समय लगता है। सभी कार्यों के लिए प्रत्येक मशीन पर Iterating करने में O(n*m^n)समय लगता है।
केएसएफटी

O(n*m^n)प्रत्येक पथ के लिए प्रत्येक कार्य पर पुनरावृत्ति नहीं है ? और प्रत्येक कार्य के लिए प्रत्येक मशीन पर कुछ की तरह Iterating O(n*m)
डोमिनिक मुलर

आह, टाइपो। मैं "प्रत्येक मशीन से अधिक पुनरावृत्ति लिखने के लिए होती रास्तों में से सभी के लिए ले जाता है O(n*m^n)"।
KSFT

रुको, नहीं, यह है O(m*m^n)=O(m^n+1)। यह अभी भी एक ही स्कोर है, हालांकि।
केएसएफटी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.