Hackerboard Wiki HaboBlog
Hackerboard bei Facebook Hackerboard bei Google+ Hackerboard bei Twitter

[HaBo]

 
Programmieraufgaben Hier wird regelmäßig eine neue Programmieraufgabe gestellt, die dann gelöst werden soll und in Zusammenarbeit mit den Moderatoren auch besprochen werden kann.

Optimale Platzausnutzung

Diskussion: Optimale Platzausnutzung im Forum Programmieraufgaben, in der Kategorie Code Kitchen; Anzeige Mal wieder eine Aufgabe die auf indi zurückgeht (sry, dass ich etwas lange zum posten gebraucht hab ) Also ...

Antwort
Alt 14.09.03, 16:57   #1 (permalink)
 
Registriert seit: 02.10.01
Nornagest Leistung: Facit NTK
Likes: 0
Standard Optimale Platzausnutzung

Anzeige

Mal wieder eine Aufgabe die auf indi zurückgeht (sry, dass ich etwas lange zum posten gebraucht hab )

Also es geht darum ein Programm zu schreiben, dass mehrere Verzeichnisse so auswählt, dass eine vorher festgelegte Speicherplatzmenge optimal ausgenutzt wird, um z.B. bei einem Backup nicht 1/4 einer CD leer zu lassen.
Es soll folgendermaßen funktionieren:
Angenommen man möchte ein Backup eines bestimmten Laufwerkes oder Verzeichnisses machen, dass natürlich mehrere Unterverzeichisse hat, gibt man den Pfad und den verfügbaren Speicherplatz ein und das Programm wählt dann die Unterverzeichnisse so aus, dass der Speicherplatz optimal genutzt wird.

Ich hoffe jemand findet eine Lösung dafür
mfg
Nornagest

Nornagest ist offline   Mit Zitat antworten
Alt 14.09.03, 21:07   #2 (permalink)
Member of Honour
 
Registriert seit: 02.10.01
Indi Leistung: Z3
Likes: 0
Standard

Wär schön, wenn jemand eine PHP-Lösung schreiben könnte.
Indi ist offline   Mit Zitat antworten
   
HaBOT
 
- Anzeige -

Werbung ist gerade online    
Alt 14.09.03, 22:16   #3 (permalink)
 
Registriert seit: 20.04.03
as3jg Leistung: Facit NTK
Likes: 0
Standard

Hmm, wenn du wirklich ein Backup ziehen willst und den Platz auf den Datenträgern optimal ausnutzen willst, würde ich es anders machen, nämlich eine Kombination von tar und split:

Man erzeuge ein virtuelles File, in dem alle zu archivierenden Files mit Verzeichnisinformationen drinne sind, wie tar halt, und teile dieses dann portionsweise auf die Datenträger auf, wie split halt. Auf den Datenträgern vermerkt man noch die laufende Nummer, um die Reihenfolge nachher sicherstellen zu können, und fertig ist die Laube. Platzausnutzung 100%.

In Pseudocode:
Code:
Sub SchreibeByte(byte)
  if anzbytes > datenträgergröße
      if anzdatenträger > 0
         CloseAltenDatenträger()
      endif
      neuenDatenträgerAnfordern()
      anzdatenträger++
      schreibe_byte(anzdatenträger)    // für die Reihenfolge !!!
      anzbytes=1
   endif
  anzbytes++
  schreibe_byte(byte)
EndSub

Sub leseByteAusFiles
   if anzreadbytes > dateilänge
      if ÖffneNächstesFileAusListe() = FALSE
         noch_bytes_einzulesen=FALSE
         return -1
      endif
      anzreadbytes=0
      SchreibeKennsatzMitDateiinformationen()
   endif
   return lese_ein_byte()
EndSub

Main()
   anzdatenträger=0
   anzreadbytes=0
   dateilänge=-1
   anzbytes=datenträgergröße+1
   noch_bytes_einzulesen=TRUE

   while noch_bytes_einzulesen
      byte=leseByteAusFiles()
      if byte > -1
         SchreibeByte(byte)
      endif
   wend
   CloseAltenDatenträger()
END
Oder schwebte dir als Aufgabe vor, eine gegebene Menge von Zahlen (Dateigrößen) so aufzuteilen, daß man sie in möglichst wenigen Einheiten bestimmter Größe (Datenträgern) unterbringen kann?
as3jg ist offline   Mit Zitat antworten
Alt 15.09.03, 04:45   #4 (permalink)
Member of Honour
 
Registriert seit: 02.10.01
Indi Leistung: Z3
Likes: 0
Standard

