NOVINKA: Získej 40 hodin praktických dovedností s AI – ZDARMA ke každému akreditovanému kurzu!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

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.

Jak se ti líbí článek?
Před uložením hodnocení, popiš prosím autorovi, co je špatněZnaků 0 z 50-500
Jak se ti kurz líbí?
Tvé hodnocení kurzuZnaků 0 z 50-500
Aktivity
Avatar
mifro
Člen
Avatar
mifro:19.8.2019 13:56

Ahoj, prosím o radu. Nevím, jak seřadit hodnoty, abych dosáhl co nejvíce symetrického paprskového grafu. Mám např. hmotnosti lopatek. 1=500g, 2=480g, 3=490g, 4=475g, 5=492g, 6=510g, 7=505g, 8=520g, 9=470g. Hmotnosti nyní potřebuji setřídit tak, abych po vložení paprskového grafu dostal co nejlepší tvar. Viz. příloha - příklad z excelu. Jedná se o co nejlepší vyvážení kola podle hmotnosti lopatek. Ručně to seřadím během chvilky, ale programově se nedokážu pohnout. Díky za každou radu.

 
Odpovědět
19.8.2019 13:56
Avatar
Tomáš Valenta:19.8.2019 15:41

Jsou ty hodnoty seřazené nějak speciálně nebo jde jen o to, aby se střídaly velké a malé hodnoty?

Nahoru Odpovědět
19.8.2019 15:41
C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off.
Avatar
mifro
Člen
Avatar
Odpovídá na Tomáš Valenta
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ě.

 
Nahoru Odpovědět
19.8.2019 15:49
Avatar
STP
Člen
Avatar
Odpovídá na mifro
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();
 }
Nahoru Odpovědět
19.8.2019 22:31
Když umřít, tak online!!!
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:20.8.2019 10:10

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.

 
Nahoru Odpovědět
20.8.2019 10:10
Avatar
Peter Mlich
Člen
Avatar
Odpovídá na mifro
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

 
Nahoru Odpovědět
20.8.2019 10:14
Avatar
mifro
Člen
Avatar
Odpovídá na Peter Mlich
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á.

 
Nahoru Odpovědět
20.8.2019 11:25
Avatar
Odpovídá na STP
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?

Nahoru Odpovědět
20.8.2019 11:53
Neaktivní uživatelský účet
Avatar
simon.steiner:20.8.2019 12:42

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.

 
Nahoru Odpovědět
+2
20.8.2019 12:42
Avatar
mifro
Člen
Avatar
Odpovídá na STP
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...

 
Nahoru Odpovědět
20.8.2019 15:55
Avatar
Tomáš Valenta:21.8.2019 14:59

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.

Nahoru Odpovědět
21.8.2019 14:59
C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off.
Avatar
Jakub Švasta
Lektor
Avatar
Odpovídá na mifro
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; }
}
 
Nahoru Odpovědět
21.8.2019 17:50
Avatar
mifro
Člen
Avatar
Odpovídá na Jakub Švasta
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!

 
Nahoru Odpovědět
22.8.2019 7:13
Avatar
Ghst
Člen
Avatar
Ghst:22.8.2019 14:44

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
Editováno 22.8.2019 14:45
 
Nahoru Odpovědět
22.8.2019 14:44
Avatar
mifro
Člen
Avatar
Odpovídá na Ghst
mifro:28.8.2019 11:14

Ahoj Ghst, vůbec netuším, jak toto provést v kódu...

 
Nahoru Odpovědět
28.8.2019 11:14
Avatar
mifro
Člen
Avatar
mifro:1.9.2019 18:49

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.

 
Nahoru Odpovědět
1.9.2019 18:49
Avatar
Bugmaster
Člen
Avatar
Odpovídá na mifro
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.
 
Nahoru Odpovědět
7.9.2019 0:28
Avatar
mifro
Člen
Avatar
Odpovídá na Bugmaster
mifro:9.9.2019 17:25

Ahoj Bugmaster,

  1. jedná se o vyvážení kola axiálního ventilátoru
  2. 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ží.

 
Nahoru Odpovědět
9.9.2019 17:25
Avatar
Bugmaster
Člen
Avatar
Odpovídá na mifro
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.

 
Nahoru Odpovědět
9.9.2019 21:22
Avatar
mifro
Člen
Avatar
Odpovídá na Bugmaster
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.

 
Nahoru Odpovědět
10.9.2019 11:30
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:10.9.2019 12:50

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

 
Nahoru Odpovědět
10.9.2019 12:50
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:10.9.2019 13:05
        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
 
