function [outmat]=optimizerep(target,reihe,ausschlussmat,anzahlwiederholungen,berichtstatus)

%   optimizerepandausschluss

%   This software is protected by german copyright and international treaties.             
%   Copyright 2004 Markus Junghöfer & Peter Peyk. All Rights Reserved.                     
%                                                                                          
%   THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS MAKE        
%   NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO,    
%   WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE    
%   OF THE SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS,
%   TRADEMARKS OR OTHER RIGHTS. COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT,       
%   INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE      
%   OR DOCUMENTATION.                                                                      
target=2;
reihe=[1 3 4 2 4 3 5 2 2 4 7 2 2 2 3 4 8 9 5 4 7 3 1 7 2 8];
erfolg = 0;
erfolgloszaehler=0;

if anzahlwiederholungen == -1; uiwait(errordlg('Optimierung sinnlos bei unbeschränkter Wiederholung!','Achtung:'));
outmat=[];return;end;neuziehenzaehler=1;sternzaehler=1;
if nargin<4; berichtstatus=0;end
if nargin < 3;ausschlussmat = [];end
outmat=zeros(1,length(reihe));
%indices des targets
%-----------------
inds=find(reihe==target);
indsini=inds;


while erfolg == 0
    
%problempos finden
%---------------------
	problemstellenvec=[];
	problemstellenzaehler=1;
	resourcestellenvec=[];
	resourcestellenzaehler=1;
	check=[];
	diffs = diff(inds);
	
	for i=1:length(inds)
        diffmat=zeros(anzahlwiederholungen+(anzahlwiederholungen-2),1);
        groessediffmat = anzahlwiederholungen+(anzahlwiederholungen-2);
        if anzahlwiederholungen == 1
            if i<=length(diffs)
                diffmat=diffs(i);
            else
                diffmat=0;
            end
        end
        for j=1:anzahlwiederholungen-1
            %upper
            if i+j-1<length(diffs)
                if groessediffmat/2+j<=length(diffmat)
                    diffmat(groessediffmat/2+j)=diffs(i+j-1);
                end
            end
            %lower
            if i-j>0
                if groessediffmat/2+1-j>0
                    diffmat(groessediffmat/2+1-j)=diffs(i-j*1);
                end
            end  
        end
        evalstring='diffmat==1';
        for t=1:anzahlwiederholungen-1
            evalstring=['diff(find(',evalstring,'))==1'];
        end
        evalstring=['if ~isempty(find(',evalstring,'));',...
                'problemstellenvec(problemstellenzaehler)=i;problemstellenzaehler=problemstellenzaehler+1;end'];
        if sum(1==diffmat)>=anzahlwiederholungen-1
             warning off
             eval(evalstring);
             warning on
        end
	end
    
	%resourcenpos finden
	%--------------------
	resourcenstellenvec=[];
	indstmp=inds;
	if inds(1)~=1;indstmp=[1,indstmp];end
	if inds(end)~=length(outmat);indstmp=[indstmp,length(outmat)];end
	diffinds=diff(indstmp);
	resourcenzaehler=1;
	naechsteserie=1;
	resourcenstellen=find(diffinds>3);
	for i=1:length(resourcenstellen)
        naechsteserie = 1;
        serienabschnitte = 0;
        while naechsteserie == 1
            naechsteserie = 0;
            serienzaehler = 1;
            while serienzaehler<=anzahlwiederholungen & serienzaehler<diffinds(resourcenstellen(i))-2
                resourcenstellenvec(resourcenzaehler)=indstmp(resourcenstellen(i))+1+serienzaehler+serienabschnitte;
                resourcenzaehler=resourcenzaehler+1;
                serienzaehler = serienzaehler + 1; 
            end
            if indstmp(resourcenstellen(i))+1+serienabschnitte + serienzaehler + 1 < indstmp(resourcenstellen(i)+1)-1
                naechsteserie = 1;
                serienabschnitte=serienabschnitte + serienzaehler;
            end
        end
	end
    
    %ausschlussmat berücksichtigen
    %---------------------------
    
    if ~isempty(ausschlussmat)
        denyresourcenstellenvec=zeros(1,length(resourcenstellen));
        for y=1:length(ausschlussmat)
            for u=1:length(resourcenstellenvec)
                if reihe(resourcenstellenvec(u)-1)==ausschlussmat(y) | reihe(resourcenstellenvec(u)+1)==ausschlussmat(y) 
                    denyresourcenstellenvec(u)=1;
                end
            end
        end
    end
    resourcenstellenvec(find(denyresourcenstellenvec==1))=[];
    
    
    
    
	%abbruch
	%-------
	if ~isempty(problemstellenvec)
        if isempty(resourcenstellenvec)
            if berichtstatus == 1
                inds
                problemstellenvec
                resourcenstellen
                uiwait(errordlg('Verteilung der <mergemat> unter geforderten Wiederholungsbedingungen schwierig in optimizerep.m!','Achtung:'));
            end
            inds=[];
            return;
        end
	end
	if berichtstatus == 1
		length(problemstellenvec)
		indini=inds
	end       
    
    %resourcenstellenvec mischen
    %------------------
    resourcenstellenvec=shuffle(resourcenstellenvec);
    
    
	%problempos auf resourcenpos verteilen
	%------------------------------------
	anzahloptimierungsdurchgaenge=1;
	if berichtstatus == 1
        disp([num2str(length(problemstellenvec)),' verbleibende Problemstellen...']);
	end
	problemstellenvectmp=problemstellenvec;
	while length(problemstellenvectmp)>0
		%Optimierung
		%-----------------
		inds(problemstellenvec(anzahloptimierungsdurchgaenge))=resourcenstellenvec(anzahloptimierungsdurchgaenge);
        indssort=sort(inds);
        diffs = diff(indssort);
		%problemposveränderung testen
		%----------------------------
		problemstellenvectmp=[];
		problemstellenzaehlertmp=1;
		for i=1:length(inds)
            diffmat=zeros(anzahlwiederholungen+(anzahlwiederholungen-2),1);
            groessediffmat = anzahlwiederholungen+(anzahlwiederholungen-2);
            if anzahlwiederholungen == 1
                if i<=length(diffs)
                    diffmat=diffs(i);
                else
                    diffmat=0;
                end
            end
            for j=1:anzahlwiederholungen-1
                %upper
                if i+j-1<length(diffs)
                    if groessediffmat/2+j<=length(diffmat)
                        diffmat(groessediffmat/2+j)=diffs(i+j-1);
                    end
                end
                %lower
                if i-j>0
                    if groessediffmat/2+1-j>0
                        diffmat(groessediffmat/2+1-j)=diffs(i-j*1);
                    end
                end  
            end
            evalstring='diffmat==1';
            for t=1:anzahlwiederholungen-1
                evalstring=['diff(find(',evalstring,'))==1'];
            end
            evalstring=['if ~isempty(find(',evalstring,'));',...
            'problemstellenvectmp(problemstellenzaehlertmp)=i;problemstellenzaehlertmp=problemstellenzaehlertmp+1;end'];
          if sum(1==diffmat)>=anzahlwiederholungen-1
                 warning off
                 eval(evalstring);
                 warning on
            end
		end
		%Progress
		%-------------------
		if length(problemstellenvectmp)<length(problemstellenvec)+1-anzahloptimierungsdurchgaenge
            anzahloptimierungsdurchgaenge=anzahloptimierungsdurchgaenge+1;
            if berichtstatus == 1
                disp([num2str(length(problemstellenvectmp)),' verbleibende Problemstellen...']);
            end
		else
            if berichtstatus == 1
                uiwait(errordlg('Reduktion der Problemstellen erfolglos!','Achtung:'));
            end
            inds = [];
            return
		end
	end

    if ~isempty(indssort);inds=indssort;end

	% indsini;
	% inds;
	
	%Fehlermeldung
	%-------------
	if length(indsini)~=length(inds)
        if berichtstatus == 1
            uiwait(errordlg('Wiedersprüchliche Längen von initialen und transformierten Indicies in <optimizerep.m>!','Achtung:'));
        end
        outmat = [];
        return
	end
    
	%reihe umschreiben
	%-----------------
    reihetmp=reihe;
	reihetmp(indsini)=[];
    
    for j=1:length(inds)
        reihetmp(end+1)=0;
        reihetmp(inds(j)+1:end)=reihetmp(inds(j):end-1);
        reihetmp(inds(j))=target;
    end
    
	
	%ausschluss überprüfen
	%------------------------
	
	ausschlussindmat=[];
	if ~isempty(ausschlussmat)
        for z=1:length(ausschlussmat)
            ausschlussindmat=[ausschlussindmat,find(reihetmp==ausschlussmat(z))];
        end
        ausschlussindmat=sort(ausschlussindmat);
        if isempty(find(diff(ausschlussindmat)==1))
            erfolg=1;
        end
	end

erfolgloszaehler=erfolgloszaehler+1;
end

outmat = reihetmp;
        



return

