একটি দ্রুততম অ্যালগরিদম অপ্টিমাইজেশন চ্যালেঞ্জ


9

এটি একটি অ্যাসিম্পটোটিক জটিলতার চ্যালেঞ্জের সাথে আমার প্রথম পরীক্ষা, যদিও আমি যতক্ষণ না তাদের সময়ের জটিলতার ব্যাখ্যা দিয়ে আসি ততক্ষণে আমি কোডের পুরো উত্তরগুলিতে খুশি।

আমি নিম্নলিখিত সমস্যা আছে।

কাজগুলি টি_1, ... টি_এন এবং প্রো এম, এম, এম, এম বিবেচনা করুন। প্রতিটি টাস্ক প্রকসের উপর নির্ভর করে সম্পাদন করতে একটি নির্দিষ্ট পরিমাণ সময় নেয়।

প্রতিটি টাস্কের জন্য প্রস উপর নির্ভর করে সম্পাদন করতে একটি নির্দিষ্ট পরিমাণের ব্যয়ও হয়।

কাজগুলি কঠোর ক্রমে সম্পন্ন করতে হবে (সেগুলি সমান্তরালে করা যায় না) এবং এটির পরিবর্তনের জন্য সময় লাগে। কোনও কাজ শুরু হওয়ার পরে একের কাছ থেকে অন্য প্রোকে স্থানান্তরিত করা যায় না।

অবশেষে, প্রতিটি কাজ একটি নির্দিষ্ট সময় দ্বারা শেষ করা আবশ্যক।

কাজটি

উদ্দেশ্যটি হল একটি অ্যালগরিদম (বা কিছু কোড) যা উপরে ফর্মের পাঁচটি সারণী দিয়েছে, সমস্ত কার্য শেষ করার সময়কালে সমস্ত কাজ শেষ করার জন্য মোট ব্যয়কে হ্রাস করে। যদি এটি সম্ভব না হয় তবে আমরা কেবল রিপোর্ট করতে পারি যে এটি করা যায় না।

স্কোর

আপনার সমাধানের বড় ওহ জটিলতাটি এন, এম এবং ডি ভেরিয়েবলের ক্ষেত্রে দেওয়া উচিত, যেখানে ডি শেষ সময়সীমা। আপনার বড় ওহ জটিলতায় কোনও অপ্রয়োজনীয় স্থিরতা থাকা উচিত নয়। সুতরাং ও (এন / 1000) ও (এন) হিসাবে লিখতে হবে, উদাহরণস্বরূপ।

আপনার স্কোরটি সহজেই আপনার বর্ণিত জটিলতায় n = 100, m = 100 এবং d = 1000 সেট করে গণনা করা হয়। আপনি সম্ভব সবচেয়ে ছোট স্কোর চান।

টাইব্রেকার

টাইয়ের ক্ষেত্রে প্রথম উত্তরটি জয়ী হয়।


যোগ করা নোট

log সময়ে একটি উত্তর জটিলতা বেস 2 নেওয়া হবে।

স্কোর বোর্ড

  • কেএসএফটি ( পাইথন ) থেকে 10 ^ 202 প্রথমে জমা দেওয়া হয়েছে যাতে অনুগ্রহ পায়।
  • ডোমিনিক মুলার ( স্কালা ) থেকে 10 ^ 202

"সারি মেশিন থেকে কলাম মেশিনে স্যুইচিং সময়" আপনি কি M_1 থেকে M_2 এ স্যুইচ করার সময় ব্যয়কে বোঝাচ্ছেন? এছাড়াও "স্যুইচিং ব্যয়" এবং "স্যুইচিং সময়" এর মধ্যে পার্থক্য কী। সময়সূচী অ্যালগরিদমগুলি বর্ণনা করার ক্ষেত্রে তারা সাধারণত একই জিনিসটি বোঝায়।
আলোকিত

@ আলোকিত সময় সেকেন্ডে চিন্তা করুন এবং ডলারে ব্যয়। তারা এই প্রশ্নের বিভিন্ন জিনিস। সারণীগুলি পরবর্তী কাজ সম্পাদনের জন্য মেশিন পরিবর্তনের সময় (যথাক্রমে ব্যয়) দেখায়। এটি M_1 থেকে M_2 বা M_2 থেকে M_1 পর্যন্ত হতে পারে।

ঠিক আছে, এটি স্পষ্ট করে।
আলোকিত

সংক্ষিপ্ত উত্তরটি হ'ল জটিলতা হবে O(m ^ n)। কোনও অ্যালগরিদম এর চেয়ে "দ্রুত" হবে না। সর্বোচ্চ প্রয়োজনীয় সময় বা ব্যয়ের উপর ভিত্তি করে ছাঁটাই অ্যালগরিদমের জটিলতা পরিবর্তন করে না, বা ডলারের মূল্য এবং সময় ব্যয় উভয়ই রাখে dনা , সুতরাং জটিলতার কোনও উপাদান নয়।
বব ডালগলেিশ

1
@ بابিডলগিশ এটি 100 এর পাওয়ারকে 100 এর স্কোর দেয় I আমি বিশ্বাস করি আপনি আরও অনেক কিছু করতে পারেন।

