Diskuze: Seřazení hodnot pro vývahu oběžného kola
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.


Jsou ty hodnoty seřazené nějak speciálně nebo jde jen o to, aby se střídaly velké a malé hodnoty?
mifro:19.8.2019 15:49
Jde o to, aby hodnoty byly co nejlépe rozděleny pro co nejlepší rozložení sil. Základ je, že nejtěžší lopatka půjde na 0°, druhá na 180°, třetí na 90° a čtvrtá na 270° (úhly jsou zde jen informativní a mohou se samozřejmě lišit podle počtu lopatek). Tzn. ideální stav je, že první 4 lopatky jdou do "kříže" a zbytek se rovnoměrně rozdělí mezi ně.
STP:19.8.2019 22:31
Co znamená
a zbytek se rovnoměrně rozdělí mezi ně.
Něco takového pomůže?
static void Main(string[] args)
{
List<int> lopatky = new List<int> { 520, 510, 505, 500, 492, 490, 480, 475, 470 };
List<int> lopatky0 = new List<int>();
List<int> lopatky180 = new List<int>();
List<int> lopatky90 = new List<int>();
List<int> lopatky270 = new List<int>();
lopatky = lopatky.OrderByDescending(i => i).ToList();
for (int i = 0; i < lopatky.Count; i = i + 4)
{
lopatky0.Add(lopatky[i]);
if (lopatky.Count > i + 1)
lopatky180.Add(lopatky[i + 1]);
if (lopatky.Count > i + 2)
lopatky90.Add(lopatky[i + 2]);
if (lopatky.Count > i + 3)
lopatky270.Add(lopatky[i + 3]);
}
List<int> ret = new List<int>();
ret.AddRange(lopatky0);
ret.AddRange(lopatky90);
ret.AddRange(lopatky180);
ret.AddRange(lopatky270);
foreach (var item in ret)
{
Console.WriteLine(item);
}
Console.ReadLine();
}
Jestli to spravne chapu, tak ty mas jakousi hvezdici z linek. Delka linek je v seznamu. Mas ty linie rozmistit tak, aby hvezdice byla, co nejvic kulata.
o
|
o-------+-----o
|
|
o
Cili, kdyz body 'o' propojis mezi sebou, aby uhly byly co nejvetsi.
Natusim, ja bych postupoval projitim vsech moznosti.
Peter Mlich:20.8.2019 10:14
" Ručně to seřadím během chvilky" - mozna by bylo dobre popsat postup, jak to delas rucne. Z toho plyne, jak napsat program. Takze bohuzel, to mas pro nas nahodne serazena cisla a netusim, jak vypada z htoho graf predtim a potom
mifro:20.8.2019 11:25
Ručně viz příloha. Prostě si přesouvám jednotlivé hmotnosti, až mi vznikne co nejlepší "kruh" tak, aby např. nejtěžší lopatky nebyly jen na jedné straně - aby hmotnost byla co nejlépe vyrovnaná.
Neaktivní uživatel:20.8.2019 11:53
Tohle by ještě chtělo se při každém druhém procházení cyklem posunout o 180°, ne?
Myslím, že cílem je dostat centrum hmostnosti všech lopatek co nejblíže středu, například pro zamezení vibrací v turbínách.
mifro:20.8.2019 15:55
Díky, pomůže, jen to ještě není úplně ono, viz obrázek. Správně by mělo být 550 proti 530, pak otočit o 90° a 525 proti 505 a zybtek rovnoměrně mezi... Je to celkem oříšek...
A jak se na to jde ručně? To zkoušíš prostě náhodně, dokud to nevypadá hezky nebo na to máš nějaký systém.
Jakub Švasta:21.8.2019 17:50
Zajímavá úloha. Já bych na to šel třeba tak, že bych lopatky seřadil od nejtěžší po nejlehčí, první dal na 0°, a zbylé postupně umisťoval doprostřed nejdelší zbývající "mezery". Tak to asi intuitivně dělá i člověk. Při více mezerách stejné délky vyberu tu s nejmenším součtem hmotností okolních lopatek.
Tady si můžeš vyzkoušet, jestli ti to vrací použitelné výsledky i pro jiné hodnoty.
using System;
using System.Collections.Generic;
using System.Linq;
public class Program
{
public static void Main()
{
int[] blades = { 500, 530, 550, 475, 450, 525, 460, 505 };
foreach (int blade in SortBlades(blades)) Console.WriteLine(blade);
}
public static int[] SortBlades(int[] blades)
{
blades = blades.OrderByDescending(b => b).ToArray();
int[] result = new int[blades.Length];
if (result.Length == 0) return new int[0];
result[0] = blades[0];
for (int i = 1; i < blades.Length - 1; i++)
{
// get the longest empty sequence and put the current blade to its middle index
var sequences = new List<Sequence>();
int tmpStartIndex = 0, tmpEndIndex = 0;
for (int j = 1; j < result.Length; j++)
{
if (result[j] == 0 && result[j-1] != 0) tmpStartIndex = j;
if (result[j] != 0 && result[j-1] == 0) tmpEndIndex = j - 1;
else if (result[j] == 0 && j == result.Length - 1) tmpEndIndex = j;
else tmpEndIndex = 0;
if (tmpEndIndex != 0) sequences.Add(new Sequence() { StartIndex = tmpStartIndex, EndIndex = tmpEndIndex });
}
foreach (var sequence in sequences) sequence.SumOfWeightsAround = result[sequence.StartIndex - 1] + (sequence.EndIndex == result.Length - 1 ? result[0] : result[sequence.EndIndex + 1]);
// for more longest sequences take the one with minimum surrounding blades weights
result[sequences.OrderByDescending(s => s.EndIndex - s.StartIndex).ThenBy(s => s.SumOfWeightsAround).Select(s => (s.StartIndex + s.EndIndex) / 2).First()] = blades[i];
}
// the computation is not needed for the last blade
result[result.Select((v, i) => new { Index = i, Value = v }).Where(e => e.Value == 0).Select(e => e.Index).First()] = blades[blades.Length - 1];
return result;
}
}
public class Sequence
{
public int StartIndex { get; set; }
public int EndIndex { get; set; }
public int SumOfWeightsAround { get; set; }
}
mifro:22.8.2019 7:13
Ahoj Mouser, to je myslím přesně to, co jsem potřeboval - jdu to přehodit do VB a testovat. Každopádně zatím díky všem!
Ahoj,
napadá mě jednoduché řešení, ale je to hrubou silou. Zase by si to mělo
poradit s různým počtem lopatek a případnými extrémy ve hmotnosti.
- 1. Vytvořit všechny kombinace lopatek
- 2. Výpočet těžiště pro daný útvar (namísto délky použít hmotnost lopatky)-
- 3 . Nalézt těžiště nejblíže středu
Tak jsem udělal pokrok. Už si umím spočítat vektory a ukáže mi to
kolik gramů dát na jaký úhel pro ideální vyvážení kola. Teď ještě
najít ideální rozmístění. Potřeboval bych udělat kombinaci všech
hmotností a u každé kombinace spočítat vektory - pak zjistím, která
varianta bude mít nejmenší hmotnost.
Poradil byste mi někdo, jak udělat všechny varianty hmotností lopatek?
Předpokládám permutace bez opakování. Díky moc.
Bugmaster:7.9.2019 0:28
Ahoj mifro,
když to pochopim, tak je určitá šance, že ti s tim pomůžu.
Mám několik dotazů:
- Je to jen nějaký teoretický cvičení, nebo to má i praktický využití? Je to nějaký statický vyvažování něčeho?
- Musí být paprsky rozmístěny rovnoměrně? Myslím, musí být všechny úhly stejný?
- Prošel jsem ve škole nějakou matematikou a myslím si, že chápu, co je to vektor. Jsem si docela jistý, že hmotnost je skalár. Jak to s těma vektorama tedy myslíš? Vektor čeho? Něco společnýho s pozicí těžiště od středu rotace?
- Jak myslíš "která varianta bude mít nejmenší hmotnost"? Když použiješ všechny paprsky, tak hmotnost budeš mít přeci vždycky stejnou.
mifro:9.9.2019 17:25
Ahoj Bugmaster,
- jedná se o vyvážení kola axiálního ventilátoru
- lopatky mají různé hmotnosti a jde o to je rozmístit co nejlépe kvůli zbytkové nevývaze
Jde o to, najít po zadání hmotností lopatek co nejlepší rozmístění - tzn. navařit na náboj minimální možné závaží.
Bugmaster:9.9.2019 21:22
Aha, už mi to začíná dávat smysl. Už chápu, jak jsi myslel tu nejmenší hmotnost.
Takže, oprav mě, pokud se v některém z předpokladů pletu:
- Lopatky musí být rozmístěny rovnoměrně. Poštelovat úhly tak, aby to vycházelo, není možné, protože takové oběžné kolo by vypadalo divně.
- Lopatky mají víceméně stejný tvar a tedy i těžiště ve víceméně stejném místě, resp. na stejném poloměru.
- Když budeš mít různé permutace, podle čeho posoudíš, která je nejlepší? Čím menší vzdálenost těžiště od středu rotace, tím lépe?
Pokud ti jde jen vygenerování všech permutací, tak tam nemusíš nic vymýšlet. Stačí zkopírovat něco, co udělal někdo jiný.
Problém je ale v tom, že počet permutací hodně rychle stoupá s počtem lopatek. Projít je všechny může trvat docela dlouho. Možná to bude chtít něco chytřejšího, než brute force.
Přijde mi to jako úloha na optimalizaci. Teoreticky by k tomu mohl jít přiohnout řešitel v Excelu.
mifro:10.9.2019 11:30
Ahoj,
- V náboji jsou otvory, do kterých se jednotlivé lopatk šroubují - nejde úplně o úhel ale o pořadí.
- Lopatky jsou tvarově stejné, mohou se lišit hmotností - dáno technologií výroby
- Permutace - u každé varianty bych spočítal nevývahu a u které by hmotnost vývažku vyšla nejmenší, ta by byla ideální.
Jak píšeš, problém je s počtem variant - např. pro 21 lopatek je to
hodně velké číslo.
V příloze je zatím to, co jsem udělal a příklad jak vypadá oběžné
kolo. Zadám hmotnosti jednotlivých lopatek, které se mi pak setřídí
(použitý návrh Mousera) a spočítá se na jaký úhel navařit kolik gramů.
Nicméně i toto řazení není optimální - ručně se dokážu dostat na
nižší hmotnost vývažku - viz přiložené screenshoty.
Podle mne to potrebujes seradit podle velikosti.
Pak suda-suda a licha-licha by mely byt pary, ktere hledas.
Nebo to seradit nejak tak, aby rozdil hmotmosti paru by mel byt co
nejmensi.
abs(a-b) + abs(c-d) + ... = minimum
Coz si myslim, ze by melo resit nebo aspon pomoci prave serazeni podle
hmotnosti.
Kde je pak teziste pro dolozeni protizavazi se ale urcuje jinak. To zalezi
pak na delce lopatky a jeji vaze a i tak to nebude moc presne...
A ledaco se zmeni po roztoceni, az se soucastky usadi. resp, muze byt teziste
jinde pri malych otackach a pri vetsich.
A pak je tu tez vliv prachu a necistot.
Nemas to snadne
serazeno; rozdil od min; kazda druha, sude radky k sobe, liche k sobe
9 470 0 0
4 475 5 10
2 480 10 22
3 490 20 35
5 492 22 50
1 500 30 5
7 505 35 20
6 510 40 30
8 520 50 40
min 470
A nebo mozna lepsi, kdyz kazdy druhy par vzajemne vymenis
0 0 470
10 30 500
22 22 492
35 20 490
50 50 520
5 5 475
20 35 505
30 10 480
40 40 510
0-40 zustava
10-30 das opacne jako 30-10
A jeste dalsi tip, to tu bylo zmineno, rozmistovat to do krize a ne
poporade.
Vodorovne, svisle, 45 stupnu, -45 stupnu a opet pary, co jsem 0-40, 30-10,
22-35...
Mimochodem, proc je tech cisel 9 a ne 8? To je jako nejak lepcejsi pro vyvazeni?
No, a takhle to vypada, jak jsem to myslel uz na zacatku. idealni je co nejvetsi uhly, kruhovy graf (obe moznosti, po sobe i na preskacku). To by melo nejvice snizit vibrace, ikdyz bude treba pridat vetsi zavazi.
50 520 40 510
35 505 35 505
22 492 20 490
10 480 10 480
0 470 0 470
5 475 5 475
20 490 22 492
30 500 30 500
40 510 50 520
mifro:10.9.2019 14:31
Díky, ale nějak jsem to teď nepobral... nemohl bys mi to prosím ukázat jednoduše v kódu? Já dělám ve ventilátorech a nejsem programátor - to je spíš koníček - občas se snažím udělat něco pro zjednodušení práce. Počet čísel / lopatek resp. hmotností je vždy různý. Většinou něco mezi 6-30 (sudé i liché počty). Jinak jsem zkoušel zadat do mého programu - tvé seřazení ukázalo dovařit závaží 21 gramů, moje řazení 18 gramů. Mám tady jeden příklad z praxe - excel v příloze. Takto jsou hodnoty seřazeny ideálně - ukazuje to 0 gramů. Ale nevidím v tom použitelnou logiku.
Ano, urcite to jde vynulovat. Ale kdyz o neco zavadi, tak se ti roztrepe,
pokud nevytvoris kruhovy diagram.
Viz tem prvni graf v poslednim obrazku, esicko, tam je v podstate stred na
stredu a vpravo a vlevo je zhruba stejny tvar. Ale, kdyz ta vrtulka o neco
zavadi, tak vpravo, vlevo bude udrzovat odstredivou silu a nahore se bude
kymacet do stran.
A ty tve data jsi dal jako obrazek, to si nemuzu do excelu zkopirovat (musel
bych to cislo po cislu opisovat). Jen to oznac, ctrl+c. Klikni sem, klikni
tlacitko </> (code) a mezi znacky ctrl+v.
To nedelam programem
min-y2
min+x1
min
min-x2
min+y1
je system, ktery pouzivam. 2 je vyssi hodnota z tech 2 serazenych.
1 10300 10020 0 80 360 280 560 10020 280
2 10300 10030 10 100 380 280 560 10300 560
3 10210 10060 40 70 350 110 390 10060 320
4 10160 10060 40 110 390 110 390 10210 470
5 10130 10070 50 60 340 80 360 10090 350
6 10130 10080 60 140 420 80 360 10130 390
7 10120 10090 70 40 320 60 340 10030 290
8 10120 10090 70 280 560 50 330 10100 360
9 10100 10100 80 10 290 10 290 10120 380
10 10100 10100 80 0 280 0 280 10070 330
11 10090 10120 100 280 560 40 320 10300 560
12 10090 10120 100 40 320 40 320 10060 320
13 10080 10130 110 190 470 70 350 10160 420
14 10070 10130 110 50 330 70 350 10090 350
15 10060 10160 140 110 390 100 380 10130 390
16 10060 10210 190 70 350 100 380 10080 340
17 10030 10300 280 100 380 140 420 10100 360
18 10020 10300 280 80 360 190 470 10120 380
Mozna, po chvili premysleni nebo googlovani bych nasel reseni i na kruhove rozmisteni se stredem uprostred. Tento problem je uz urcite davno vyreseny. PS. Pouzil jsem OCR, ale stejne jsem musel nejake cisla opravovat.
Ten oranzovy graf mozna vypada jako zahada, ale postup je podobny jako u predchoziho. Jdu po serazenych cislech, jednou cislo dam nahoru, podruhe dolu. Na prskascku, takto mensi nahoru - vetsi dolu, mensi dolu - vetsi nahoru... Muzu ti to zas barevne oznacit.
Jo, a tohle je podle schematu ze vcera.
Rozdelis to napul a cisla rozdeluje na radek 1, (n/2), 2, (n/2)+1, ...
A druhe je totez, jen beres jedno cislo zhora, druhe ze spode a delas pary
zhora+zespodu, zespodu+zhora. Nechce se mi delat ted screen. V druhem pripade
jsem dostal hodne podobny tvar tve hvezdici.
10 290 280 560
40 320 10 290
60 340 190 470
70 350 40 320
80 360 110 390
100 380 60 340
110 390 100 380
140 420 70 350
280 560 80 360
0 280 0 280
40 320 280 560
50 330 40 320
70 350 140 420
80 360 50 330
100 380 110 390
110 390 70 350
190 470 100 380
280 560 80 360
Bugmaster:11.9.2019 20:12
Vzal jsem hmotnosti z úplně prvního příspěvku a zkusil jsem to prohnat řešitelem v Excelu. Jestli jsem to správně pochopil a realizoval, tak by to mělo být o chloupek lepší, než tebou navržené řešení. Moje reseni je v tom modrym zaramovani.
mifro:12.9.2019 17:53
Díky, ten zelený graf vypadá perfektně - zkusím se v tom zorientovat.
Jinak pro info, lopatka nikde zavadit nemůže - resp. 2-tunové kolo o
průměru 3 metry se 775 otáčkami zavadí jen jednou
mifro:13.9.2019 7:33
Peter Mlich - já se omlouvám, ale koukal jsem na to a úpně tomu nerozumím - jakým systémem seřadím hodnoty, abych dostal zelený graf? Nemohl bys mi prosím dát názorný příklad? Díky moc.
Zeleny graf jsou tve hodnoty. Obrazek jsem tam dal pro srovnani. Je na nem
videt urcita symetrie rozlozeni kolem kruhu uprostred.
Posilam obrazek z hodnot, ktere jsem tam pridal pak.
V te druhe casti jsem zkousel dalsi logickou variantu. Rozdelit kolo na 4
casti a stridat velke-male cislo jako par lopatek proti sobe.
(male 1) 2 3 4 (velke 5) 6 7 89
9 2
\ |
1 ------------ 5
| \
6 4
1 - 5, pak do krize 2 - 6 a pro vyvazeni mezi 1-2 vlozit velke cislo od konce 9 a k nemu par 4 do protivky. Atd.
A samozrejme to ted rikam blbe, bylo by mozna lepsi i tu serazenou radu
rozdelit po ctvrtitach a tak pridelovat cisla. Rozdil cisel v paru by mel byt co
nejmensi.
Ale, pokud nechces neco takoveho jako ten obrazek S nebo zubate kolo, dvojite S
do krize, ale chces hvezdu, tak je lepsi to parovat prave male-velke cislo a
rozdil je 1/4.
Nebo, mozna si to pletu, mozna ses ptal na zeleny graf v prispevku
"A jeste 1 obrazek."
https://www.itnetwork.cz/…0662_image_0
Tam zeleny graf, no, jak to popsat.
Serazena cisla rozdelis na dve pulky.
Pro ukladani cisel rozdelis na 2 pulky (parovani)
0 cislo zhora, 30 cislo zhora pulka2
5 cislo zhora, 35 cislo zhora pulka2, 10 cislo zhora, 40 cislo zhora pulka2
20 cislo zhora, 50 cislo zhora pulka2, ...
Je to zas jeden pokus, jak vyvazit kolo, rozdelit cisla rovnomerne a na
stridacku. Ten obrazec by vypadal lepe, kdybych pouzil system z druheho sesitu
pro ten vetsi pocet hodnot.
Pozn:
- zhora je mysleno jakoze zhora, nepridelene cislo.
- poloha 0, 5 je dana, musi byt doprotivky na kole, proto je 0 na prvnim radku a 5 na radku 4 nebo 5, to je na tobe
- system je voleny tak, aby rozdil protilehlych cisel byl 50%. Proto se bere jedno cislo zhora a druhe az od poloviny serazene rady.
mifro:19.9.2019 14:01
Ten řešitel resp. jeho výpočet jde nějak "převést" do kódu?
Bugmaster:19.9.2019 14:36
Algoritmy, které Excel k tomuhle ve střevech používá, jsou obecně známé. Tak snad se našel někdo, kdo to přepsal do dotnetu (přeci jen je to jedna z nejrozšířenějších platforem).
Zatím jsem se zběžně díval na OR-Tools od Googlu, ale zdá se, že ten k tomu použít nepůjde (patrně se nejedná o lineární optimalizaci). Určitě ale někde někdo napsal něco použitelnýho a chce to "jen" najít. Až budu mít pár hodin v kuse čas, tak se na to podívám. Tohle je docela zajímavý porblém.
Peter Mlich:20.9.2019 10:06
Mimochodem, nemuzes poslat soubor, ten xls? Ja bych tam testnul ty moje varianty, jak to vychazi. Nechce se mi ted vymyslet algoritmus, ktery proveri vsechny moznosti nebo nejakou matematicko-fyzikalni rovnici. Spis tak, proo zajimavost.
Bugmaster:20.9.2019 10:41
Včera při čištění zůbů mě napadl jednoduchý algoritmu, který nazahrnouje žádnou složitou optimlalizace.
V podstatě to funguje takhle:
- Vezme vstupní hodnoty a "vyrobí" z nich oběžné kolo. Následně zkouší prohodit vždycky pár lopatek a zkouší, která verze je nejlepší (= má těžiště nejblíže středu).
- Vezme nejlepší verzi a opakuje od bodu 1 dokud došlo k nějakýmu prohození (v určitým momentu každé prohození vede ke zhoršení).
Výhoda je, že při každé iteraci je třeba projít pouze n*(n-1)/2 variant oběžného kola (n je počet lopatek), což není tak mnoho.
Naimplementoval jsem to ve vb.net, takže by neměl být problém, kdybys to nejdebože chtěl použít.
Vypisuje to tohle. (hehe, mám zdroják s idečkem 1234, heč!)
Bugmaster:21.9.2019 9:04
Teď si nejsem jist, který excel myslíš (reaguješ na mifra). Pokud ten můj výplod s tím řešitelem, tak tady ho máš.
Jenom si nejsem úplně jist, jestli ti to k něčemu bude :/
mifro:21.9.2019 15:17
Bugmaster: Díky a gratulace k idečku Jinak to vypadá perfektně -
budu zkoumat a testovat.
Bugmaster:22.9.2019 20:59
Jeste jsem s tim nebyl spokojenej. Tenhle algoritmus zavisi na vstupnich hodnotach a nezajisti vzdy nejlepsi mozny vysledek. Tak jsem vymyslel, ze lopatky zkusim nekolikrat (deterministicky) promichat a optimalizuju jednotlive verze. Az z tech pak vyberu tu nejlepsi. Funguje to docela dobre.
Uz to ale nebylo rozumny cpat do jednoho souboru, tak jsem zpublikoval repozitar, kde si to muzes stahnout.
Pro vetsi kola to muze trvat docela dlouho. Je tam ale prostor pro zrycheni - tohle by melo jit snadno rozlozit do vice vlaken. A mozna tam man nekde nejakou botu, ktera to brzdi :/ To se obcas taky stava (viz můj nickname).
K promichani se da pouzit serazovaci algoritmus s podminkou, ze 0.66 a vic, aby to co nejvic promichal. Ale nevim, jak se to ve VB pise. V JS by to vypadalo nejak takto
<script>
function sortCmp(a, b) {return 0.66-Math.random();}
arr = [1, 2, 3, 4];
arr.sort(sortCmp);
alert(arr);
</script>
U normalniho sortu porovnava vzdy 2 hodnoty, a, b. Vysledek operace je bud a\<b nebo a\>\=b nebo -1 +0 +1. A podle toho se bud a vymeni za b nebo ne. Cili, kdyz se tam da prvek random a vysledek nastavi cie plusovy, proto 0.66 a ne 0.5, tak bude a,b vic vzajemne vymenovat. Ale nesmis tam dat 0 protoze nic neseradi a nesmis dat 1 protoze budou jen v opacnem poradi.
A nebo zrovna pouzij serazovani jako zpusob prochazeni pole pro hledani vysledku, kde tu funkci prepises na tvoji.
<script>
function sortCmp(a, b) {return jeVicVyvazenejsi(a,b);}
arr = [1, 2, 3, 4];
arr.sort(sortCmp);
alert(arr);
</script>
Proc? Nativni funkce byvaji obvykle optimalizovane, rychlejsi.
Ted porovnavas pary a, b a skocis na dalsi par. Slo by treba v druhe fazi zkusi jako par pouzit a+1, b. Lopatky, ktere nejsou uplne proti sobe je zkusit vymenit.
Bugmaster:23.9.2019 10:37
Mě ale nešlo o to seřadit je náhodně. Já je chtěl seřadit deterministicky - tak, aby byly rozházený, ale požadý rozházený stejně. Když je rozházim náhodně, tak hrozí, že při každym volání funkce dostanu na stejný vstup jiný výstup. To se mi nelíbí, proto jsem si dal tu práci s vymýšlením algoritmu, který to míchá deterministicky.
K tomu jak píšeš:
function sortCmp(a, b) {return 0.66-Math.random();}
Když použiješ komparační funkci timhle způsobem, nebojíš se trochu? Takhle ta funkce není tranzitivní (neplatí: jestliže a < b AND b < c potom a < c). Představ si, že tohle použiješ na rozházení dlouhý posloupnosti třeba nějakým bubble sortem: ukončí se to jen v případě, že ti ve všech porovnáních zrovna padne výsledek "menší než 0", což záleží na náhodě.
Jak píšeš "Nativni funkce byvaji obvykle optimalizovane, rychlejsi.".
Ano, to máš pravdu. Jenže já nepotřebuju seřadit možná řešení od
nejlepších po nejhorší. Já potřebuju najít to jedno řešení, které je
nejlepší. A k tomu stejně musím projít všechny návrhy.
Ted porovnavas pary a, b a skocis na dalsi par. Slo by treba v druhe fazi zkusi jako par pouzit a+1, b. Lopatky, ktere nejsou uplne proti sobe je zkusit vymenit.
V každé iteraci vyzkouším prohodit úplně všechny páry. Jednotlivá prohození si představ jako hranu úplného grafu (alespoň já si to tak v hlvě vizualizuju).
mifro:23.9.2019 12:19
Díky, zkouším to nahodit do mého "výtvoru" a asi už jsem blbej, ale
nemůžu přijít, jak převést hodnoty / hmoptnosti z listboxu do Dim
zadaniList As New List(Of Double()) From {
New Double() {500.0, 480.0, 490.0, 475.0, 492.0, 510.0, 505.0, 520.0,
470.0}}
Tzn. místo ručně zadaných hodnot tam načíst listbox. Zkoušel jsem for
xx=0 to listbox1.items.count do zadanilist(xx)=listbox1.items.item(xx)
next ale bez úspěchu...
Bugmaster:23.9.2019 13:07
Někde si psal, že si použil algoritmus od Mousera, že?
To znamená, že umíš z ListBoxu sestavit pole intů s hodnotama hmotností.
V tom případě by ti pak měla stačit následující funkce, která spapinká stejný vstup a vrátí ti seřazený výstup.
''' <summary>
''' Vrati pole serazenych hodnot.
''' </summary>
''' <param name="hmotnosti">hodnoty k serazeni</param>
Function Seradit(hmotnosti As IEnumerable(Of Integer)) As Integer()
' Inicializovat optimalizer, ktery provadi samotny algoritmus
Dim rozvazny = New RozvaznyOptimalizer("Rozvazny")
' Zabalit ho do wrapperu, ktery bude zkouset ruzne promichany vstupy
Dim kolikratPromichat = 30
Dim rozvaznyScrambled = New ScrambleOptimalizer("Zamichany rozvazny", kolikratPromichat, rozvazny)
' Vytvorit kolo (ve vnitr pracuju s Doublama, vstup jsoi inty takze to potrebuju konvertovat)
Dim pocatecniKolo = New Kolo((From h In hmotnosti Select CDbl(h)).ToArray())
' Optimalizovat
Dim optimalizovaneKolo = rozvaznyScrambled.Optimalizovat(pocatecniKolo)
' Vratit vysledne poradi (tady to zase konvertuju zpet z doublu do intu)
Return (From h In optimalizovaneKolo.SerazeneHmotnosti Select CInt(h)).ToArray()
End Function
Vola se to pak nejak takto:
' Musis nejak sestavit pole nebo list integeru, ktere nejakym zpusobem prectese z ListBoxu
Dim hodnotyZListBoxu = New Integer() {500, 480, 490, 475, 492, 510, 505, 520, 470}
' Zoptimalizovat. Vysledek je zase pole integeru.
Dim zoptimalizovano = Seradit(hodnotyZListBoxu)
' Pak to dale zpracovat. Treba vypsat nebo cokoliv
Console.WriteLine(String.Join(", ", zoptimalizovano))
mifro:23.9.2019 13:52
Díky, zkouším to - ještě jedna věc - jak pak dostanu do druheho
listboxu vysledky? (jedna lopatka/hmotnost = 1 řádek) V msgboxu mi to vyjede,
ale....
MsgBox("finální kolo: " & String.Join("; ", From l In kolo Select
String.Format("{0:N1}", l.Hmotnost)))
Díky a omlouvám se, že prudím s kravinama, ale tohle už je pro mě vyšší
dívčí
Zobrazeno 50 zpráv z 94.