Zitat:
Hmm, wenn du wirklich ein Backup ziehen willst und den Platz auf den Datenträgern optimal ausnutzen willst, würde ich es anders machen, nämlich eine Kombination von tar und split:
Keine Gute Idee. Es war genauso gedacht, wie es Nornagest in der Aufgabenstellung schrieb. )
Indi ist offline   Mit Zitat antworten
Alt 18.09.03, 21:38   #5 (permalink)
 
Registriert seit: 20.04.03
as3jg Leistung: Facit NTK
Likes: 0
Standard

Na gut,

hier ein Proggi, welches verschiedene Größen auf Datenträgern verteilt. Das Auslesen der Directories, schreiben des Backups, Lizenzzahlungen an Microsoft wegen Verwendung von Leerzeichen und Kommentaren im Quellcode schenke ich mir, da es ja um den reinen Verteilalgorithmus geht. Dieser hier verteilt stur, was noch drauf paßt

Code:
# include <stdio.h>
# include <stdlib.h>

int main(int argc, char **argv)
{
   /* Die Groessen der betroffenen Dateien */
	int daten[32]={47,112,18,3,4,1,933,144,332,223,47,2,2,11,15,64,57,58,
	               432,32,543,47,98,85,7,765,344,500,117,235,711,23};
   /* Das Fassungsvermoegen eines Datentraegers */
	int fassungsvermoegen=1000;

	int t;
	int anz, anzdat=0;

                 /* Passen alle Files ueberhaupt auf einen Datentrageger? */
	for(anz=0, t=0; t<32; t++){
		if(daten[t]>fassungsvermoegen) anz++;
	}
	if(anz>0){                     /* Nein? Dann raus                      */
		printf("%d Daten passen nicht auf einen Datentraeger!!!\n", anz);
		return(1);
	}
	for(;;){                       /* Bis alle wech sind                   */
		for(anz=0, t=0; t<32; t++){ /* Noch Daten zu verteilen da?          */
			if(daten[t]>0) anz++;
		}
		if(anz==0) break;           /* Nein, Fertig.                        */
		for(anz=0, t=0; t<32; t++){
			if(daten[t]>0){
				if(daten[t]<=(fassungsvermoegen-anz)){ /* Passt noch rauf?    */
					printf("%d\n", daten[t]);           /* Nehmen,...          */
					anz+=daten[t];   
					daten[t]=0;                         /* und markieren.      */
				}
			}
		}
		printf("%d ==========( voll )===========\n", anz); /* Einer voll    */
		anzdat++;
	}
	printf("Fertig, %d Datentraeger belegt.\n", anzdat);
	return(0);
}
as3jg ist offline   Mit Zitat antworten
Alt 25.05.04, 00:20   #6 (permalink)
Member of Honour
 
Benutzerbild von ivegotmail
 
Registriert seit: 28.05.03
ivegotmail Leistung: Z3
Likes: 1
Standard

hier ist so ein programm falls noch jemand danach sucht
http://bttb.sourceforge.net/
__________________
http://livehabo.hackerboard.de | http://livebb.sourceforge.net
ivegotmail ist offline   Mit Zitat antworten
Alt 31.05.04, 00:12   #7 (permalink)
 
Registriert seit: 12.04.04
zovax Leistung: Facit NTK
Likes: 0
Standard

Ich weiss nicht, ob ich die Aufgabe richtig verstanden habe, aber hier meine Lösung in C#.NET :

Class1.cs
Code:
using System;
using System.IO;
using System.Collections;
using System.Windows.Forms;	//NUR für den FolderBrowserDialog