Nahoru Odpovědět
10.9.2019 13:05
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:10.9.2019 13:11

Vychazi mi to takhle, co se rozdeleni hmotnosti tyce, modry graf.

 
Nahoru Odpovědět
10.9.2019 13:11
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:10.9.2019 13:33

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?

 
Nahoru Odpovědět
10.9.2019 13:33
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:10.9.2019 14:10

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
 
Nahoru Odpovědět
10.9.2019 14:10
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:10.9.2019 14:20

A jeste 1 obrazek.

 
Nahoru Odpovědět
10.9.2019 14:20
Avatar
mifro
Člen
Avatar
Odpovídá na Peter Mlich
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.

 
Nahoru Odpovědět
10.9.2019 14:31
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:11.9.2019 7:58

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.

Editováno 11.9.2019 8:00
 
Nahoru Odpovědět
11.9.2019 7:58
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:11.9.2019 8:39
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.

 
Nahoru Odpovědět
11.9.2019 8:39
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:11.9.2019 8:43

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.

 
Nahoru Odpovědět
11.9.2019 8:43
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:11.9.2019 9:35

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
Editováno 11.9.2019 9:36
 
Nahoru Odpovědět
11.9.2019 9:35
Avatar
Bugmaster
Člen
Avatar
Odpovídá na mifro
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.

 
Nahoru Odpovědět
11.9.2019 20:12
Avatar
mifro
Člen
Avatar
Odpovídá na Peter Mlich
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 ;-)

 
Nahoru Odpovědět
12.9.2019 17:53
Avatar
mifro
Člen
Avatar
Odpovídá na Peter Mlich
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.

 
Nahoru Odpovědět
13.9.2019 7:33
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:13.9.2019 7:50

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.

 
Nahoru Odpovědět
13.9.2019 7:50
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:13.9.2019 8:02

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.

 
Nahoru Odpovědět
13.9.2019 8:02
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:13.9.2019 8:29

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.
 
Nahoru Odpovědět
13.9.2019 8:29
Avatar
mifro
Člen
Avatar
Odpovídá na Bugmaster
mifro:19.9.2019 14:01

Ten řešitel resp. jeho výpočet jde nějak "převést" do kódu?

 
Nahoru Odpovědět
19.9.2019 14:01
Avatar
Bugmaster
Člen
Avatar
Odpovídá na mifro
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.

 
Nahoru Odpovědět
19.9.2019 14:36
Avatar
Peter Mlich
Člen
Avatar
Odpovídá na mifro
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.

 
Nahoru Odpovědět
20.9.2019 10:06
Avatar
Bugmaster
Člen
Avatar
Odpovídá na mifro
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:

  1. 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).
  2. 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č!)

 
Nahoru Odpovědět
20.9.2019 10:41
Avatar
Bugmaster
Člen
Avatar
Odpovídá na Peter Mlich
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 :/

 
Nahoru Odpovědět
21.9.2019 9:04
Avatar
mifro
Člen
Avatar
Odpovídá na Bugmaster
mifro:21.9.2019 15:17

Bugmaster: Díky a gratulace k idečku :-D Jinak to vypadá perfektně - budu zkoumat a testovat.

 
Nahoru Odpovědět
21.9.2019 15:17
Avatar
Bugmaster
Člen
Avatar
Odpovídá na mifro
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).

 
Nahoru Odpovědět
22.9.2019 20:59
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:23.9.2019 8:14

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.

Editováno 23.9.2019 8:15
 
Nahoru Odpovědět
23.9.2019 8:14
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:23.9.2019 8:18

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.

 
Nahoru Odpovědět
23.9.2019 8:18
Avatar
Bugmaster
Člen
Avatar
Odpovídá na Peter Mlich
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).

 
Nahoru Odpovědět
23.9.2019 10:37
Avatar
mifro
Člen
Avatar
Odpovídá na Bugmaster
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.item­s.count do zadanilist(xx)=lis­tbox1.items.i­tem(xx) next ale bez úspěchu...

 
Nahoru Odpovědět
23.9.2019 12:19
Avatar
Bugmaster
Člen
Avatar
Odpovídá na mifro
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))
 
Nahoru Odpovědět
23.9.2019 13:07
Avatar
mifro
Člen
Avatar
Odpovídá na Bugmaster
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čí :-D

 
Nahoru Odpovědět
23.9.2019 13:52
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 50 zpráv z 94.