Avaleht
uus teema   vasta Tarkvara »  Programmeerimine »  Seljakoti pakkimine c-s märgi kõik teemad loetuks
märgi mitteloetuks
vaata eelmist teemat :: vaata järgmist teemat
Hinnavaatlus :: Foorum :: Uudised :: Ärifoorumid :: HV F1 ennustusvõistlus :: Pangalink :: Telekavad :: HV toote otsing
autor
sõnum Saada viide sõbrale.  :: Teata moderaatorile teata moderaatorile
otsing:  
raffaello
HV vaatleja

liitunud: 15.10.2008




sõnum 15.10.2008 15:56:35 Seljakoti pakkimine c-s vasta tsitaadiga

Vaja oli leida lahendus täisarvulisele seljakoti pakkimise ülesandele kasutades sügavuti otsivat (tagasivõtmisega - backtracking) algoritmi.
Põhiülesandeks oli realiseerida tagasivõtmisega rekursiivne algoritm koos kärpimisega.

Siin see kood siis on kuid miskipärast ei väljasta ta vastust. Ehk siis väljastab nii kaua kui input.txt ei eksisteeri. Siis ütleb kenasti et "sisendfaili ei leitud". Kui aga input.txt on olemas, väljastab ainult tühja rea, isegi mitte mingeid veateateid. Ma ei suuda leida milles võiks probleem olla. kas keegi oskab aidata?

Kood ise:
#include <stdio.h>
#include <stdlib.h>

int maxprofit=0; //maksimaalne leitud asjade kogukasum
int maxweight=0; //maksimaalne leitud asjade kogukaal
int total_weight; //lubatud maksimaalne kaal


ty****f struct item thing;
struct item{
int price;
int weight;
double relationship;
};
void pack(int i, int profit, int weight);
int promising(int i, int weight, int profit);
int compare(const void * a, const void * b);




thing items[5000];

int include[5000]; // seljakotis olevad asjad
int maxinclude[5000]; // maksimaalsed asjad
int find;
int i_max; //maksimaalse elemendi väärtus

int main(void)
{
int j; // for tsükli jaoks
FILE *pFile;// = stdin;
pFile = fopen("input.txt", "r");
if( !pFile ) {
printf("Sisendfaili ei ole");

return 1;
}

//sisendi lugemine
fscanf(pFile,"%d",&total_weight);//loeb täisarvu failist

for(i_max = 0 ;!feof(pFile);i_max++)
{
fscanf(pFile,"%d %d\n",&items[i_max].price,&items[i_max].weight);
items[i_max].relationship = (double)items[i_max].price/(double)items[i_max].weight;
//kas fail lõppenud
}
qsort(items,i_max+1,sizeof(thing),compare);
for(j=0;j<101;j++){

}
//arvutamine
//include[0]=1;
//pack(0, 0, 0);//esimene element, kaal, väärtus
//include[0]=0;
pack(0,0,0);

//vastuse väljatrükk
printf("Maximaalsed \n%d %d\n\n Kotti vottis\n" , maxprofit, maxweight);

for(j=0; j<=find; j++)
{
if(maxinclude[j])
printf("%d %d\n",items[j].price, items[j].weight);

}
//getchar();
return 0;
}

void pack(int i, int profit, int weight){
int j;

if( weight > total_weight)
return;

if( profit > maxprofit)
{
maxprofit = profit;
maxweight = weight;
find = i;
for( j=0; j<=i; j++ )
{
maxinclude[j]=include[j];
}
}


//kärpimine
if( promising(i, weight, profit))
{
include[i]=1;
pack(i+1, profit + items[i+1].price, weight + items[i+1].weight);
include[i]=0;
pack(i+1, profit, weight);
}
}


int promising(int i, int weight, int profit){
int totalWeight;
float totalProfit;
int j = i+1;

if( weight > total_weight )
return 0;


totalProfit = profit;
totalWeight = weight;

while( j <= i_max && totalWeight + items[j].weight < maxweight )
{
totalWeight=totalWeight+items[j].weight;
totalProfit=totalProfit+items[j].price;
j++;
}


if( totalProfit >= maxprofit )
return 1;

return 0;
}

int compare(const void *a, const void* b)
{
struct item *item1 = (struct item*)a;
struct item *item2 = (struct item*)b;

if( item1->relationship > item2->relationship )
return -1;
else if( item1->relationship < item2->relationship )
return 1;
return 0;
}



Ja sisendfailiks siis oleks lihtne txt laiendiga fail kujul:
105
11 21
17 27
19 29
17 27
12 22
19 29
22 32
16 26
23 33
18 28
15 25
22 32
12 22
16 26
17 27
22 32
14 24
17 27
Kommentaarid: 1 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 1
tagasi üles
vaata kasutaja infot saada privaatsõnum
nene
Kreisi kasutaja
nene

liitunud: 20.03.2004




sõnum 15.10.2008 17:31:17 vasta tsitaadiga