namespace Platzausnutzung
{
	class Class1
	{
		internal static DirectoryInfo dir;	//Um Ordnerinformationen auszulesen
		internal static ArrayList Dirs= new ArrayList(0);	//ArrayList für Ordnernamen
		private static ArrayList DirSizes = new ArrayList(0);	//ArrayList für Ordnergröße
		private static long temp;	
		private static long temp2;
		private static FolderBrowserDialog OrdnerWahl = new FolderBrowserDialog();	//zum komfortablen Ordner auswählen
		

		
		static void Main()
		{
			long maximal;	//lokale Variable für den Maximalwert des Speichers
			
			OrdnerWahl.Description = "Bitte einen Ordner auswählen, von dem ein Backup gemacht werden soll";
			OrdnerWahl.ShowNewFolderButton = false;
			if(OrdnerWahl.ShowDialog() == DialogResult.OK)	//Ordnerauswahl
				dir = new DirectoryInfo(OrdnerWahl.SelectedPath);

			Console.Write("Bitte den Maximalspeicherplatz des Backups eingeben (in KB): ");
			maximal = Convert.ToInt64(Console.ReadLine());	//Maximalgröße eingeben
			
				FileSystemInfo[] ordner = dir.GetFileSystemInfos();
		
			foreach (System.IO.FileSystemInfo obj in ordner)
			{
				
				if (obj.GetType().ToString() == "System.IO.DirectoryInfo")	//Auf weitere Unterordner prüfen
				{
					temp2 = FileMethoden.hatUnterverzeichnis((DirectoryInfo) obj);
					Dirs.Add("(directory) " +obj.Name + " -> "+ temp2 +"KB ");
					DirSizes.Add(temp2);
					
					FileMethoden.i = 0;
				}
				else	//Wenn keine weiten Unterordner vorhanden, die Größe der Dateien zusammenrechnen
				{
					FileInfo Datei = new FileInfo(obj.FullName);
					temp += Datei.Length;
				}
			}

			Dirs.Add("(files) Dateien -> " + temp/1024 + "KB");	//Dateigröße im Root Ordner in die ArrayList einfügen

			Console.WriteLine("\n\n Die folgenden Verzeichnisse wurden ausgewählt: \n");
			FileMethoden.DatenVerteilen(DirSizes, maximal);	//Methode um die "richtigen" Verzeichnisse auszuwählen
			
			Console.ReadLine();
			
		}
	}
}
FileMethoden.cs
Code:
using System;
using System.IO;
using System.Collections;

namespace Platzausnutzung
{
	internal class FileMethoden
	{
		internal static long i = 0;	// temp Variable
		private static long temp = 1;	//temp Variable
		
		
		internal static long hatUnterverzeichnis(DirectoryInfo dir) //Die Größe des übergebenen Verzeichnisses prüfen
		{
			
			FileSystemInfo[] ordner = dir.GetFileSystemInfos();
			foreach (System.IO.FileSystemInfo obj in ordner)
			{
				if (obj.GetType().ToString() == "System.IO.DirectoryInfo")
				{
					FileMethoden.hatUnterverzeichnis((DirectoryInfo) obj);	//Rekursiver Methodenaufruf
				}
				else
				{
					FileInfo datei = new FileInfo(obj.FullName);
					i += (datei.Length / 1024);	//Byte in KB
				}

			}
			return (i);

		}

		internal static void DatenVerteilen(ArrayList daten, long maxi) //Dateien verteilen
		{
			for (int i = 0; i != daten.Count; i++)	//Schauen ob es Ordner gibt, die absolut nicht passen
			{
				if((long)daten[i] > maxi)
				{
					daten.RemoveAt(i);
					Class1.Dirs.RemoveAt(i);
					i--;
				}
			}
			for (int i = 0; i != daten.Count; i++)	//Nacheinandern die ArrayList auslesen und wenn
			{										//noch Platz vorhanden ist Ordner hinzufügen
				if(temp > maxi)
				{
					temp -= (long)daten[i-1];
					break;
				}
				else
				{
					temp += (long)daten[i];
					if(temp < maxi)
						Console.WriteLine(Class1.Dirs[i].ToString());
				}

			}
			Console.WriteLine("\n Gesamtspeicherplatz: "+temp.ToString() + "KB");

												  
		} 
	}

}
Habe System.Windows.Forms nur wegen dem BrowserDialog eingebunden, da es mir doch bei öfterem Benutzen auf die Nerven geht immer den kompletten Pfad in die Eingabeaufforderung einzugeben.

Das Programm unterstützt nur die 1. Ebene von Unterordnern des ausgewählten Verzeichnisses, da ich mir nicht die Mühe machen wollte weitere Ebenen einzeln zu unterstützen, da es meiner Meinung auch Unsinn ist, denn diese Ordner sind dann meistens für die darüberliegenden Ebenen unerlässlich und ein alleiniges Backup bringt nicht viel.

Ich habe natürlich nicht die 'optimale' Platzausnutzung implementiert, da dieser Algorithmus doch sehr viel Arbeit wäre (Rucksack-Prinzip), ich habe es ähnlich wie as3jg implementiert.
zovax ist offline   Mit Zitat antworten
Antwort
   
- Anzeige -

Werbung ist gerade online    

[HaBo] » Software Home » Code Kitchen » Programmieraufgaben » Optimale Platzausnutzung
Themen-Optionen
Ansicht

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks sind aus
Pingbacks sind aus
Refbacks sind aus


Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
Problem Online-Banking: Live-CD die optimale Lösung? zero-9 (In)security allgemein 5 01.06.07 13:38
Bild drehen => optimale größe Berechnen Gottzilla Code Kitchen 4 28.10.05 22:30
Optimale Router Konfiguration Orniflyer Network · LAN, WAN, Firewalls 1 22.04.05 23:27


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61