Lassen Sie mich Ihnen ein Beispiel geben, was ich meine. Nehmen wir an, ich habe N=3
Artikel { A, B, C }
und möchte sie in K
Gruppen konsolidieren (0 < K < N
). Zum Beispiel könnten sie in K=2
Gruppen Konsolidierung produzieren das ErgebnisWie kann ich die Elemente {a_0, .., a_N} in K-Gruppen zusammenfassen, sodass der Konsolidierungsprozess am kostengünstigsten ist?
{ {A, B}, {C} }
Ich habe eine Funktion Cost(X, Y) >= 0
, die die Kosten zurück von Artikel Konsolidierung X
in Artikel Y
. Zum Beispiel, wenn Cost(A, B) = 10
und Cost(B, C) = 15
dann produzieren
{ {A, B}, {C} }
Kosten 10
und Herstellung
{ {A}, {B, C} }
Kosten 15
.
Die Kostenfunktion ist nicht kommutativ (Es ist nicht immer wahr, dass Cost(X, Y) = Cost(Y, X)
).
Was ich tun möchte, ist einen Algorithmus für die kostengünstigste Konsolidierung in K
Gruppen zu finden.
Zum Beispiel, sagen wir, die Kosten sind
Cost(A, B) = 12
Cost(B, A) = 4
Cost(A, C) = 5
Cost(C, A) = 11
Cost(B, C) = 3
Cost(C, B) = 20
und ich möchte in K=1
Gruppen konsolidieren. Die billigste wäre
B -> C
A -> C
zu einem Preis von 8
.
Ich versuche eine Verallgemeinerung herauszufinden, wie das zu bestimmen ist.
Wie ich denke, es anfangen sollte, ist, alle Kosten zu bestellen:
Cost(B, C) = 3
Cost(B, A) = 4
Cost(A, C) = 5
Cost(C, A) = 11
Cost(A, B) = 12
Cost(C, B) = 20
Der Artikel in der obigen Liste wird immer eine Eins der Bewegungen im Konsolidierungsprozess:
Nun, was ich vermute muss passieren iterieren durch den Rest der Liste und sehen, ob jede Konsolidierung.
Das nächste Element in der Liste ist B -> A
. Da ich bereits B
zu C
verschoben habe, überspringen Sie diese.
Der nächste Artikel ist A -> C
. Da A
noch nicht zu einer Gruppe konsolidiert wurde, ist dies eine gültige Konsolidierung.
Jetzt sind wir fertig, da wir K=1
Gruppen haben, { {A, B, C} }
.
Ich frage mich, wie man diesen Algorithmus schreibt.
konkreter werden, hier ist ein C# Setup:
using System;
using System.Collections.Generic;
using System.Linq;
public class Widget
{
public int Distance { get; set; }
public int Weight { get; set; }
public static int Cost(Widget w1, Widget w2)
{
// returns the cost of consolidating w1 into w2
return Math.Abs(w1.Distance - w2.Distance) * w1.Weight;
}
}
public class Program
{
public static void Main()
{
var widgets = new List<Widget>()
{
new Widget() { Distance = 10, Weight = 1 },
new Widget() { Distance = 20, Weight = 1 },
new Widget() { Distance = 30, Weight = 1 },
};
var tuples = from x in widgets
from y in widgets
where !x.Equals(y)
select Tuple.Create(x,y);
var ordered = from t in tuples
orderby Widget.Cost(t.Item1, t.Item2)
select t;
int K = 2;
int sum = 0;
// ... What to do here???
Console.WriteLine(sum); // should write 10
}
}
FYI, das ist kein Problem, Hausaufgaben oder irgendetwas ist. Ich mache es zum Spaß.
Warum haben Sie B-> A nicht berücksichtigt und A-> C betrachtet? Der Grund ist nicht klar. bitte ausführlicher. –
@PrakharAsthana Diese Kosten wären "9", was größer ist als die Kosten von "B -> C, A -> C". –
Was ich meinte, war nach der Auswahl von B-> C "Warum haben Sie nicht B-> A und dachte A-> C?" Als ob Sie B-> A gewählt hätten, wären die Gesamtkosten 7. –