Äkki sa saaksid oma koodi panna [ code ] ja [ / code ] märgendite vahele, et oleks natukegi loetavam.

Või veelgi parem - [ syntax="c" ] ja [ / syntax ] vahele - siis on ka süntaks kenasti esile tõstetud.
Kommentaarid: 24 loe/lisa Kasutajad arvavad:  :: 0 :: 1 :: 23
tagasi üles
vaata kasutaja infot saada privaatsõnum mine selle kasutaja kodulehele
ref
Kreisi kasutaja

liitunud: 10.08.2003




sõnum 15.10.2008 19:50:17 vasta tsitaadiga

kooliülesanne ttüs ? kuidagi tuttav teema icon_wink.gif
Kommentaarid: 17 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 15
tagasi üles
vaata kasutaja infot saada privaatsõnum
andreie
HV vaatleja
andreie

liitunud: 09.09.2006




sõnum 15.10.2008 21:32:00 vasta tsitaadiga

Ma loeksin ka heameelega koodi, aga treppimata kood on hirmus nüri ja pealegi ilmselge kooliülesanne. Senikaua saan aidata ainult silumisega.

Silumine - see on imelihtne!

1. Teed andmefaili "input.txt" lühemaks, näiteks kaherealiseks.
2. Avad programmi IDE-s.
3. Käid samm-sammult programmi läbi (single-stepping, näiteks MSVC menüüs "Debug -> Step over" või "Debug -> Step into"), otsides loogikavigu.
4. Kui leidsid, siis parandada.
5. Vajadusel korrata.

_________________
Unix survives only because everyone else has done so badly.
Kommentaarid: 5 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 5
tagasi üles
vaata kasutaja infot saada privaatsõnum
raffaello
HV vaatleja

liitunud: 15.10.2008




sõnum 15.10.2008 22:55:08 vasta tsitaadiga

c:
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. int maxprofit=0; //maksimaalne leitud asjade kogukasum
  5. int maxweight=0; //maksimaalne leitud asjade kogukaal
  6. int total_weight; //lubatud maksimaalne kaal
  7.  
  8.  
  9. ty****f struct item thing;
  10. struct item{
  11. int price;
  12. int weight;
  13. double relationship;
  14. };
  15. void pack(int i, int profit, int weight);
  16. int promising(int i, int weight, int profit);
  17. int compare(const void * a, const void * b);
  18.  
  19.  
  20.  
  21.  
  22. thing items[5000];
  23.  
  24. int include[5000]; // seljakotis olevad asjad
  25. int maxinclude[5000]; // maksimaalsed asjad
  26. int find;
  27. int i_max; //maksimaalse elemendi väärtus
  28.  
  29. int main(void)
  30. {
  31. int j; // for tsükli jaoks
  32. FILE *pFile;// = stdin;
  33. pFile = fopen("input.txt", "r");
  34. if( !pFile ) {
  35. printf("Sisendfaili ei ole");
  36.  
  37. return 1;
  38. }
  39.  
  40. //sisendi lugemine
  41. fscanf(pFile,"%d",&total_weight);//loeb täisarvu failist
  42.  
  43. for(i_max = 0 ;!feof(pFile);i_max++)
  44. {
  45. fscanf(pFile,"%d %d\n",&items[i_max].price,&items[i_max].weight);
  46. items[i_max].relationship = (double)items[i_max].price/(double)items[i_max].weight;
  47. //kas fail lõppenud
  48. }
  49. qsort(items,i_max+1,sizeof(thing),compare);
  50. for(j=0;j<101;j++){
  51.  
  52. }
  53. //arvutamine
  54. //include[0]=1;
  55. //pack(0, 0, 0);//esimene element, kaal, väärtus
  56. //include[0]=0;
  57. pack(0,0,0);
  58.  
  59. //vastuse väljatrükk
  60. printf("Maximaalsed \n%d %d\n\n Kotti vottis\n" , maxprofit, maxweight);
  61.  
  62. for(j=0; j<=find; j++)
  63. {
  64. if(maxinclude[j])
  65. printf("%d %d\n",items[j].price, items[j].weight);
  66.  
  67. }
  68. //getchar();
  69. return 0;
  70. }
  71.  
  72. void pack(int i, int profit, int weight){
  73. int j;
  74.  
  75. if( weight > total_weight)
  76. return;
  77.  
  78. if( profit > maxprofit)
  79. {
  80. maxprofit = profit;
  81. maxweight = weight;
  82. find = i;
  83. for( j=0; j<=i; j++ )
  84. {
  85. maxinclude[j]=include[j];
  86. }
  87. }
  88.  
  89.  
  90. //kärpimine
  91. if( promising(i, weight, profit))
  92. {
  93. include[i]=1;
  94. pack(i+1, profit + items[i+1].price, weight + items[i+1].weight);
  95. include[i]=0;
  96. pack(i+1, profit, weight);
  97. }
  98. }
  99.  
  100.  
  101. int promising(int i, int weight, int profit){
  102. int totalWeight;
  103. float totalProfit;
  104. int j = i+1;
  105.  
  106. if( weight > total_weight )
  107. return 0;
  108.  
  109.  
  110. totalProfit = profit;
  111. totalWeight = weight;
  112.  
  113. while( j <= i_max && totalWeight + items[j].weight < maxweight )
  114. {
  115. totalWeight=totalWeight+items[j].weight;
  116. totalProfit=totalProfit+items[j].price;
  117. j++;
  118. }
  119.  
  120.  
  121. if( totalProfit >= maxprofit )
  122. return 1;
  123.  
  124. return 0;
  125. }
  126.  
  127. int compare(const void *a, const void* b)
  128. {
  129. struct item *item1 = (struct item*)a;
  130. struct item *item2 = (struct item*)b;
  131.  
  132. if( item1->relationship > item2->relationship )
  133. return -1;
  134. else if( item1->relationship < item2->relationship )
  135. return 1;
  136. return 0;
  137. }



