Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

Build a relationship of devices from different lists

by shawshankred (Sexton)
on Dec 07, 2010 at 22:19 UTC ( [id://875901]=perlquestion: print w/replies, xml ) Need Help??

shawshankred has asked for the wisdom of the Perl Monks concerning the following question:

Perl Experts. I have a problem and I need an efficient solution. I have been struggling with it and any help is much appreciated.

I have n number of hierarchical devices and need to create a relationship between them based on some simple rules.

I have an list called TOP with its elements TOP01 TOP02 TOP03

I have another list called MID with its elements MID01 to MID24

I have list called LOW with its elements LOW1 to LOW 27, the elements have associated number of devices.

Based on associated number of devices of LOW list assign LOW elements to MID and MID elements to TOP element following the rules.

The rules are TOP cant exceed 650000 devices

MID cant exceed 35000 devices

Here is my incomplete code.

#! /usr/bin/perl # # my @relation_Arr; my @toplevelArr = qw(TOP01 TOP02 TOP03); my @midlevelArr = qw(MID01 MID02 MID03 MID04 MID05 MID06 MID07 MID08 M +ID09 MID10 MID11 MID12 MID13 MID14 MID15 MID16 MID17 MID18 MID19 MID2 +0 MID21 MID22 MID23 MID24); my %lowlevelH = qw(LOW01 19000 LOW02 19523 LOW03 13456 LOW04 18992 LOW +05 19560 LOW06 18945 LOW07 19855 LOW08 12344 LOW09 17400 LOW10 18990 +LOW11 14566 LOW12 17896 LOW13 19000 LOW14 1 9523 LOW15 13456 LOW16 18992 LOW17 19560 LOW18 18945 LOW19 19855 LOW20 + 12344 LOW21 17400 LOW22 16897 LOW23 19877 LOW24 18676 LOW25 13457 LO +W26 12345 LOW27 18456); my $tottopSum = 0; my $totmidSum = 0; while (1) { foreach my $lowLevel (sort keys %lowlevelH) { if($tottopSum == 0) { $tottopSum = $tottopCount + $lowlevelH{$lowLevel}; $totmidSum = $totmidSum + $lowlevelH{$lowLevel}; push(@relation_Arr, "$toplevelArr[0]:$tottopSum, $midlevelArr[ +0]:$totmidSum, $lowLevel, $lowlevelH{$lowLevel}"); ### REmove the first element from the array toplevelArr and mi +dlevelArr next; } if (($tottopSum + $lowlevelH{$lowLevel}) < 650000) { if (($totmidSum + $lowlevelH{$lowLevel}) < 35000) { $tottopSum = $tottopCount + $lowlevelH{$lowLevel}; $totmidSum = $totmidSum + $lowlevelH{$lowLevel}; push(@relation_Arr, "$toplevelArr[0]:$tottopSum, $midlevel +Arr[0]:$totmidSum, $lowLevel, $lowlevelH{$lowLevel}"); ### Remove the first element from the array midlevelArr } else { #### Go down the list of lowLevel Hash and find a value th +at can #### added to $totmidSum such that it does not cross 35000 #### IF found add it to the result array relation_Arr #### Else assign it to the next mid level Element. } } else { ### Assign next TOP element of the array } } } print "@relation_Arr\n"; Results should be TOP01:19000 MID01:19000 LOW01 19000 TOP01:32456 MID01:32456 LOW03 13456 TOP01:51979 MID02:19523 LOW02 19523 TOP01:64323 MID02:31867 LOW08 12344 ;; ;; ;; and so on.

Replies are listed 'Best First'.
Re: Build a relationship of devices from different lists
by state-o-dis-array (Hermit) on Dec 08, 2010 at 00:11 UTC
    First, I'll suggest adding "use strict;" and "use warnings;" at the top of your script. You use $tottopCount in your calculations, but I don't see it getting set.

    As far as how to handle your problem, just to give you a start, I'd suggest doing one thing at a time, add as many LOWn to as many MIDn as you need. Something like:

    while( keys %addedLow < keys %lowlevelH ){ for my $lowLevel ( keys %lowlevelH ){ if( exists $addedLow{$lowLevel} ){ next; } if( $mid{$midItem}{CNT} + $lowlevelH{$lowLevel} <= 35000 ){ push( @{$mid{$midItem}{LowLevel}}, $lowLevel ); $mid{$midItem}{CNT} += $lowlevelH{$lowLevel}; $addedLow{$lowLevel} = 1; } } $midItem++; }
    Then repeat the process for adding mid to top.

    Note that this is not tested and is incomplete, just intended to provide some thoughts about a possible direction to take.

      Thanks a lot State-o-disarray. That is a good and efficient way.

      I was able to do it this morning by modifying my code posted earlier. Here it is, its ugly but it works.. Thanks again

      my @relation_Arr; my @TOPArr = qw(TOP01 TOP02 TOP03); my @MIDArr = qw(SVM01 SVM02 SVM03 SVM04 SVM05 SVM06 SVM07 SVM08 SVM09 +SVM10 SVM11 SVM12 SVM13 SVM14 SVM15 SVM16 SVM17 SVM18 SVM19 SVM20 SVM +21 SVM22 SVM23 SVM24); my @LOWArr = qw(LOW01:19000 LOW02:19523 LOW03:13456 LOW04:18992 LOW05: +19560 LOW06:18945 LOW07:19855 LOW08:12344 LOW09:17400 LOW10:18990 LOW +11:14566 LOW12:17896 LOW13:19000 LOW14:19523 LOW15:13456 LOW16:18992 +LOW17:19560 LOW18:18945 LOW19:19855 LOW20:12344 LOW21:17400 LOW22:168 +97 LOW23:19877 LOW24:18676 LOW25:13457 LOW26:12345 LOW27:18456); my $tottopsum = 0; my $totmidsum = 0; while($#LOWArr >= 0) { if($tottopsum == 0) { $lowdevName = (split /\:/, $LOWArr[0])[0]; $devCnt = (split /\:/, $LOWArr[0])[1]; $tottopsum = $tottopsum + $devCnt; $totmidsum = $totmidsum + $devCnt; push(@relation_Arr, "$TOPArr[0]:$tottopsum, $MIDArr[0]:$totmid +sum, $LOWArr[0]\n"); splice(@LOWArr, 0, 1); next; } for ($index = 0; $index <= $#LOWArr; $index++) { $lowdevName = (split /\:/, $LOWArr[$index])[0]; $devCnt = (split /\:/, $LOWArr[$index])[1]; if (($tottopsum + $devCnt) < 366667) { if (($totmidsum + $devCnt) < 36667) { $tottopsum = $tottopsum + $devCnt; $totmidsum = $totmidsum + $devCnt; push(@relation_Arr, "$TOPArr[0]:$tottopsum, $MIDArr[0] +:$totmidsum, $LOWArr[$index]\n"); splice(@LOWArr, $index, 1); ### Remove an element of t +he array $index = $index - 1; } else { next; } } else { splice(@TOPArr, 0, 1); ### Remove an element of the array splice(@MIDArr, 0, 1); ### Remove an element of the array $tottopsum = 0; $totmidsum = 0; $tottopsum = $tottopsum + $devCnt; $totmidsum = $totmidsum + $devCnt; push(@relation_Arr, "$TOPArr[0]:$tottopsum, $MIDArr[0]:$to +tmidsum, $LOWArr[$index]\n"); splice(@LOWArr, $index, 1); ### Remove an element of the a +rray $index = $index - 1; last; } } splice(@MIDArr, 0, 1); ### Remove an element of the array $totmidsum = 0; } print "@relation_Arr";

      Here are the results

      TOP01:19000, MID01:19000, LOW01:19000 TOP01:32456, MID01:32456, LOW03:13456 TOP01:51979, MID02:19523, LOW02:19523 TOP01:64323, MID02:31867, LOW08:12344 TOP01:83315, MID03:18992, LOW04:18992 TOP01:100715, MID03:36392, LOW09:17400 TOP01:120275, MID04:19560, LOW05:19560 TOP01:134841, MID04:34126, LOW11:14566 TOP01:153786, MID05:18945, LOW06:18945 TOP01:167242, MID05:32401, LOW15:13456 TOP01:187097, MID06:19855, LOW07:19855 TOP01:199441, MID06:32199, LOW20:12344 TOP01:218431, MID07:18990, LOW10:18990 TOP01:235831, MID07:36390, LOW21:17400 TOP01:253727, MID08:17896, LOW12:17896 TOP01:270624, MID08:34793, LOW22:16897 TOP01:289624, MID09:19000, LOW13:19000 TOP01:303081, MID09:32457, LOW25:13457 TOP01:322604, MID10:19523, LOW14:19523 TOP01:334949, MID10:31868, LOW26:12345 TOP01:353941, MID11:18992, LOW16:18992 TOP02:19560, MID12:19560, LOW17:19560 TOP02:38505, MID13:18945, LOW18:18945 TOP02:58360, MID14:19855, LOW19:19855 TOP02:78237, MID15:19877, LOW23:19877 TOP02:96913, MID16:18676, LOW24:18676 TOP02:115369, MID17:18456, LOW27:18456

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://875901]
Approved by sweetblood
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others about the Monastery: (4)
As of 2024-04-24 22:29 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found