উত্তর:


2

স্কোর: 10 ^ 202

আমি আশা করি আমাদের এখন ল্যাটেক্স সমর্থন থাকলে ...

যেহেতু অন্য কেউ উত্তর দেয়নি, আমি ভেবেছিলাম চেষ্টা করব, যদিও এটি খুব দক্ষ নয়। যদিও এর বড় ওটি কী তা আমি নিশ্চিত নই।

আমি মনে করি এটি কাজ করে। কমপক্ষে, এটি পোস্ট করা একমাত্র পরীক্ষার ক্ষেত্রে করে।

এটি মেশিন বা টাস্ক নম্বর লেবেল ব্যতীত এবং লাইন ব্রেকগুলির পরিবর্তে সেমিকোলন সহ প্রশ্নের মতো ইনপুট নেয় takes

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

আপনি কি কিছু ব্যাখ্যা প্রদান করতে পারেন এবং বলতে পারেন যে আপনার স্কোরটি কী হওয়া উচিত? এছাড়াও, আপনি এটি প্রশ্নের উদাহরণের জন্য যা দেয় তা প্রদর্শন করতে পারেন?

আমি আমার উত্তরে যেমন বলেছি, আমি এটি চেষ্টা করেছি এবং এটি উদাহরণে কাজ করে। আমি নিশ্চিত না যে বড় ও কী (যা আমি আমার উত্তরে উল্লেখ করতে চাইছিলাম)।
কেএসএফটি

মূলত, মোট কতগুলি অপারেশন সম্পূর্ণ হতে লাগে। দেখে মনে হচ্ছে এটি প্রায় ntasks * মি সময় নেয় (ধরুন লুপের সমস্ত অ্যাসাইনমেন্টগুলি ধ্রুব সময় নেয়) যা আমাকে স্বীকার করতে হবে তার সঠিকতা সম্পর্কে সন্দেহজনক করে তোলে। আপনি কেন ভাবেন যে এটি কার্যকর হয় সে সম্পর্কে আপনি কিছু বলতে পারেন?

1
উহু! আমি সেটা মিস করেছি. সুতরাং মি আসলে আকারের নামচাইন। N টাস্কগুলি। ঠিক আছে এখন আমি বিশ্বাস করি এটি কাজ করে। আমি মনে করি আপনার স্কোর (100 ^ 100) * 100।

4
@ ল্যাম্বিক এটি এখন পর্যন্ত সেরা স্কোর আছে!
কেএসএফটি

1

সমস্ত পরীক্ষা করুন - স্কেলা

আনুমানিক স্কোর: 2 মি। N

আমি প্রতিটি মেশিন থেকে শুরু করি এবং নির্ধারিত সময়সীমার সাথে মেলে এমন বিভিন্ন মেশিনের সাহায্যে কার্যের মাধ্যমে সমস্ত ক্রিয়াকলাপ তৈরি করতে সমস্ত কার্যগুলিতে পুনরাবৃত্তি করি। মানে সবকিছু যদি সময় মতো হয় তবে আমি 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, পথ: তালিকা (এম_1, এম_1, এম_1, এম 2) সময়: 18, ব্যয়: 15, পথ: তালিকা (এম 2, এম_1, এম_1, এম_1)

এটি কীভাবে পরিচালনা করা উচিত তা প্রশ্ন উত্থাপন করে। সব কি এক ছাপানো উচিত? আর সময় যদি অন্যরকম হত? সর্বনিম্ন ব্যয় সহ একটি কি যথেষ্ট পরিমাণে মিস হয়নি এবং এটিও সর্বনিম্ন সময়ের সাথে এক হওয়া উচিত?


প্রশ্নটি বলছে যে লক্ষ্যটি হচ্ছে "মোট ব্যয়" [কমিয়ে আনুন] "। যাইহোক, আপনি কীভাবে আপনার অ্যালগোরিদম কাজ করে তার সংক্ষিপ্ত বিবরণ দিতে পারেন? আমি স্ক্যালাকে জানি না এবং আমি কীভাবে এটি কাজ করে তা বুঝতে পারি না।
কেএসএফটি

সমস্ত পাথের উপরে আইট্রেট করতে O(m^n)সময় লাগে । সমস্ত কাজের জন্য প্রতিটি মেশিনের মধ্যে আইট্রেট করতে O(n*m^n)সময় লাগে ।
কেএসএফটি

O(n*m^n)প্রতিটি পাথের প্রতিটি কাজের জন্য পুনরাবৃত্তি হয় না ? এবং প্রতিটি কাজের জন্য প্রতিটি মেশিনের মধ্যে আইট্রেট করা এর মতো কিছু O(n*m)
ডোমিনিক

আহ, টাইপো আমি "প্রতিটি মেশিনের উপর iterating লিখতে বোঝানো পাথ সব জন্য লাগে O(n*m^n)"।
কেএসএফটি

অপেক্ষা করুন, না, এটা O(m*m^n)=O(m^n+1)। যদিও এটি এখনও একই স্কোর।
কেএসএফটি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.