Ja on küll tegemist kooliülesandega. Kahjuks kõik tõesti ei pruugi olla nii targad kui teie ning soovivad vahel ka natuke abi. Ma pole ju palunud tervet ülesannet lahendada vaid palunud juhatada veani mida ma ise ei suuda leida.
Kommentaarid: 1 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 1
tagasi üles
vaata kasutaja infot saada privaatsõnum
nene
Kreisi kasutaja
nene

liitunud: 20.03.2004




sõnum 16.10.2008 01:28:11 vasta tsitaadiga

Õigupoolest mina ei saa küll aru, mida su kood üldse teha üritab... Kui sa ütled et ta tegeleb täisarvulise seljakoti pakkimise ülesandega, siis see ei ütle mulle küll mitte midagi. Võimalik, et tegemist on populaarse kooliülesandega, aga mulle juhtumisi täiesti tundmatu.

Lisaks on su koodis väga müstilisi asju...

Milleks näiteks see:

for(j=0;j<101;j++){

}


See on ju täiesti tühi ja kasutu tsükkel. Enne siia foorumisse postitamist võiks sellise jampsi eemaldada.

Kõige jubedam asi seal koodis on see pack() funktsioon. Ma ei tea, mida see funktsioon teeb. Ühtegi kommentaari pole ja see kood on minu jaoks küllaltki keerukas (olgugi, et mul on üle kümne aasta programmeerimiskogemust). Ma saan aru vaid seda, et see funktsioon muudab mõningate globaalsete muutujate väärtusi (mis tabas mind paraja üllatusena) - ja see on suure tõenäosusega halb enne. Ilmselt paari tunni süvenemise järel saaksin ma aru, mida see funktsioon teeb, aga miks peaksin ma oma aega selle peale raiskama?

Seega, palun seleta lähemalt, milles selle koodi ülesanne täpsemalt seisneb.

Ning palun-palun-palun, ehk saaksid sa oma koodi anda trepitud kujul. Ma vähemasti loodan, et sa siiski trepid oma koodi. Kui ei, siis oleks viimane aeg seda tegema hakata. Ma võin muidugi kopeerida su koodi oma tekstiredaktorisse ja lasta selle automaatselt treppida, aga miks peaksin Mina nägema vaeva sinu küsimuse parema vormistamisega - minu meelest kuulub elementaarse netiketi juurde, et küsija vormistab oma küsimuse nii selgelt ja arusaadavalt kui võimalik.
Kommentaarid: 24 loe/lisa Kasutajad arvavad:  :: 0 :: 1 :: 23
tagasi üles
vaata kasutaja infot saada privaatsõnum mine selle kasutaja kodulehele
pinfo
HV vaatleja

liitunud: 16.10.2008




sõnum 16.10.2008 14:28:34 vasta tsitaadiga

Selle ülesande lahendamise saab jagada etappideks.

1) kirjuta rekurssiivne kõigi seljakottide väljaarvutamine (saad kokku 2 astmes N kaalu-hinna komplekti). Testi see ära.
2) Lisa rekursioonile piirang mis ei lase etteantud maksimumkaalu ületada.
3) Lisa kärpimine.
tagasi üles
vaata kasutaja infot saada privaatsõnum
näita postitusi alates eelmisest:   
uus teema   vasta Tarkvara »  Programmeerimine »  Seljakoti pakkimine c-s
[vaata eelmist teemat] [vaata järgmist teemat]
 lisa lemmikuks
näita foorumit:  
 ignoreeri teemat 
sa ei või postitada uusi teemasid siia foorumisse
sa ei või vastata selle foorumi teemadele
sa ei või muuta oma postitusi selles foorumis
sa ei või kustutada oma postitusi selles foorumis
sa ei või vastata küsitlustele selles foorumis
sa ei saa lisada manuseid selles foorumis
sa võid manuseid alla laadida selles foorumis



Hinnavaatlus ei vastuta foorumis tehtud postituste eest.